From a4216e907b3e139589b5fcee35874b670f985b89 Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Wed, 21 Aug 2024 10:57:47 +0800
Subject: [PATCH] Add .ini parser example code
---
booster/logger.c | 544 ++++++++++++++++++-----------------------------------
1 files changed, 189 insertions(+), 355 deletions(-)
diff --git a/booster/logger.c b/booster/logger.c
index d8f0e92..364fa72 100644
--- a/booster/logger.c
+++ b/booster/logger.c
@@ -1,416 +1,250 @@
/*********************************************************************************
- * Copyright: (C) 2020 LingYun IoT System Studio
+ * Copyright: (C) 2023 LingYun IoT System Studio.
* All rights reserved.
*
* Filename: logger.c
- * Description: This file is the linux infrastructural logger system library
- *
- * Version: 1.0.0(08/08/2020~)
+ * Description: This file is common logger API functions
+ *
+ * Version: 1.0.0(11/08/23)
* Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "08/08/2020 04:24:01 PM"
- *
+ * ChangeLog: 1, Release initial version on "11/08/23 16:18:43"
+ *
********************************************************************************/
+
+#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"
-#define PRECISE_TIME_FACTOR 1000
+typedef void (*log_LockFn)(void *udata, int lock);
-static unsigned long log_rollback_size = LOG_ROLLBACK_NONE;
+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;
-/* This library is not thread safe */
-static logger_t *logger = NULL;
+static const char *level_names[] = {
+ "ERROR",
+ "WARN",
+ "INFO",
+ "DEBUG",
+ "TRACE"
+};
-char *log_str[LOG_LEVEL_MAX + 1] = { "", "F", "E", "W", "N", "D", "I", "T", "M" };
+static const char *level_colors[] = {
+ "\x1b[31m",
+ "\x1b[33m",
+ "\x1b[32m",
+ "\x1b[36m",
+ "\x1b[94m"
+};
-#define LOG_TIME_FMT "%Y-%m-%d %H:%M:%S"
-
-static void log_signal_handler(int sig)
+static inline void time_to_str(char *buf)
{
- if(!logger)
- return ;
+ struct timeval tv;
+ struct tm *tm;
+ int len;
- if (sig == SIGHUP)
- {
- signal(SIGHUP, log_signal_handler);
- log_fatal("SIGHUP received - reopenning log file [%s]", logger->file);
- logger_reopen();
- }
+ 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 logger_banner(char *prefix)
+static void mutex_lock(void *udata, int lock)
{
- if(!logger)
- return ;
+ int err;
+ pthread_mutex_t *l = (pthread_mutex_t *) udata;
- fprintf(logger->fp, "%s log \"%s\" on level [%s] size [%lu] KiB, log system version %s\n",
- prefix, logger->file, log_str[logger->level], log_rollback_size / 1024, LOG_VERSION_STR);
-#ifdef LOG_FILE_LINE
- fprintf(logger->fp, " [ Date ] [ Time ] [ Level ] [ File/Line ] [ Message ]\n");
-#else
- fprintf(logger->fp, " [ Date ] [ Time ] [ Level ] [ Message ]\n");
-#endif
- fprintf(logger->fp, "-------------------------------------------------------------\n");
-}
-
-static void check_and_rollback(void)
-{
- if(!logger)
- return ;
-
- if (log_rollback_size != LOG_ROLLBACK_NONE)
+ if (lock)
{
- long _curOffset = ftell(logger->fp);
-
- if ((_curOffset != -1) && (_curOffset >= log_rollback_size))
- {
- char cmd[512];
-
- snprintf(cmd, sizeof(cmd), "cp -f %s %s.roll", logger->file, logger->file);
- system(cmd);
-
- if (-1 == fseek(logger->fp, 0L, SEEK_SET))
- fprintf(logger->fp, "log rollback fseek failed \n");
-
- rewind(logger->fp);
-
- truncate(logger->file, 0);
- logger_banner("Already rollback");
- }
- }
-}
-
-
-/* log_size unit is KB */
-int logger_init(logger_t *log, char *log_file, int level, int log_size)
-{
- if( !log )
- {
- printf("ERROR: Invalid input arguments\n");
- return -1;
- }
-
- if( log_file )
- {
- strncpy(log->file, log_file, FILENAME_LEN);
- log->flag |= FLAG_LOGGER_FILE;
+ if ( (err = pthread_mutex_lock(l)) != 0 )
+ log_error("Unable to lock log lock: %s", strerror(err));
}
else
{
- strncpy(log->file, DBG_LOG_FILE, FILENAME_LEN);
- log->flag |= FLAG_LOGGER_CONSOLE;
+ 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));
}
- log->level = level;
- log->size = log_size;
- /* set static global $logger point to argument $log */
- logger = log;
+ 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;
}
-int logger_open(void)
+void log_close(void)
{
- struct sigaction act;
- char *filemode;
+ if( L.fp && L.fp!=stderr )
+ fclose(L.fp);
- if(!logger)
- {
- printf("ERROR: logger not initialise\n");
- return -1;
- }
-
- log_rollback_size = logger->size <= 0 ? LOG_ROLLBACK_NONE : logger->size*1024; /* Unit KiB */
-
- if ('\0' == logger->file[0])
- {
- printf("ERROR: Logger filename not set\n");
- return -1;
- }
-
- if (!strcmp(logger->file, DBG_LOG_FILE))
- {
- logger->fp = stderr;
- log_rollback_size = LOG_ROLLBACK_NONE;
- logger->flag |= FLAG_LOGGER_CONSOLE;
- goto OUT;
- }
-
- filemode = (log_rollback_size==LOG_ROLLBACK_NONE) ? "a+" : "w+";
-
- logger->fp = fopen(logger->file, filemode);
- if (NULL == logger->fp)
- {
- fprintf(stderr, "Open log file \"%s\" in %s failure: %s\n", logger->file, filemode, strerror(errno));
- return -2;
- }
-
- act.sa_handler = log_signal_handler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- sigaction(SIGHUP, &act, NULL);
-
- OUT:
- logger_banner("Initialize");
-
- return 0;
+ if (L.udata )
+ pthread_mutex_destroy( L.udata);
}
-void logger_close(void)
+static void log_rollback(void)
{
- if (!logger || !logger->fp )
- return;
+ char cmd[128]={0};
+ long fsize;
- logger_banner("\nTerminate");
- logger_raw("\n\n\n\n");
+ /* don't need rollback */
+ if(L.size <= 0 )
+ return ;
- fflush(logger->fp);
+ fsize = ftell(L.fp);
+ if( fsize < L.size )
+ return ;
- fclose(logger->fp);
- logger->fp = NULL;
+ /* 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 ;
}
-int logger_reopen(void)
+void _log_write(int level, const char *file, int line, const char *fmt, ...)
{
- int rc = 0;
- char *filemode;
+ va_list args;
+ char time_string[100];
- if( !logger )
- return -1;
-
- log_rollback_size = logger->size <= 0 ? LOG_ROLLBACK_NONE : logger->size*1024; /* Unit KiB */
-
- if (logger->flag & FLAG_LOGGER_CONSOLE )
- {
- fflush(logger->fp);
- logger->fp = stderr;
- return 0;
- }
-
- if (logger->fp)
- {
- logger_close();
- filemode = log_rollback_size==LOG_ROLLBACK_NONE ? "a+" : "w+";
- logger->fp = fopen(logger->file, filemode);
-
- if (logger->fp == NULL)
- rc = -2;
- }
- else
- {
- rc = -3;
- }
-
- if (!rc)
- {
- logger_banner("\nReopen");
- }
- return rc;
-}
-
-void logger_term(void)
-{
- if(!logger)
- return ;
-
- logger_close();
-
- logger = NULL;
-}
-
-void logger_raw(const char *fmt, ...)
-{
- va_list argp;
-
- if (!logger || !logger->fp)
+ if ( !L.fp || level>L.level )
return;
- check_and_rollback();
+ /* Acquire lock */
+ if ( L.lockfn )
+ L.lockfn(L.udata, 1);
- va_start(argp, fmt);
- vfprintf(logger->fp, fmt, argp);
- va_end(argp);
-}
+ log_rollback();
-static void cp_printout(char *level, char *fmt, va_list argp)
-{
- char buf[MAX_LOG_MESSAGE_LEN];
- struct tm *local;
- struct timeval now;
- char timestr[256];
+ /* check and rollback file */
+ time_to_str(time_string);
- if(!logger)
- return ;
-
- check_and_rollback();
-
- gettimeofday(&now, NULL);
- local = localtime(&now.tv_sec);
-
- strftime(timestr, 256, LOG_TIME_FMT, local);
- vsnprintf(buf, MAX_LOG_MESSAGE_LEN, fmt, argp);
-
-#ifdef DUMPLICATE_OUTPUT
- printf("%s.%03ld [%s] : %s",
- timestr, now.tv_usec / PRECISE_TIME_FACTOR, level, buf);
-#endif
-
- if (logger->fp)
- fprintf(logger->fp, "%s.%03ld [%s] : %s", timestr, now.tv_usec / PRECISE_TIME_FACTOR, level, buf);
-
- if (logger->fp)
- fflush(logger->fp);
-}
-
-static void cp_printout_line(char *level, char *fmt, char *file, int line, va_list argp)
-{
- char buf[MAX_LOG_MESSAGE_LEN];
- struct tm *local;
- struct timeval now;
- char timestr[256];
-
- if(!logger)
- return ;
-
- check_and_rollback();
-
- gettimeofday(&now, NULL);
- local = localtime(&now.tv_sec);
-
- strftime(timestr, 256, LOG_TIME_FMT, local);
- vsnprintf(buf, MAX_LOG_MESSAGE_LEN, fmt, argp);
-
-#ifdef DUMPLICATE_OUTPUT
- printf("[%s.%03ld] <%s> <%s:%04d> : %s",
- timestr, now.tv_usec / PRECISE_TIME_FACTOR, level, file, line, buf);
-#endif
-
- if (logger->fp)
+ /* Log to stderr */
+ if ( L.fp == stderr )
{
- fprintf(logger->fp, "[%s.%03ld] <%s> <%s:%04d> : %s",
- timestr, now.tv_usec / PRECISE_TIME_FACTOR, level, file, line, buf);
-
- fflush(logger->fp);
+ fprintf(L.fp, "%s %s %-5s\x1b[0m \x1b[90m%s:%03d:\x1b[0m ",
+ time_string, level_colors[level], level_names[level], file, line);
}
-}
-
-void logger_str(int level, const char *msg)
-{
- if (!logger || level>logger->level)
- return;
-
- check_and_rollback();
-
- if (logger->fp)
- fwrite(msg, 1, strlen(msg), logger->fp);
-
- if(logger->fp)
- fflush(logger->fp);
-}
-
-void logger_min(int level, char *fmt, ...)
-{
- va_list argp;
-
- if (!logger || level>logger->level)
- return;
-
- va_start(argp, fmt);
- cp_printout(log_str[level], fmt, argp);
- va_end(argp);
-}
-
-void logger_line(int level, char *file, int line, char *fmt, ...)
-{
- va_list argp;
-
- if (!logger || level>logger->level)
- return;
-
- va_start(argp, fmt);
- cp_printout_line(log_str[level], fmt, file, line, argp);
-
- va_end(argp);
-}
-
-#define LINELEN 81
-#define CHARS_PER_LINE 16
-static char *print_char =
- " "
- " "
- " !\"#$%&'()*+,-./"
- "0123456789:;<=>?"
- "@ABCDEFGHIJKLMNO"
- "PQRSTUVWXYZ[\\]^_"
- "`abcdefghijklmno"
- "pqrstuvwxyz{|}~ "
- " "
- " "
- " ???????????????"
- "????????????????"
- "????????????????"
- "????????????????"
- "????????????????"
- "????????????????";
-
-void logger_dump(int level, char *buf, int len)
-{
- int rc;
- int idx;
- char prn[LINELEN];
- char lit[CHARS_PER_LINE + 2];
- char hc[4];
- short line_done = 1;
-
- if (!logger || level>logger->level)
- return;
-
- rc = len;
- idx = 0;
- lit[CHARS_PER_LINE] = '\0';
-
- while (rc > 0)
+ else /* Log to file */
{
- if (line_done)
- snprintf(prn, LINELEN, "%08X: ", idx);
+ fprintf(L.fp, "%s %-5s %s:%03d: ", time_string, level_names[level], file, line);
+ }
- do
+ 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);
+}
+
+
+void log_dump(int level, const char *prompt, char *buf, size_t len)
+{
+ int i, j, ofset;
+ char line[256];
+ unsigned char c;
+ unsigned char *buffer = (unsigned char *)buf;
+
+ if (!L.fp || level>L.level)
+ return;
+
+ if( prompt )
+ _log_write(level, __FILE__, __LINE__, "%s\r\n", prompt);
+
+ for(i=0; i<len; i+=16)
+ {
+ ofset = snprintf(line, sizeof(line), "%04x: ", i);
+
+ /* print hex representation, and print spaces if end of buffer */
+ for(j=0; j<16; j++)
{
- unsigned char c = buf[idx];
- snprintf(hc, 4, "%02X ", c);
- strncat(prn, hc, LINELEN);
-
- lit[idx % CHARS_PER_LINE] = print_char[c];
+ if(i+j < len)
+ ofset += snprintf(line+ofset, sizeof(line)-ofset, "%02x ", buffer[i+j]);
+ else
+ ofset += snprintf(line+ofset, sizeof(line)-ofset, " ");
}
- while (--rc > 0 && (++idx % CHARS_PER_LINE != 0));
+ ofset += snprintf(line+ofset, sizeof(line)-ofset, " ");
- line_done = (idx % CHARS_PER_LINE) == 0;
- if (line_done)
+ /* print ASCII representation */
+ for(j=0; j<16; j++)
{
-#ifdef DUMPLICATE_OUTPUT
- printf("%s %s\n", prn, lit);
-#endif
- if (logger->fp)
- fprintf(logger->fp, "%s %s\n", prn, lit);
+ if (i+j < len)
+ {
+ c = buffer[i+j];
+ ofset += snprintf(line+ofset, sizeof(line)-ofset, "%c", (c>=32 && c<=126) ? c : '.');
+ }
+ else
+ {
+ ofset += snprintf(line+ofset, sizeof(line)-ofset, " ");
+ }
}
- }
- 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));
-
-#ifdef DUMPLICATE_OUTPUT
- printf("%s %s\n", prn, lit);
-#endif
- if (logger->fp)
- fprintf(logger->fp, "%s %s\n", prn, lit);
-
+ if (L.fp)
+ fprintf(L.fp, "%s\r\n", line);
}
}
+
--
Gitblit v1.9.1