changeset 251:307fd62f376d

Implement log file rotation
author Daniele Nicolodi <daniele@grinta.net>
date Thu, 28 May 2015 16:12:18 +0200
parents 9b35a2b2c759
children d948e3ced2b9
files FXAnalyse.ini logging.c logging.h
diffstat 3 files changed, 90 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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);
+}
--- 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