# HG changeset patch # User Daniele Nicolodi # Date 1432822338 -7200 # Node ID 307fd62f376db6662a47ceefbc15cc35ba983c91 # Parent 9b35a2b2c75973428bb579c8e6342bdcacf5e1df Implement log file rotation diff -r 9b35a2b2c759 -r 307fd62f376d FXAnalyse.ini --- a/FXAnalyse.ini Mon May 04 17:48:07 2015 +0200 +++ b/FXAnalyse.ini Thu May 28 16:12:18 2015 +0200 @@ -1,3 +1,7 @@ +[logging] +level = DEBUG +folder = C:\\\\data\\test + [AD9912] clock = 1000e6 host = 145.238.205.55 diff -r 9b35a2b2c759 -r 307fd62f376d logging.c --- a/logging.c Mon May 04 17:48:07 2015 +0200 +++ b/logging.c Thu May 28 16:12:18 2015 +0200 @@ -12,13 +12,72 @@ extern unsigned int MainPanel; +struct logger { + unsigned int panel; + char *dirpath; + char *filepath; + int fd; + int level; + int yday; + void(*onerror)(int, const char *); +}; + + +static inline int strtolevel(const char *str) +{ + for (int i = 0; i < 4; i++) { + if (streq(levels[i], str)) + return i; + } + return DEBUG; +} + + +static int rotate(struct logger *l, struct tm *t) +{ + int rv; + char id[7]; + + if (! l->dirpath) + return; + + if (l->yday == t.rm_yday) + return 0; + + /* close old file descriptor */ + close(l->fd); + l->fd = -1; + + /* construct new file name */ + strftime(id, sizeof(id), "%y%m%d", t); + rv = asprintf(&l->filepath, "%s\\%s-Log.txt", l->dirpath, id); + if (rv < 0) + return rv; + + /* open new log file */ + rv = open(filename, O_CREAT|O_WRONLY|O_APPEND, 00744); + if (rv < 0) + return rv; + + /* update status */ + l->fd = rv; + l->yday = t.rm_yday; + + return 1; +} + + int __logger_init(struct logger *l, void(*onerror)(int, const char *)) { int rv, panel; char path[MAX_PATHNAME_LEN], *filename; + + l = malloc(sizeof(struct logger)); + memset(l, 0, sizeof(*l)); l->onerror = onerror; l->fd = -1; + l->level = DEBUG; panel = LoadPanel(0, "FXAnalyse.uir", LOGGING); if (panel < 0) @@ -32,16 +91,16 @@ IniText configuration = Ini_New(TRUE); Ini_ReadFromFile(configuration, path); - /* logging file name */ - rv = Ini_GetStringCopy(configuration, "logging", "filename", &filename); + /* logging folder path */ + rv = Ini_GetStringCopy(configuration, "logging", "folder", &l->dirname); + + /* logging level */ + rv = Ini_GetStringCopy(configuration, "logging", "level", &str); if (rv > 0) { - __logmessage(l, INFO, "logging to '%s'", filename); - l->fd = open(filename, O_CREAT|O_WRONLY|O_APPEND, 00744); - if (l->fd < 0) - __logmessage(l, ERROR, "open log file %s: %s", filename, strerror(errno)); + l->level = strtolevel(str); + free(str); } - - free(filename); + Ini_Dispose(configuration); return 0; @@ -62,7 +121,9 @@ /* timestamp */ len += sprintf(msg, "%014.3f ", utc); - time_t now = time(NULL); + time_t now = (time_t)utc; + if (now == 0) + now = time(NULL); struct tm *t = localtime(&now); len += strftime(msg + len, sizeof(msg) - len, "%d-%m-%Y %H:%M:%S ", t); @@ -90,7 +151,16 @@ if (level == ERROR) l->onerror(level, msg); + /* rotate log file based on current date */ + rotate(l, t); + /* write to log file */ - if (l->fd >= 0) + if ((level <= l->level) && (l->fd >= 0)) write(l->fd, msg, len); } + + +void __logger_panel_visible(struct logger *l, visible) +{ + SetPanelAttribute(l->panel, ATTR_VISIBLE, visible); +} diff -r 9b35a2b2c759 -r 307fd62f376d logging.h --- a/logging.h Mon May 04 17:48:07 2015 +0200 +++ b/logging.h Thu May 28 16:12:18 2015 +0200 @@ -5,11 +5,7 @@ #include "FXAnalyse.h" #include "utils.h" -struct logger { - unsigned int panel; - int fd; - void(*onerror)(int, const char *); -} __logger; +struct logger *__logger; /* an ERROR macro is defined in `WinGDI.h` which is included * by some other header file included before this. to be on @@ -25,10 +21,11 @@ int __logger_init(struct logger *l, void(*onerror)(int, const char *)); void __logmessage(struct logger *l, enum loglevel level, const char *frmt, ...); +int __logger_panel_visible(struct logger *l, int visible); -#define logger_init(onerror) __logger_init(&__logger, onerror) -#define logmessage(level, msg, ...) __logmessage(&__logger, (level), (msg), ##__VA_ARGS__) -#define logmsg(msg, ...) __logmessage(&__logger, INFO, msg, ##__VA_ARGS__) -#define logger_panel_visible(visible) SetPanelAttribute(__logger.panel, ATTR_VISIBLE, visible) +#define logger_init(onerror) __logger_init(__logger, onerror) +#define logmessage(level, msg, ...) __logmessage(__logger, (level), (msg), ##__VA_ARGS__) +#define logmsg(msg, ...) __logmessage(__logger, INFO, msg, ##__VA_ARGS__) +#define logger_panel_visible(visible) __logger_panel_visible(__logger, visible) #endif