Mercurial > hg > fxanalyse
view logging.c @ 258:5296f3bcd160
Implement DDS clients reconnect
On network send() failures try to reconnect to the server before
returning an error. This allows to restart the network servers
controlling the DDSes wiothout having to restart the clients.
author | Daniele Nicolodi <daniele.nicolodi@obspm.fr> |
---|---|
date | Tue, 16 Jun 2015 14:31:35 +0200 |
parents | d948e3ced2b9 |
children | 3622e24a443f |
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, struct tm *t) { int len, rv; char id[7]; if (! l->dirpath) return 0; 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, t); /* 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); }