]> git.ipfire.org Git - thirdparty/chrony.git/blame - logging.c
conf: rework allow/deny parser
[thirdparty/chrony.git] / logging.c
CommitLineData
88840341 1/*
88840341
RC
2 chronyd/chronyc - Programs for keeping computer clocks accurate.
3
4 **********************************************************************
6672f045 5 * Copyright (C) Richard P. Curnow 1997-2003
3916c336 6 * Copyright (C) Miroslav Lichvar 2011-2014, 2018-2020
88840341
RC
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
8e23110a 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
88840341
RC
20 *
21 **********************************************************************
22
23 =======================================================================
24
25 Module to handle logging of diagnostic information
26 */
27
da2c8d90
ML
28#include "config.h"
29
88840341
RC
30#include "sysincl.h"
31
903fa247
ML
32#include <syslog.h>
33
e78e65ef 34#include "conf.h"
88840341 35#include "logging.h"
51d77d6c 36#include "memory.h"
9d35b5de 37#include "util.h"
88840341 38
0dea8d97 39/* This is used by DEBUG_LOG macro */
1227873b 40LOG_Severity log_min_severity = LOGS_INFO;
0dea8d97 41
88840341
RC
42/* ================================================== */
43/* Flag indicating we have initialised */
44static int initialised = 0;
45
d05e9fb2 46static FILE *file_log = NULL;
fe4b661f 47static int system_log = 0;
88840341 48
1d2a0856
ML
49static int parent_fd = 0;
50
e78e65ef
ML
51struct LogFile {
52 const char *name;
53 const char *banner;
54 FILE *file;
55 unsigned long writes;
56};
57
58static int n_filelogs = 0;
59
60/* Increase this when adding a new logfile */
c386d117 61#define MAX_FILELOGS 6
e78e65ef
ML
62
63static struct LogFile logfiles[MAX_FILELOGS];
64
51d77d6c
ML
65/* Global prefix for debug messages */
66static char *debug_prefix;
67
88840341
RC
68/* ================================================== */
69/* Init function */
70
71void
72LOG_Initialise(void)
73{
51d77d6c 74 debug_prefix = Strdup("");
88840341 75 initialised = 1;
d05e9fb2 76 LOG_OpenFileLog(NULL);
88840341
RC
77}
78
79/* ================================================== */
80/* Fini function */
81
82void
83LOG_Finalise(void)
84{
7b98443a 85 if (system_log)
88840341 86 closelog();
7b98443a
ML
87
88 if (file_log)
6cbeb107 89 fclose(file_log);
88840341 90
e78e65ef
ML
91 LOG_CycleLogFiles();
92
51d77d6c
ML
93 Free(debug_prefix);
94
88840341 95 initialised = 0;
88840341
RC
96}
97
98/* ================================================== */
99
cd7bfa25 100static void log_message(int fatal, LOG_Severity severity, const char *message)
88840341 101{
fe4b661f 102 if (system_log) {
cd7bfa25 103 int priority;
88840341 104 switch (severity) {
4bbc5520
ML
105 case LOGS_DEBUG:
106 priority = LOG_DEBUG;
107 break;
88840341 108 case LOGS_INFO:
cd7bfa25 109 priority = LOG_INFO;
88840341
RC
110 break;
111 case LOGS_WARN:
cd7bfa25 112 priority = LOG_WARNING;
88840341
RC
113 break;
114 case LOGS_ERR:
cd7bfa25
ML
115 priority = LOG_ERR;
116 break;
117 case LOGS_FATAL:
118 priority = LOG_CRIT;
88840341 119 break;
cd7bfa25
ML
120 default:
121 assert(0);
88840341 122 }
cd7bfa25 123 syslog(priority, fatal ? "Fatal error : %s" : "%s", message);
7b98443a 124 } else if (file_log) {
6cbeb107 125 fprintf(file_log, fatal ? "Fatal error : %s\n" : "%s\n", message);
88840341 126 }
88840341
RC
127}
128
129/* ================================================== */
130
7b2430fc
ML
131void LOG_Message(LOG_Severity severity,
132#if DEBUG > 0
f282856c 133 int line_number, const char *filename, const char *function_name,
7b2430fc
ML
134#endif
135 const char *format, ...)
88840341
RC
136{
137 char buf[2048];
138 va_list other_args;
cd7bfa25 139 time_t t;
63fe34e8 140 struct tm *tm;
88840341 141
51d77d6c
ML
142 assert(initialised);
143
1227873b 144 if (!system_log && file_log && severity >= log_min_severity) {
788e7fcd 145 /* Don't clutter up syslog with timestamps and internal debugging info */
88840341 146 time(&t);
63fe34e8
ML
147 tm = gmtime(&t);
148 if (tm) {
149 strftime(buf, sizeof (buf), "%Y-%m-%dT%H:%M:%SZ", tm);
150 fprintf(file_log, "%s ", buf);
151 }
7b2430fc 152#if DEBUG > 0
1227873b 153 if (log_min_severity <= LOGS_DEBUG)
51d77d6c 154 fprintf(file_log, "%s%s:%d:(%s) ", debug_prefix, filename, line_number, function_name);
7b2430fc 155#endif
88840341 156 }
cd7bfa25
ML
157
158 va_start(other_args, format);
159 vsnprintf(buf, sizeof(buf), format, other_args);
160 va_end(other_args);
161
162 switch (severity) {
4bbc5520 163 case LOGS_DEBUG:
cd7bfa25
ML
164 case LOGS_INFO:
165 case LOGS_WARN:
166 case LOGS_ERR:
1227873b
ML
167 if (severity >= log_min_severity)
168 log_message(0, severity, buf);
cd7bfa25
ML
169 break;
170 case LOGS_FATAL:
1227873b
ML
171 if (severity >= log_min_severity)
172 log_message(1, severity, buf);
cd7bfa25 173
7b98443a
ML
174 /* Send the message also to the foreground process if it is
175 still running, or stderr if it is still open */
176 if (parent_fd > 0) {
177 if (write(parent_fd, buf, strlen(buf) + 1) < 0)
178 ; /* Not much we can do here */
179 } else if (system_log && parent_fd == 0) {
180 system_log = 0;
181 log_message(1, severity, buf);
cd7bfa25 182 }
f4c6a00b 183 exit(1);
cd7bfa25
ML
184 break;
185 default:
186 assert(0);
187 }
88840341
RC
188}
189
6cbeb107
ML
190/* ================================================== */
191
192void
193LOG_OpenFileLog(const char *log_file)
194{
195 FILE *f;
196
eb8c9ad6 197 if (log_file) {
794cbfbb 198 f = UTI_OpenFile(NULL, log_file, NULL, 'A', 0640);
eb8c9ad6
ML
199 } else {
200 f = stderr;
201 }
6cbeb107 202
d70df3da
ML
203 /* Enable line buffering */
204 setvbuf(f, NULL, _IOLBF, BUFSIZ);
205
68475366
ML
206 if (file_log && file_log != stderr)
207 fclose(file_log);
208
6cbeb107
ML
209 file_log = f;
210}
211
212
88840341
RC
213/* ================================================== */
214
215void
fe4b661f 216LOG_OpenSystemLog(void)
88840341 217{
fe4b661f
ML
218 system_log = 1;
219 openlog("chronyd", LOG_PID, LOG_DAEMON);
88840341
RC
220}
221
032ac800
ML
222/* ================================================== */
223
1227873b 224void LOG_SetMinSeverity(LOG_Severity severity)
4bbc5520 225{
c7223f4c
ML
226 /* Don't print any debug messages in a non-debug build */
227 log_min_severity = CLAMP(DEBUG > 0 ? LOGS_DEBUG : LOGS_INFO, severity, LOGS_FATAL);
4bbc5520
ML
228}
229
230/* ================================================== */
231
51d77d6c
ML
232LOG_Severity
233LOG_GetMinSeverity(void)
234{
235 return log_min_severity;
236}
237
238/* ================================================== */
239
240void
241LOG_SetDebugPrefix(const char *prefix)
242{
243 Free(debug_prefix);
244 debug_prefix = Strdup(prefix);
245}
246
247/* ================================================== */
248
1d2a0856
ML
249void
250LOG_SetParentFd(int fd)
251{
252 parent_fd = fd;
7b98443a
ML
253 if (file_log == stderr)
254 file_log = NULL;
1d2a0856
ML
255}
256
257/* ================================================== */
258
259void
260LOG_CloseParentFd()
261{
262 if (parent_fd > 0)
263 close(parent_fd);
ed0ac6e3 264 parent_fd = -1;
1d2a0856
ML
265}
266
267/* ================================================== */
268
e78e65ef
ML
269LOG_FileID
270LOG_FileOpen(const char *name, const char *banner)
271{
c9f03fb2
ML
272 if (n_filelogs >= MAX_FILELOGS) {
273 assert(0);
274 return -1;
275 }
e78e65ef
ML
276
277 logfiles[n_filelogs].name = name;
278 logfiles[n_filelogs].banner = banner;
279 logfiles[n_filelogs].file = NULL;
280 logfiles[n_filelogs].writes = 0;
281
282 return n_filelogs++;
283}
284
285/* ================================================== */
286
287void
288LOG_FileWrite(LOG_FileID id, const char *format, ...)
289{
290 va_list other_args;
7ab2c0e4 291 int banner;
e78e65ef
ML
292
293 if (id < 0 || id >= n_filelogs || !logfiles[id].name)
294 return;
295
296 if (!logfiles[id].file) {
e18903a6 297 char *logdir = CNF_GetLogDir();
fb5d4f1d 298
60049f15 299 if (!logdir) {
f282856c 300 LOG(LOGS_WARN, "logdir not specified");
fb5d4f1d
ML
301 logfiles[id].name = NULL;
302 return;
303 }
e78e65ef 304
e18903a6
ML
305 logfiles[id].file = UTI_OpenFile(logdir, logfiles[id].name, ".log", 'a', 0644);
306 if (!logfiles[id].file) {
307 /* Disable the log */
e78e65ef
ML
308 logfiles[id].name = NULL;
309 return;
310 }
311 }
312
7ab2c0e4
ML
313 banner = CNF_GetLogBanner();
314 if (banner && logfiles[id].writes++ % banner == 0) {
e78e65ef
ML
315 char bannerline[256];
316 int i, bannerlen;
317
96771d68 318 bannerlen = MIN(strlen(logfiles[id].banner), sizeof (bannerline) - 1);
e78e65ef
ML
319
320 for (i = 0; i < bannerlen; i++)
321 bannerline[i] = '=';
322 bannerline[i] = '\0';
323
324 fprintf(logfiles[id].file, "%s\n", bannerline);
325 fprintf(logfiles[id].file, "%s\n", logfiles[id].banner);
326 fprintf(logfiles[id].file, "%s\n", bannerline);
327 }
328
329 va_start(other_args, format);
330 vfprintf(logfiles[id].file, format, other_args);
331 va_end(other_args);
332 fprintf(logfiles[id].file, "\n");
333
334 fflush(logfiles[id].file);
335}
336
337/* ================================================== */
338
e78e65ef
ML
339void
340LOG_CycleLogFiles(void)
341{
342 LOG_FileID i;
343
344 for (i = 0; i < n_filelogs; i++) {
345 if (logfiles[i].file)
346 fclose(logfiles[i].file);
347 logfiles[i].file = NULL;
348 logfiles[i].writes = 0;
349 }
350}
351
352/* ================================================== */