From c13c9806f957ebc675462737f4b328d3ab89e028 Mon Sep 17 00:00:00 2001 From: guowenxue <guowenxue@gmail.com> Date: Mon, 10 Jul 2023 17:29:22 +0800 Subject: [PATCH] update gpsd.c --- gpsd/booster/logger.c | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 276 insertions(+), 0 deletions(-) diff --git a/gpsd/booster/logger.c b/gpsd/booster/logger.c new file mode 100644 index 0000000..116a529 --- /dev/null +++ b/gpsd/booster/logger.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2022 Guo Wenxue + * Author: Guo Wenxue <guowenxue@gmail.com> + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GPL license. + */ + +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/time.h> +#include <pthread.h> + +#include "logger.h" + +typedef void (*log_LockFn)(void *udata, int lock); + +static struct { + char file[32]; /* logger file name */ + FILE *fp; /* logger file pointer */ + long size; /* logger file max size */ + int level; /* logger level */ + log_LockFn lockfn; /* lock function */ + void *udata; /* lock data */ +} L; + +static const char *level_names[] = { + "FATAL", + "ERROR", + "WARN", + "INFO", + "DEBUG", + "TRACE" +}; + +static const char *level_colors[] = { + "\x1b[35m", + "\x1b[31m", + "\x1b[33m", + "\x1b[32m", + "\x1b[36m", + "\x1b[94m" +}; + +static inline void time_to_str(char *buf) +{ + struct timeval tv; + struct tm *tm; + int len; + + gettimeofday(&tv, NULL); + tm = localtime(&tv.tv_sec); + + len = sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d.%06d ", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, (int)tv.tv_usec); + + buf[len] = '\0'; +} + +static void mutex_lock(void *udata, int lock) +{ + int err; + pthread_mutex_t *l = (pthread_mutex_t *) udata; + + if (lock) + { + if ( (err = pthread_mutex_lock(l)) != 0 ) + log_error("Unable to lock log lock: %s", strerror(err)); + } + else + { + if ( (err = pthread_mutex_unlock(l) != 0) ) + log_error("Unable to unlock log lock: %s", strerror(err)); + } +} + +int log_open(char *fname, int level, int size, int lock) +{ + FILE *fp; + + L.level = level; + L.size = size*1024; + + if( !fname || !strcmp(fname, "console") || !strcmp(fname, "stderr") ) + { + strcpy(L.file, "console"); + L.fp = stderr; + L.size = 0; /* console don't need rollback */ + } + else + { + if ( !(fp = fopen(fname, "a+")) ) + { + fprintf(stderr, "%s() failed: %s\n", __func__, strerror(errno)); + return -2; + } + L.fp = fp; + strncpy(L.file, fname, sizeof(L.file)); + } + + + if( lock ) + { + static pthread_mutex_t log_lock; + + pthread_mutex_init(&log_lock, NULL); + L.udata = (void *)&log_lock; + L.lockfn = mutex_lock; + } + + fprintf(L.fp, "\n"); + log_info("logger system(%s) start: file:\"%s\", level:%s, maxsize:%luKiB\n\n", + LOG_VERSION, L.file, level_names[level], size); + + return 0; +} + +void log_close(void) +{ + if( L.fp && L.fp!=stderr ) + fclose(L.fp); + + if (L.udata ) + pthread_mutex_destroy( L.udata); +} + +static void log_rollback(void) +{ + char cmd[128]={0}; + long fsize; + + /* don't need rollback */ + if(L.size <= 0 ) + return ; + + fsize = ftell(L.fp); + if( fsize < L.size ) + return ; + + /* backup current log file */ + snprintf(cmd, sizeof(cmd), "cp %s %s.bak", L.file, L.file); + system(cmd); + + /* rollback file */ + fseek(L.fp, 0, SEEK_SET); + truncate(L.file, 0); + + fprintf(L.fp, "\n"); + log_info("logger system(%s) rollback: file:\"%s\", level:%s, maxsize:%luKiB\n\n", + LOG_VERSION, L.file, level_names[L.level], L.size/1024); + + return ; +} + +void _log_write(int level, const char *file, int line, const char *fmt, ...) +{ + va_list args; + char time_string[100]; + + if ( !L.fp || level>L.level ) + return; + + /* Acquire lock */ + if ( L.lockfn ) + L.lockfn(L.udata, 1); + + log_rollback(); + + /* check and rollback file */ + time_to_str(time_string); + + /* Log to stderr */ + if ( L.fp == stderr ) + { + fprintf(L.fp, "%s %s %-5s\x1b[0m \x1b[90m%s:%03d:\x1b[0m ", + time_string, level_colors[level], level_names[level], file, line); + } + else /* Log to file */ + { + fprintf(L.fp, "%s %-5s %s:%03d: ", time_string, level_names[level], file, line); + } + + va_start(args, fmt); + vfprintf(L.fp, fmt, args); + va_end(args); + + fflush(L.fp); + + /* Release lock */ + if ( L.lockfn ) + L.lockfn(L.udata, 0); +} + +#define LINELEN 81 +#define CHARS_PER_LINE 16 +static char *print_char = +" " +" " +" !\"#$%&'()*+,-./" +"0123456789:;<=>?" +"@ABCDEFGHIJKLMNO" +"PQRSTUVWXYZ[\\]^_" +"`abcdefghijklmno" +"pqrstuvwxyz{|}~ " +" " +" " +" ???????????????" +"????????????????" +"????????????????" +"????????????????" +"????????????????" +"????????????????"; + +void log_dump(int level, const char *prompt, char *buf, size_t len) +{ + int rc; + int idx; + char prn[LINELEN]; + char lit[CHARS_PER_LINE + 2]; + char hc[4]; + short line_done = 1; + + if (!L.fp || level>L.level) + return; + + if( prompt ) + _log_write(level, __FILE__, __LINE__, "%s", prompt); + + rc = len; + idx = 0; + lit[CHARS_PER_LINE] = '\0'; + + while (rc > 0) + { + if (line_done) + snprintf(prn, LINELEN, "%08X: ", idx); + + do + { + unsigned char c = buf[idx]; + snprintf(hc, 4, "%02X ", c); + strncat(prn, hc, LINELEN); + + lit[idx % CHARS_PER_LINE] = print_char[c]; + } + while (--rc > 0 && (++idx % CHARS_PER_LINE != 0)); + + line_done = (idx % CHARS_PER_LINE) == 0; + if (line_done) + { + if (L.fp) + fprintf(L.fp, "%s %s\n", prn, lit); + } + } + + if (!line_done) + { + int ldx = idx % CHARS_PER_LINE; + lit[ldx++] = print_char[(int)buf[idx]]; + lit[ldx] = '\0'; + + while ((++idx % CHARS_PER_LINE) != 0) + strncat(prn, " ", sizeof(prn)-strlen(prn)); + + if (L.fp) + fprintf(L.fp, "%s %s\n", prn, lit); + + } +} -- Gitblit v1.9.1