Mercurial > hg > fxanalyse
view logging.c @ 260:3622e24a443f
Also rotate log file at midnight UTC not local time
author | Daniele Nicolodi <daniele.nicolodi@obspm.fr> |
---|---|
date | Tue, 16 Jun 2015 15:06:19 +0200 |
parents | d948e3ced2b9 |
children |
line wrap: on
line source
#include <ansi_c.h> #include <inifile.h> #include <lowlvlio.h> #include <ansi_c.h> #include "config.h" #include "logging.h" /* this refers to the event time defined as a global variable in the main program */ extern double utc; /* main panel id */ 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 const char *levels[] = { [ERROR] = "ERROR", [WARNING] = "WARNING", [INFO] = "INFO", [DEBUG] = "DEBUG", }; 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, time_t now) { int len, rv; char id[7]; struct tm *t; if (! l->dirpath) return 0; /* utc day */ t = gmtime(&now); if (l->yday == t->tm_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); len = strlen(l->dirpath) + 1 + sizeof(id) + strlen("-Log.txt") + 1; l->filepath = malloc(len); snprintf(l->filepath, len, "%s\\%s-Log.txt", l->dirpath, id); /* open new log file */ rv = open(l->filepath, O_CREAT|O_WRONLY|O_APPEND, 00744); if (rv < 0) return rv; /* update status */ l->fd = rv; l->yday = t->tm_yday; __logmessage(l, DEBUG, "logging to '%s'", l->filepath); return 1; } struct logger * __logger_init(void(*onerror)(int, const char *)) { int rv, panel; char path[MAX_PATHNAME_LEN], *str; struct logger *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) return NULL; l->panel = panel; /* configuration file path */ GetIniFilePath(path); /* load configuration file */ IniText configuration = Ini_New(TRUE); Ini_ReadFromFile(configuration, path); /* logging folder path */ rv = Ini_GetStringCopy(configuration, "logging", "folder", &l->dirpath); /* logging level */ rv = Ini_GetStringCopy(configuration, "logging", "level", &str); if (rv > 0) { l->level = strtolevel(str); free(str); } Ini_Dispose(configuration); return l; } void __logmessage(struct logger *l, enum loglevel level, const char *frmt, ...) { char msg[1024]; int len = 0; /* timestamp */ len += sprintf(msg, "%014.3f ", utc); 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); /* level */ len += snprintf(msg + len, sizeof(msg) - len, "%s: ", levels[level]); /* message */ va_list args; va_start(args, frmt); len += vsnprintf(msg + len, sizeof(msg) - len, frmt, args); va_end(args); /* newline */ len = MIN(len, sizeof(msg) - 3); msg[len++] = '\r'; msg[len++] = '\n'; /* string terminator */ msg[len] = '\0'; /* rotate log file based on current date */ rotate(l, now); /* write to log file */ if ((level <= l->level) && (l->fd >= 0)) write(l->fd, msg, len); /* display message */ SetCtrlVal(l->panel, LOGGING_LOGGING, msg); /* report error */ if (level == ERROR) l->onerror(level, msg); } void __logger_panel_visible(struct logger *l, int visible) { SetPanelAttribute(l->panel, ATTR_VISIBLE, visible); }