comparison logging.c @ 251:307fd62f376d

Implement log file rotation
author Daniele Nicolodi <daniele@grinta.net>
date Thu, 28 May 2015 16:12:18 +0200
parents eaac96094640
children d948e3ced2b9
comparison
equal deleted inserted replaced
250:9b35a2b2c759 251:307fd62f376d
10 extern double utc; 10 extern double utc;
11 /* main panel id */ 11 /* main panel id */
12 extern unsigned int MainPanel; 12 extern unsigned int MainPanel;
13 13
14 14
15 struct logger {
16 unsigned int panel;
17 char *dirpath;
18 char *filepath;
19 int fd;
20 int level;
21 int yday;
22 void(*onerror)(int, const char *);
23 };
24
25
26 static inline int strtolevel(const char *str)
27 {
28 for (int i = 0; i < 4; i++) {
29 if (streq(levels[i], str))
30 return i;
31 }
32 return DEBUG;
33 }
34
35
36 static int rotate(struct logger *l, struct tm *t)
37 {
38 int rv;
39 char id[7];
40
41 if (! l->dirpath)
42 return;
43
44 if (l->yday == t.rm_yday)
45 return 0;
46
47 /* close old file descriptor */
48 close(l->fd);
49 l->fd = -1;
50
51 /* construct new file name */
52 strftime(id, sizeof(id), "%y%m%d", t);
53 rv = asprintf(&l->filepath, "%s\\%s-Log.txt", l->dirpath, id);
54 if (rv < 0)
55 return rv;
56
57 /* open new log file */
58 rv = open(filename, O_CREAT|O_WRONLY|O_APPEND, 00744);
59 if (rv < 0)
60 return rv;
61
62 /* update status */
63 l->fd = rv;
64 l->yday = t.rm_yday;
65
66 return 1;
67 }
68
69
15 int __logger_init(struct logger *l, void(*onerror)(int, const char *)) 70 int __logger_init(struct logger *l, void(*onerror)(int, const char *))
16 { 71 {
17 int rv, panel; 72 int rv, panel;
18 char path[MAX_PATHNAME_LEN], *filename; 73 char path[MAX_PATHNAME_LEN], *filename;
74
75 l = malloc(sizeof(struct logger));
76 memset(l, 0, sizeof(*l));
19 77
20 l->onerror = onerror; 78 l->onerror = onerror;
21 l->fd = -1; 79 l->fd = -1;
80 l->level = DEBUG;
22 81
23 panel = LoadPanel(0, "FXAnalyse.uir", LOGGING); 82 panel = LoadPanel(0, "FXAnalyse.uir", LOGGING);
24 if (panel < 0) 83 if (panel < 0)
25 return -1; 84 return -1;
26 l->panel = panel; 85 l->panel = panel;
30 89
31 /* load configuration file */ 90 /* load configuration file */
32 IniText configuration = Ini_New(TRUE); 91 IniText configuration = Ini_New(TRUE);
33 Ini_ReadFromFile(configuration, path); 92 Ini_ReadFromFile(configuration, path);
34 93
35 /* logging file name */ 94 /* logging folder path */
36 rv = Ini_GetStringCopy(configuration, "logging", "filename", &filename); 95 rv = Ini_GetStringCopy(configuration, "logging", "folder", &l->dirname);
96
97 /* logging level */
98 rv = Ini_GetStringCopy(configuration, "logging", "level", &str);
37 if (rv > 0) { 99 if (rv > 0) {
38 __logmessage(l, INFO, "logging to '%s'", filename); 100 l->level = strtolevel(str);
39 l->fd = open(filename, O_CREAT|O_WRONLY|O_APPEND, 00744); 101 free(str);
40 if (l->fd < 0)
41 __logmessage(l, ERROR, "open log file %s: %s", filename, strerror(errno));
42 } 102 }
43 103
44 free(filename);
45 Ini_Dispose(configuration); 104 Ini_Dispose(configuration);
46 105
47 return 0; 106 return 0;
48 } 107 }
49 108
60 char msg[1024]; 119 char msg[1024];
61 int len = 0; 120 int len = 0;
62 121
63 /* timestamp */ 122 /* timestamp */
64 len += sprintf(msg, "%014.3f ", utc); 123 len += sprintf(msg, "%014.3f ", utc);
65 time_t now = time(NULL); 124 time_t now = (time_t)utc;
125 if (now == 0)
126 now = time(NULL);
66 struct tm *t = localtime(&now); 127 struct tm *t = localtime(&now);
67 len += strftime(msg + len, sizeof(msg) - len, "%d-%m-%Y %H:%M:%S ", t); 128 len += strftime(msg + len, sizeof(msg) - len, "%d-%m-%Y %H:%M:%S ", t);
68 129
69 /* level */ 130 /* level */
70 len += snprintf(msg + len, sizeof(msg) - len, "%s: ", levels[level]); 131 len += snprintf(msg + len, sizeof(msg) - len, "%s: ", levels[level]);
88 149
89 /* report error */ 150 /* report error */
90 if (level == ERROR) 151 if (level == ERROR)
91 l->onerror(level, msg); 152 l->onerror(level, msg);
92 153
154 /* rotate log file based on current date */
155 rotate(l, t);
156
93 /* write to log file */ 157 /* write to log file */
94 if (l->fd >= 0) 158 if ((level <= l->level) && (l->fd >= 0))
95 write(l->fd, msg, len); 159 write(l->fd, msg, len);
96 } 160 }
161
162
163 void __logger_panel_visible(struct logger *l, visible)
164 {
165 SetPanelAttribute(l->panel, ATTR_VISIBLE, visible);
166 }