]> git.ipfire.org Git - thirdparty/chrony.git/blame - logging.c
cmdmon: save NTS cookies and server keys on dump command
[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
5dc86c23 6 * Copyright (C) Miroslav Lichvar 2011-2014, 2018
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"
9d35b5de 36#include "util.h"
88840341 37
0dea8d97 38/* This is used by DEBUG_LOG macro */
1227873b 39LOG_Severity log_min_severity = LOGS_INFO;
0dea8d97 40
88840341
RC
41/* ================================================== */
42/* Flag indicating we have initialised */
43static int initialised = 0;
44
d05e9fb2 45static FILE *file_log = NULL;
fe4b661f 46static int system_log = 0;
88840341 47
1d2a0856
ML
48static int parent_fd = 0;
49
e78e65ef
ML
50struct LogFile {
51 const char *name;
52 const char *banner;
53 FILE *file;
54 unsigned long writes;
55};
56
57static int n_filelogs = 0;
58
59/* Increase this when adding a new logfile */
c386d117 60#define MAX_FILELOGS 6
e78e65ef
ML
61
62static struct LogFile logfiles[MAX_FILELOGS];
63
88840341
RC
64/* ================================================== */
65/* Init function */
66
67void
68LOG_Initialise(void)
69{
70 initialised = 1;
d05e9fb2 71 LOG_OpenFileLog(NULL);
88840341
RC
72}
73
74/* ================================================== */
75/* Fini function */
76
77void
78LOG_Finalise(void)
79{
7b98443a 80 if (system_log)
88840341 81 closelog();
7b98443a
ML
82
83 if (file_log)
6cbeb107 84 fclose(file_log);
88840341 85
e78e65ef
ML
86 LOG_CycleLogFiles();
87
88840341 88 initialised = 0;
88840341
RC
89}
90
91/* ================================================== */
92
cd7bfa25 93static void log_message(int fatal, LOG_Severity severity, const char *message)
88840341 94{
fe4b661f 95 if (system_log) {
cd7bfa25 96 int priority;
88840341 97 switch (severity) {
4bbc5520
ML
98 case LOGS_DEBUG:
99 priority = LOG_DEBUG;
100 break;
88840341 101 case LOGS_INFO:
cd7bfa25 102 priority = LOG_INFO;
88840341
RC
103 break;
104 case LOGS_WARN:
cd7bfa25 105 priority = LOG_WARNING;
88840341
RC
106 break;
107 case LOGS_ERR:
cd7bfa25
ML
108 priority = LOG_ERR;
109 break;
110 case LOGS_FATAL:
111 priority = LOG_CRIT;
88840341 112 break;
cd7bfa25
ML
113 default:
114 assert(0);
88840341 115 }
cd7bfa25 116 syslog(priority, fatal ? "Fatal error : %s" : "%s", message);
7b98443a 117 } else if (file_log) {
6cbeb107 118 fprintf(file_log, fatal ? "Fatal error : %s\n" : "%s\n", message);
88840341 119 }
88840341
RC
120}
121
122/* ================================================== */
123
7b2430fc
ML
124void LOG_Message(LOG_Severity severity,
125#if DEBUG > 0
f282856c 126 int line_number, const char *filename, const char *function_name,
7b2430fc
ML
127#endif
128 const char *format, ...)
88840341
RC
129{
130 char buf[2048];
131 va_list other_args;
cd7bfa25 132 time_t t;
63fe34e8 133 struct tm *tm;
88840341 134
1227873b 135 if (!system_log && file_log && severity >= log_min_severity) {
788e7fcd 136 /* Don't clutter up syslog with timestamps and internal debugging info */
88840341 137 time(&t);
63fe34e8
ML
138 tm = gmtime(&t);
139 if (tm) {
140 strftime(buf, sizeof (buf), "%Y-%m-%dT%H:%M:%SZ", tm);
141 fprintf(file_log, "%s ", buf);
142 }
7b2430fc 143#if DEBUG > 0
1227873b 144 if (log_min_severity <= LOGS_DEBUG)
6cbeb107 145 fprintf(file_log, "%s:%d:(%s) ", filename, line_number, function_name);
7b2430fc 146#endif
88840341 147 }
cd7bfa25
ML
148
149 va_start(other_args, format);
150 vsnprintf(buf, sizeof(buf), format, other_args);
151 va_end(other_args);
152
153 switch (severity) {
4bbc5520 154 case LOGS_DEBUG:
cd7bfa25
ML
155 case LOGS_INFO:
156 case LOGS_WARN:
157 case LOGS_ERR:
1227873b
ML
158 if (severity >= log_min_severity)
159 log_message(0, severity, buf);
cd7bfa25
ML
160 break;
161 case LOGS_FATAL:
1227873b
ML
162 if (severity >= log_min_severity)
163 log_message(1, severity, buf);
cd7bfa25 164
7b98443a
ML
165 /* Send the message also to the foreground process if it is
166 still running, or stderr if it is still open */
167 if (parent_fd > 0) {
168 if (write(parent_fd, buf, strlen(buf) + 1) < 0)
169 ; /* Not much we can do here */
170 } else if (system_log && parent_fd == 0) {
171 system_log = 0;
172 log_message(1, severity, buf);
cd7bfa25 173 }
f4c6a00b 174 exit(1);
cd7bfa25
ML
175 break;
176 default:
177 assert(0);
178 }
88840341
RC
179}
180
6cbeb107
ML
181/* ================================================== */
182
183void
184LOG_OpenFileLog(const char *log_file)
185{
186 FILE *f;
187
eb8c9ad6 188 if (log_file) {
794cbfbb 189 f = UTI_OpenFile(NULL, log_file, NULL, 'A', 0640);
eb8c9ad6
ML
190 } else {
191 f = stderr;
192 }
6cbeb107 193
d70df3da
ML
194 /* Enable line buffering */
195 setvbuf(f, NULL, _IOLBF, BUFSIZ);
196
68475366
ML
197 if (file_log && file_log != stderr)
198 fclose(file_log);
199
6cbeb107
ML
200 file_log = f;
201}
202
203
88840341
RC
204/* ================================================== */
205
206void
fe4b661f 207LOG_OpenSystemLog(void)
88840341 208{
fe4b661f
ML
209 system_log = 1;
210 openlog("chronyd", LOG_PID, LOG_DAEMON);
88840341
RC
211}
212
032ac800
ML
213/* ================================================== */
214
1227873b 215void LOG_SetMinSeverity(LOG_Severity severity)
4bbc5520 216{
c7223f4c
ML
217 /* Don't print any debug messages in a non-debug build */
218 log_min_severity = CLAMP(DEBUG > 0 ? LOGS_DEBUG : LOGS_INFO, severity, LOGS_FATAL);
4bbc5520
ML
219}
220
221/* ================================================== */
222
1d2a0856
ML
223void
224LOG_SetParentFd(int fd)
225{
226 parent_fd = fd;
7b98443a
ML
227 if (file_log == stderr)
228 file_log = NULL;
1d2a0856
ML
229}
230
231/* ================================================== */
232
233void
234LOG_CloseParentFd()
235{
236 if (parent_fd > 0)
237 close(parent_fd);
ed0ac6e3 238 parent_fd = -1;
1d2a0856
ML
239}
240
241/* ================================================== */
242
e78e65ef
ML
243LOG_FileID
244LOG_FileOpen(const char *name, const char *banner)
245{
246 assert(n_filelogs < MAX_FILELOGS);
247
248 logfiles[n_filelogs].name = name;
249 logfiles[n_filelogs].banner = banner;
250 logfiles[n_filelogs].file = NULL;
251 logfiles[n_filelogs].writes = 0;
252
253 return n_filelogs++;
254}
255
256/* ================================================== */
257
258void
259LOG_FileWrite(LOG_FileID id, const char *format, ...)
260{
261 va_list other_args;
7ab2c0e4 262 int banner;
e78e65ef
ML
263
264 if (id < 0 || id >= n_filelogs || !logfiles[id].name)
265 return;
266
267 if (!logfiles[id].file) {
e18903a6 268 char *logdir = CNF_GetLogDir();
fb5d4f1d
ML
269
270 if (logdir[0] == '\0') {
f282856c 271 LOG(LOGS_WARN, "logdir not specified");
fb5d4f1d
ML
272 logfiles[id].name = NULL;
273 return;
274 }
e78e65ef 275
e18903a6
ML
276 logfiles[id].file = UTI_OpenFile(logdir, logfiles[id].name, ".log", 'a', 0644);
277 if (!logfiles[id].file) {
278 /* Disable the log */
e78e65ef
ML
279 logfiles[id].name = NULL;
280 return;
281 }
282 }
283
7ab2c0e4
ML
284 banner = CNF_GetLogBanner();
285 if (banner && logfiles[id].writes++ % banner == 0) {
e78e65ef
ML
286 char bannerline[256];
287 int i, bannerlen;
288
96771d68 289 bannerlen = MIN(strlen(logfiles[id].banner), sizeof (bannerline) - 1);
e78e65ef
ML
290
291 for (i = 0; i < bannerlen; i++)
292 bannerline[i] = '=';
293 bannerline[i] = '\0';
294
295 fprintf(logfiles[id].file, "%s\n", bannerline);
296 fprintf(logfiles[id].file, "%s\n", logfiles[id].banner);
297 fprintf(logfiles[id].file, "%s\n", bannerline);
298 }
299
300 va_start(other_args, format);
301 vfprintf(logfiles[id].file, format, other_args);
302 va_end(other_args);
303 fprintf(logfiles[id].file, "\n");
304
305 fflush(logfiles[id].file);
306}
307
308/* ================================================== */
309
e78e65ef
ML
310void
311LOG_CycleLogFiles(void)
312{
313 LOG_FileID i;
314
315 for (i = 0; i < n_filelogs; i++) {
316 if (logfiles[i].file)
317 fclose(logfiles[i].file);
318 logfiles[i].file = NULL;
319 logfiles[i].writes = 0;
320 }
321}
322
323/* ================================================== */