]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/log.c
log: add support for prefixing console log messages with current timestamp
[thirdparty/systemd.git] / src / basic / log.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <inttypes.h>
6 #include <limits.h>
7 #include <stdarg.h>
8 #include <stddef.h>
9 #include <sys/signalfd.h>
10 #include <sys/time.h>
11 #include <sys/uio.h>
12 #include <sys/un.h>
13 #include <unistd.h>
14
15 #include "sd-messages.h"
16
17 #include "alloc-util.h"
18 #include "errno-util.h"
19 #include "fd-util.h"
20 #include "format-util.h"
21 #include "io-util.h"
22 #include "log.h"
23 #include "macro.h"
24 #include "parse-util.h"
25 #include "proc-cmdline.h"
26 #include "process-util.h"
27 #include "ratelimit.h"
28 #include "signal-util.h"
29 #include "socket-util.h"
30 #include "stdio-util.h"
31 #include "string-table.h"
32 #include "string-util.h"
33 #include "syslog-util.h"
34 #include "terminal-util.h"
35 #include "time-util.h"
36 #include "utf8.h"
37
38 #define SNDBUF_SIZE (8*1024*1024)
39
40 static LogTarget log_target = LOG_TARGET_CONSOLE;
41 static int log_max_level[] = {LOG_INFO, LOG_INFO};
42 assert_cc(ELEMENTSOF(log_max_level) == _LOG_REALM_MAX);
43 static int log_facility = LOG_DAEMON;
44
45 static int console_fd = STDERR_FILENO;
46 static int syslog_fd = -1;
47 static int kmsg_fd = -1;
48 static int journal_fd = -1;
49
50 static bool syslog_is_stream = false;
51
52 static bool show_color = false;
53 static bool show_location = false;
54 static bool show_time = false;
55
56 static bool upgrade_syslog_to_journal = false;
57 static bool always_reopen_console = false;
58 static bool open_when_needed = false;
59 static bool prohibit_ipc = false;
60
61 /* Akin to glibc's __abort_msg; which is private and we hence cannot
62 * use here. */
63 static char *log_abort_msg = NULL;
64
65 /* An assert to use in logging functions that does not call recursively
66 * into our logging functions (since that might lead to a loop). */
67 #define assert_raw(expr) \
68 do { \
69 if (_unlikely_(!(expr))) { \
70 fputs(#expr "\n", stderr); \
71 abort(); \
72 } \
73 } while (false)
74
75 static void log_close_console(void) {
76 console_fd = safe_close_above_stdio(console_fd);
77 }
78
79 static int log_open_console(void) {
80
81 if (!always_reopen_console) {
82 console_fd = STDERR_FILENO;
83 return 0;
84 }
85
86 if (console_fd < 3) {
87 int fd;
88
89 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
90 if (fd < 0)
91 return fd;
92
93 console_fd = fd_move_above_stdio(fd);
94 }
95
96 return 0;
97 }
98
99 static void log_close_kmsg(void) {
100 kmsg_fd = safe_close(kmsg_fd);
101 }
102
103 static int log_open_kmsg(void) {
104
105 if (kmsg_fd >= 0)
106 return 0;
107
108 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
109 if (kmsg_fd < 0)
110 return -errno;
111
112 kmsg_fd = fd_move_above_stdio(kmsg_fd);
113 return 0;
114 }
115
116 static void log_close_syslog(void) {
117 syslog_fd = safe_close(syslog_fd);
118 }
119
120 static int create_log_socket(int type) {
121 struct timeval tv;
122 int fd;
123
124 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
125 if (fd < 0)
126 return -errno;
127
128 fd = fd_move_above_stdio(fd);
129 (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
130
131 /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever
132 * in the unlikely case of a deadlock. */
133 if (getpid_cached() == 1)
134 timeval_store(&tv, 10 * USEC_PER_MSEC);
135 else
136 timeval_store(&tv, 10 * USEC_PER_SEC);
137 (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
138
139 return fd;
140 }
141
142 static int log_open_syslog(void) {
143
144 static const union sockaddr_union sa = {
145 .un.sun_family = AF_UNIX,
146 .un.sun_path = "/dev/log",
147 };
148
149 int r;
150
151 if (syslog_fd >= 0)
152 return 0;
153
154 syslog_fd = create_log_socket(SOCK_DGRAM);
155 if (syslog_fd < 0) {
156 r = syslog_fd;
157 goto fail;
158 }
159
160 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
161 safe_close(syslog_fd);
162
163 /* Some legacy syslog systems still use stream
164 * sockets. They really shouldn't. But what can we
165 * do... */
166 syslog_fd = create_log_socket(SOCK_STREAM);
167 if (syslog_fd < 0) {
168 r = syslog_fd;
169 goto fail;
170 }
171
172 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
173 r = -errno;
174 goto fail;
175 }
176
177 syslog_is_stream = true;
178 } else
179 syslog_is_stream = false;
180
181 return 0;
182
183 fail:
184 log_close_syslog();
185 return r;
186 }
187
188 static void log_close_journal(void) {
189 journal_fd = safe_close(journal_fd);
190 }
191
192 static int log_open_journal(void) {
193
194 static const union sockaddr_union sa = {
195 .un.sun_family = AF_UNIX,
196 .un.sun_path = "/run/systemd/journal/socket",
197 };
198
199 int r;
200
201 if (journal_fd >= 0)
202 return 0;
203
204 journal_fd = create_log_socket(SOCK_DGRAM);
205 if (journal_fd < 0) {
206 r = journal_fd;
207 goto fail;
208 }
209
210 if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
211 r = -errno;
212 goto fail;
213 }
214
215 return 0;
216
217 fail:
218 log_close_journal();
219 return r;
220 }
221
222 int log_open(void) {
223 int r;
224
225 /* Do not call from library code. */
226
227 /* If we don't use the console we close it here, to not get
228 * killed by SAK. If we don't use syslog we close it here so
229 * that we are not confused by somebody deleting the socket in
230 * the fs, and to make sure we don't use it if prohibit_ipc is
231 * set. If we don't use /dev/kmsg we still keep it open,
232 * because there is no reason to close it. */
233
234 if (log_target == LOG_TARGET_NULL) {
235 log_close_journal();
236 log_close_syslog();
237 log_close_console();
238 return 0;
239 }
240
241 if (log_target != LOG_TARGET_AUTO ||
242 getpid_cached() == 1 ||
243 isatty(STDERR_FILENO) <= 0) {
244
245 if (!prohibit_ipc &&
246 IN_SET(log_target, LOG_TARGET_AUTO,
247 LOG_TARGET_JOURNAL_OR_KMSG,
248 LOG_TARGET_JOURNAL)) {
249 r = log_open_journal();
250 if (r >= 0) {
251 log_close_syslog();
252 log_close_console();
253 return r;
254 }
255 }
256
257 if (!prohibit_ipc &&
258 IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
259 LOG_TARGET_SYSLOG)) {
260 r = log_open_syslog();
261 if (r >= 0) {
262 log_close_journal();
263 log_close_console();
264 return r;
265 }
266 }
267
268 if (IN_SET(log_target, LOG_TARGET_AUTO,
269 LOG_TARGET_JOURNAL_OR_KMSG,
270 LOG_TARGET_SYSLOG_OR_KMSG,
271 LOG_TARGET_KMSG)) {
272 r = log_open_kmsg();
273 if (r >= 0) {
274 log_close_journal();
275 log_close_syslog();
276 log_close_console();
277 return r;
278 }
279 }
280 }
281
282 log_close_journal();
283 log_close_syslog();
284
285 return log_open_console();
286 }
287
288 void log_set_target(LogTarget target) {
289 assert(target >= 0);
290 assert(target < _LOG_TARGET_MAX);
291
292 if (upgrade_syslog_to_journal) {
293 if (target == LOG_TARGET_SYSLOG)
294 target = LOG_TARGET_JOURNAL;
295 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
296 target = LOG_TARGET_JOURNAL_OR_KMSG;
297 }
298
299 log_target = target;
300 }
301
302 void log_close(void) {
303 /* Do not call from library code. */
304
305 log_close_journal();
306 log_close_syslog();
307 log_close_kmsg();
308 log_close_console();
309 }
310
311 void log_forget_fds(void) {
312 /* Do not call from library code. */
313
314 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
315 }
316
317 void log_set_max_level_realm(LogRealm realm, int level) {
318 assert((level & LOG_PRIMASK) == level);
319 assert(realm < ELEMENTSOF(log_max_level));
320
321 log_max_level[realm] = level;
322 }
323
324 void log_set_facility(int facility) {
325 log_facility = facility;
326 }
327
328 static int write_to_console(
329 int level,
330 int error,
331 const char *file,
332 int line,
333 const char *func,
334 const char *buffer) {
335
336 char location[256],
337 header_time[FORMAT_TIMESTAMP_MAX],
338 prefix[1 + DECIMAL_STR_MAX(int) + 2];
339 struct iovec iovec[8] = {};
340 const char *on = NULL, *off = NULL;
341 size_t n = 0;
342
343 if (console_fd < 0)
344 return 0;
345
346 if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
347 xsprintf(prefix, "<%i>", level);
348 iovec[n++] = IOVEC_MAKE_STRING(prefix);
349 }
350
351 if (show_time) {
352 if (format_timestamp(header_time, sizeof(header_time), now(CLOCK_REALTIME))) {
353 iovec[n++] = IOVEC_MAKE_STRING(header_time);
354 iovec[n++] = IOVEC_MAKE_STRING(" ");
355 }
356 }
357
358 if (show_color)
359 get_log_colors(LOG_PRI(level), &on, &off, NULL);
360
361 if (show_location) {
362 const char *lon = "", *loff = "";
363 if (show_color) {
364 lon = ANSI_HIGHLIGHT_YELLOW4;
365 loff = ANSI_NORMAL;
366 }
367
368 (void) snprintf(location, sizeof location, "%s%s:%i%s: ", lon, file, line, loff);
369 iovec[n++] = IOVEC_MAKE_STRING(location);
370 }
371
372 if (on)
373 iovec[n++] = IOVEC_MAKE_STRING(on);
374 iovec[n++] = IOVEC_MAKE_STRING(buffer);
375 if (off)
376 iovec[n++] = IOVEC_MAKE_STRING(off);
377 iovec[n++] = IOVEC_MAKE_STRING("\n");
378
379 if (writev(console_fd, iovec, n) < 0) {
380
381 if (errno == EIO && getpid_cached() == 1) {
382
383 /* If somebody tried to kick us from our console tty (via vhangup() or suchlike), try
384 * to reconnect. */
385
386 log_close_console();
387 (void) log_open_console();
388 if (console_fd < 0)
389 return 0;
390
391 if (writev(console_fd, iovec, n) < 0)
392 return -errno;
393 } else
394 return -errno;
395 }
396
397 return 1;
398 }
399
400 static int write_to_syslog(
401 int level,
402 int error,
403 const char *file,
404 int line,
405 const char *func,
406 const char *buffer) {
407
408 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
409 header_time[64],
410 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
411 struct iovec iovec[5] = {};
412 struct msghdr msghdr = {
413 .msg_iov = iovec,
414 .msg_iovlen = ELEMENTSOF(iovec),
415 };
416 time_t t;
417 struct tm tm;
418
419 if (syslog_fd < 0)
420 return 0;
421
422 xsprintf(header_priority, "<%i>", level);
423
424 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
425 if (!localtime_r(&t, &tm))
426 return -EINVAL;
427
428 if (strftime(header_time, sizeof(header_time), "%h %e %T ", &tm) <= 0)
429 return -EINVAL;
430
431 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
432
433 iovec[0] = IOVEC_MAKE_STRING(header_priority);
434 iovec[1] = IOVEC_MAKE_STRING(header_time);
435 iovec[2] = IOVEC_MAKE_STRING(program_invocation_short_name);
436 iovec[3] = IOVEC_MAKE_STRING(header_pid);
437 iovec[4] = IOVEC_MAKE_STRING(buffer);
438
439 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
440 if (syslog_is_stream)
441 iovec[4].iov_len++;
442
443 for (;;) {
444 ssize_t n;
445
446 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
447 if (n < 0)
448 return -errno;
449
450 if (!syslog_is_stream ||
451 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
452 break;
453
454 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
455 }
456
457 return 1;
458 }
459
460 static int write_to_kmsg(
461 int level,
462 int error,
463 const char *file,
464 int line,
465 const char *func,
466 const char *buffer) {
467
468 /* Set a ratelimit on the amount of messages logged to /dev/kmsg. This is mostly supposed to be a
469 * safety catch for the case where start indiscriminately logging in a loop. It will not catch cases
470 * where we log excessively, but not in a tight loop.
471 *
472 * Note that this ratelimit is per-emitter, so we might still overwhelm /dev/kmsg with multiple
473 * loggers.
474 */
475 static thread_local RateLimit ratelimit = { 5 * USEC_PER_SEC, 200 };
476
477 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
478 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
479 struct iovec iovec[5] = {};
480
481 if (kmsg_fd < 0)
482 return 0;
483
484 if (!ratelimit_below(&ratelimit))
485 return 0;
486
487 xsprintf(header_priority, "<%i>", level);
488 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
489
490 iovec[0] = IOVEC_MAKE_STRING(header_priority);
491 iovec[1] = IOVEC_MAKE_STRING(program_invocation_short_name);
492 iovec[2] = IOVEC_MAKE_STRING(header_pid);
493 iovec[3] = IOVEC_MAKE_STRING(buffer);
494 iovec[4] = IOVEC_MAKE_STRING("\n");
495
496 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
497 return -errno;
498
499 return 1;
500 }
501
502 static int log_do_header(
503 char *header,
504 size_t size,
505 int level,
506 int error,
507 const char *file, int line, const char *func,
508 const char *object_field, const char *object,
509 const char *extra_field, const char *extra) {
510 int r;
511
512 error = IS_SYNTHETIC_ERRNO(error) ? 0 : ERRNO_VALUE(error);
513
514 r = snprintf(header, size,
515 "PRIORITY=%i\n"
516 "SYSLOG_FACILITY=%i\n"
517 "%s%.256s%s" /* CODE_FILE */
518 "%s%.*i%s" /* CODE_LINE */
519 "%s%.256s%s" /* CODE_FUNC */
520 "%s%.*i%s" /* ERRNO */
521 "%s%.256s%s" /* object */
522 "%s%.256s%s" /* extra */
523 "SYSLOG_IDENTIFIER=%.256s\n",
524 LOG_PRI(level),
525 LOG_FAC(level),
526 isempty(file) ? "" : "CODE_FILE=",
527 isempty(file) ? "" : file,
528 isempty(file) ? "" : "\n",
529 line ? "CODE_LINE=" : "",
530 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
531 line ? "\n" : "",
532 isempty(func) ? "" : "CODE_FUNC=",
533 isempty(func) ? "" : func,
534 isempty(func) ? "" : "\n",
535 error ? "ERRNO=" : "",
536 error ? 1 : 0, error,
537 error ? "\n" : "",
538 isempty(object) ? "" : object_field,
539 isempty(object) ? "" : object,
540 isempty(object) ? "" : "\n",
541 isempty(extra) ? "" : extra_field,
542 isempty(extra) ? "" : extra,
543 isempty(extra) ? "" : "\n",
544 program_invocation_short_name);
545 assert_raw((size_t) r < size);
546
547 return 0;
548 }
549
550 static int write_to_journal(
551 int level,
552 int error,
553 const char *file,
554 int line,
555 const char *func,
556 const char *object_field,
557 const char *object,
558 const char *extra_field,
559 const char *extra,
560 const char *buffer) {
561
562 char header[LINE_MAX];
563 struct iovec iovec[4] = {};
564 struct msghdr mh = {};
565
566 if (journal_fd < 0)
567 return 0;
568
569 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
570
571 iovec[0] = IOVEC_MAKE_STRING(header);
572 iovec[1] = IOVEC_MAKE_STRING("MESSAGE=");
573 iovec[2] = IOVEC_MAKE_STRING(buffer);
574 iovec[3] = IOVEC_MAKE_STRING("\n");
575
576 mh.msg_iov = iovec;
577 mh.msg_iovlen = ELEMENTSOF(iovec);
578
579 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
580 return -errno;
581
582 return 1;
583 }
584
585 int log_dispatch_internal(
586 int level,
587 int error,
588 const char *file,
589 int line,
590 const char *func,
591 const char *object_field,
592 const char *object,
593 const char *extra_field,
594 const char *extra,
595 char *buffer) {
596
597 assert_raw(buffer);
598
599 if (log_target == LOG_TARGET_NULL)
600 return -ERRNO_VALUE(error);
601
602 /* Patch in LOG_DAEMON facility if necessary */
603 if ((level & LOG_FACMASK) == 0)
604 level |= log_facility;
605
606 if (open_when_needed)
607 (void) log_open();
608
609 do {
610 char *e;
611 int k = 0;
612
613 buffer += strspn(buffer, NEWLINE);
614
615 if (buffer[0] == 0)
616 break;
617
618 if ((e = strpbrk(buffer, NEWLINE)))
619 *(e++) = 0;
620
621 if (IN_SET(log_target, LOG_TARGET_AUTO,
622 LOG_TARGET_JOURNAL_OR_KMSG,
623 LOG_TARGET_JOURNAL)) {
624
625 k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
626 if (k < 0 && k != -EAGAIN)
627 log_close_journal();
628 }
629
630 if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
631 LOG_TARGET_SYSLOG)) {
632
633 k = write_to_syslog(level, error, file, line, func, buffer);
634 if (k < 0 && k != -EAGAIN)
635 log_close_syslog();
636 }
637
638 if (k <= 0 &&
639 IN_SET(log_target, LOG_TARGET_AUTO,
640 LOG_TARGET_SYSLOG_OR_KMSG,
641 LOG_TARGET_JOURNAL_OR_KMSG,
642 LOG_TARGET_KMSG)) {
643
644 if (k < 0)
645 log_open_kmsg();
646
647 k = write_to_kmsg(level, error, file, line, func, buffer);
648 if (k < 0) {
649 log_close_kmsg();
650 (void) log_open_console();
651 }
652 }
653
654 if (k <= 0)
655 (void) write_to_console(level, error, file, line, func, buffer);
656
657 buffer = e;
658 } while (buffer);
659
660 if (open_when_needed)
661 log_close();
662
663 return -ERRNO_VALUE(error);
664 }
665
666 int log_dump_internal(
667 int level,
668 int error,
669 const char *file,
670 int line,
671 const char *func,
672 char *buffer) {
673
674 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
675 PROTECT_ERRNO;
676
677 /* This modifies the buffer... */
678
679 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
680 return -ERRNO_VALUE(error);
681
682 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
683 }
684
685 int log_internalv_realm(
686 int level,
687 int error,
688 const char *file,
689 int line,
690 const char *func,
691 const char *format,
692 va_list ap) {
693
694 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
695 char buffer[LINE_MAX];
696 PROTECT_ERRNO;
697
698 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
699 return -ERRNO_VALUE(error);
700
701 /* Make sure that %m maps to the specified error (or "Success"). */
702 errno = ERRNO_VALUE(error);
703
704 (void) vsnprintf(buffer, sizeof buffer, format, ap);
705
706 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
707 }
708
709 int log_internal_realm(
710 int level,
711 int error,
712 const char *file,
713 int line,
714 const char *func,
715 const char *format, ...) {
716
717 va_list ap;
718 int r;
719
720 va_start(ap, format);
721 r = log_internalv_realm(level, error, file, line, func, format, ap);
722 va_end(ap);
723
724 return r;
725 }
726
727 int log_object_internalv(
728 int level,
729 int error,
730 const char *file,
731 int line,
732 const char *func,
733 const char *object_field,
734 const char *object,
735 const char *extra_field,
736 const char *extra,
737 const char *format,
738 va_list ap) {
739
740 PROTECT_ERRNO;
741 char *buffer, *b;
742
743 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
744 return -ERRNO_VALUE(error);
745
746 /* Make sure that %m maps to the specified error (or "Success"). */
747 errno = ERRNO_VALUE(error);
748
749 /* Prepend the object name before the message */
750 if (object) {
751 size_t n;
752
753 n = strlen(object);
754 buffer = newa(char, n + 2 + LINE_MAX);
755 b = stpcpy(stpcpy(buffer, object), ": ");
756 } else
757 b = buffer = newa(char, LINE_MAX);
758
759 (void) vsnprintf(b, LINE_MAX, format, ap);
760
761 return log_dispatch_internal(level, error, file, line, func,
762 object_field, object, extra_field, extra, buffer);
763 }
764
765 int log_object_internal(
766 int level,
767 int error,
768 const char *file,
769 int line,
770 const char *func,
771 const char *object_field,
772 const char *object,
773 const char *extra_field,
774 const char *extra,
775 const char *format, ...) {
776
777 va_list ap;
778 int r;
779
780 va_start(ap, format);
781 r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
782 va_end(ap);
783
784 return r;
785 }
786
787 static void log_assert(
788 int level,
789 const char *text,
790 const char *file,
791 int line,
792 const char *func,
793 const char *format) {
794
795 static char buffer[LINE_MAX];
796 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
797
798 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
799 return;
800
801 DISABLE_WARNING_FORMAT_NONLITERAL;
802 (void) snprintf(buffer, sizeof buffer, format, text, file, line, func);
803 REENABLE_WARNING;
804
805 log_abort_msg = buffer;
806
807 log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
808 }
809
810 _noreturn_ void log_assert_failed_realm(
811 LogRealm realm,
812 const char *text,
813 const char *file,
814 int line,
815 const char *func) {
816 (void) log_open();
817 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
818 "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
819 abort();
820 }
821
822 _noreturn_ void log_assert_failed_unreachable_realm(
823 LogRealm realm,
824 const char *text,
825 const char *file,
826 int line,
827 const char *func) {
828 (void) log_open();
829 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
830 "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
831 abort();
832 }
833
834 void log_assert_failed_return_realm(
835 LogRealm realm,
836 const char *text,
837 const char *file,
838 int line,
839 const char *func) {
840 PROTECT_ERRNO;
841 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func,
842 "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
843 }
844
845 int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
846 return log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
847 ENOMEM, file, line, func, "Out of memory.");
848 }
849
850 int log_format_iovec(
851 struct iovec *iovec,
852 size_t iovec_len,
853 size_t *n,
854 bool newline_separator,
855 int error,
856 const char *format,
857 va_list ap) {
858
859 static const char nl = '\n';
860
861 while (format && *n + 1 < iovec_len) {
862 va_list aq;
863 char *m;
864 int r;
865
866 /* We need to copy the va_list structure,
867 * since vasprintf() leaves it afterwards at
868 * an undefined location */
869
870 errno = ERRNO_VALUE(error);
871
872 va_copy(aq, ap);
873 r = vasprintf(&m, format, aq);
874 va_end(aq);
875 if (r < 0)
876 return -EINVAL;
877
878 /* Now, jump enough ahead, so that we point to
879 * the next format string */
880 VA_FORMAT_ADVANCE(format, ap);
881
882 iovec[(*n)++] = IOVEC_MAKE_STRING(m);
883
884 if (newline_separator) {
885 iovec[*n] = IOVEC_MAKE((char *)&nl, 1);
886 (*n)++;
887 }
888
889 format = va_arg(ap, char *);
890 }
891 return 0;
892 }
893
894 int log_struct_internal(
895 int level,
896 int error,
897 const char *file,
898 int line,
899 const char *func,
900 const char *format, ...) {
901
902 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
903 char buf[LINE_MAX];
904 bool found = false;
905 PROTECT_ERRNO;
906 va_list ap;
907
908 if (_likely_(LOG_PRI(level) > log_max_level[realm]) ||
909 log_target == LOG_TARGET_NULL)
910 return -ERRNO_VALUE(error);
911
912 if ((level & LOG_FACMASK) == 0)
913 level |= log_facility;
914
915 if (IN_SET(log_target,
916 LOG_TARGET_AUTO,
917 LOG_TARGET_JOURNAL_OR_KMSG,
918 LOG_TARGET_JOURNAL)) {
919
920 if (open_when_needed)
921 log_open_journal();
922
923 if (journal_fd >= 0) {
924 char header[LINE_MAX];
925 struct iovec iovec[17] = {};
926 size_t n = 0, i;
927 int r;
928 struct msghdr mh = {
929 .msg_iov = iovec,
930 };
931 bool fallback = false;
932
933 /* If the journal is available do structured logging.
934 * Do not report the errno if it is synthetic. */
935 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
936 iovec[n++] = IOVEC_MAKE_STRING(header);
937
938 va_start(ap, format);
939 r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
940 if (r < 0)
941 fallback = true;
942 else {
943 mh.msg_iovlen = n;
944 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
945 }
946
947 va_end(ap);
948 for (i = 1; i < n; i += 2)
949 free(iovec[i].iov_base);
950
951 if (!fallback) {
952 if (open_when_needed)
953 log_close();
954
955 return -ERRNO_VALUE(error);
956 }
957 }
958 }
959
960 /* Fallback if journal logging is not available or didn't work. */
961
962 va_start(ap, format);
963 while (format) {
964 va_list aq;
965
966 errno = ERRNO_VALUE(error);
967
968 va_copy(aq, ap);
969 (void) vsnprintf(buf, sizeof buf, format, aq);
970 va_end(aq);
971
972 if (startswith(buf, "MESSAGE=")) {
973 found = true;
974 break;
975 }
976
977 VA_FORMAT_ADVANCE(format, ap);
978
979 format = va_arg(ap, char *);
980 }
981 va_end(ap);
982
983 if (!found) {
984 if (open_when_needed)
985 log_close();
986
987 return -ERRNO_VALUE(error);
988 }
989
990 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
991 }
992
993 int log_struct_iovec_internal(
994 int level,
995 int error,
996 const char *file,
997 int line,
998 const char *func,
999 const struct iovec input_iovec[],
1000 size_t n_input_iovec) {
1001
1002 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
1003 PROTECT_ERRNO;
1004 size_t i;
1005 char *m;
1006
1007 if (_likely_(LOG_PRI(level) > log_max_level[realm]) ||
1008 log_target == LOG_TARGET_NULL)
1009 return -ERRNO_VALUE(error);
1010
1011 if ((level & LOG_FACMASK) == 0)
1012 level |= log_facility;
1013
1014 if (IN_SET(log_target, LOG_TARGET_AUTO,
1015 LOG_TARGET_JOURNAL_OR_KMSG,
1016 LOG_TARGET_JOURNAL) &&
1017 journal_fd >= 0) {
1018
1019 struct iovec iovec[1 + n_input_iovec*2];
1020 char header[LINE_MAX];
1021 struct msghdr mh = {
1022 .msg_iov = iovec,
1023 .msg_iovlen = 1 + n_input_iovec*2,
1024 };
1025
1026 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
1027 iovec[0] = IOVEC_MAKE_STRING(header);
1028
1029 for (i = 0; i < n_input_iovec; i++) {
1030 iovec[1+i*2] = input_iovec[i];
1031 iovec[1+i*2+1] = IOVEC_MAKE_STRING("\n");
1032 }
1033
1034 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) >= 0)
1035 return -ERRNO_VALUE(error);
1036 }
1037
1038 for (i = 0; i < n_input_iovec; i++)
1039 if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE="))
1040 break;
1041
1042 if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */
1043 return -ERRNO_VALUE(error);
1044
1045 m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
1046 input_iovec[i].iov_len - STRLEN("MESSAGE="));
1047
1048 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
1049 }
1050
1051 int log_set_target_from_string(const char *e) {
1052 LogTarget t;
1053
1054 t = log_target_from_string(e);
1055 if (t < 0)
1056 return -EINVAL;
1057
1058 log_set_target(t);
1059 return 0;
1060 }
1061
1062 int log_set_max_level_from_string_realm(LogRealm realm, const char *e) {
1063 int t;
1064
1065 t = log_level_from_string(e);
1066 if (t < 0)
1067 return -EINVAL;
1068
1069 log_set_max_level_realm(realm, t);
1070 return 0;
1071 }
1072
1073 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
1074
1075 /*
1076 * The systemd.log_xyz= settings are parsed by all tools, and
1077 * so is "debug".
1078 *
1079 * However, "quiet" is only parsed by PID 1, and only turns of
1080 * status output to /dev/console, but does not alter the log
1081 * level.
1082 */
1083
1084 if (streq(key, "debug") && !value)
1085 log_set_max_level(LOG_DEBUG);
1086
1087 else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1088
1089 if (proc_cmdline_value_missing(key, value))
1090 return 0;
1091
1092 if (log_set_target_from_string(value) < 0)
1093 log_warning("Failed to parse log target '%s'. Ignoring.", value);
1094
1095 } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1096
1097 if (proc_cmdline_value_missing(key, value))
1098 return 0;
1099
1100 if (log_set_max_level_from_string(value) < 0)
1101 log_warning("Failed to parse log level '%s'. Ignoring.", value);
1102
1103 } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1104
1105 if (log_show_color_from_string(value ?: "1") < 0)
1106 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1107
1108 } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1109
1110 if (log_show_location_from_string(value ?: "1") < 0)
1111 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1112
1113 } else if (proc_cmdline_key_streq(key, "systemd.log_time")) {
1114
1115 if (log_show_time_from_string(value ?: "1") < 0)
1116 log_warning("Failed to parse log time setting '%s'. Ignoring.", value);
1117
1118 }
1119
1120 return 0;
1121 }
1122
1123 void log_parse_environment_realm(LogRealm realm) {
1124 /* Do not call from library code. */
1125
1126 const char *e;
1127
1128 if (getpid_cached() == 1 || get_ctty_devnr(0, NULL) < 0)
1129 /* Only try to read the command line in daemons. We assume that anything that has a
1130 * controlling tty is user stuff. For PID1 we do a special check in case it hasn't
1131 * closed the console yet. */
1132 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1133
1134 e = getenv("SYSTEMD_LOG_TARGET");
1135 if (e && log_set_target_from_string(e) < 0)
1136 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1137
1138 e = getenv("SYSTEMD_LOG_LEVEL");
1139 if (e && log_set_max_level_from_string_realm(realm, e) < 0)
1140 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1141
1142 e = getenv("SYSTEMD_LOG_COLOR");
1143 if (e && log_show_color_from_string(e) < 0)
1144 log_warning("Failed to parse log color '%s'. Ignoring.", e);
1145
1146 e = getenv("SYSTEMD_LOG_LOCATION");
1147 if (e && log_show_location_from_string(e) < 0)
1148 log_warning("Failed to parse log location '%s'. Ignoring.", e);
1149
1150 e = getenv("SYSTEMD_LOG_TIME");
1151 if (e && log_show_time_from_string(e) < 0)
1152 log_warning("Failed to parse log time '%s'. Ignoring.", e);
1153 }
1154
1155 LogTarget log_get_target(void) {
1156 return log_target;
1157 }
1158
1159 int log_get_max_level_realm(LogRealm realm) {
1160 return log_max_level[realm];
1161 }
1162
1163 void log_show_color(bool b) {
1164 show_color = b;
1165 }
1166
1167 bool log_get_show_color(void) {
1168 return show_color;
1169 }
1170
1171 void log_show_location(bool b) {
1172 show_location = b;
1173 }
1174
1175 bool log_get_show_location(void) {
1176 return show_location;
1177 }
1178
1179 void log_show_time(bool b) {
1180 show_time = b;
1181 }
1182
1183 bool log_get_show_time(void) {
1184 return show_time;
1185 }
1186
1187 int log_show_color_from_string(const char *e) {
1188 int t;
1189
1190 t = parse_boolean(e);
1191 if (t < 0)
1192 return t;
1193
1194 log_show_color(t);
1195 return 0;
1196 }
1197
1198 int log_show_location_from_string(const char *e) {
1199 int t;
1200
1201 t = parse_boolean(e);
1202 if (t < 0)
1203 return t;
1204
1205 log_show_location(t);
1206 return 0;
1207 }
1208
1209 int log_show_time_from_string(const char *e) {
1210 int t;
1211
1212 t = parse_boolean(e);
1213 if (t < 0)
1214 return t;
1215
1216 log_show_time(t);
1217 return 0;
1218 }
1219
1220 bool log_on_console(void) {
1221 if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1222 LOG_TARGET_CONSOLE_PREFIXED))
1223 return true;
1224
1225 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1226 }
1227
1228 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1229 [LOG_TARGET_CONSOLE] = "console",
1230 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1231 [LOG_TARGET_KMSG] = "kmsg",
1232 [LOG_TARGET_JOURNAL] = "journal",
1233 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1234 [LOG_TARGET_SYSLOG] = "syslog",
1235 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1236 [LOG_TARGET_AUTO] = "auto",
1237 [LOG_TARGET_NULL] = "null",
1238 };
1239
1240 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1241
1242 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1243 assert(si);
1244
1245 if (pid_is_valid(si->ssi_pid)) {
1246 _cleanup_free_ char *p = NULL;
1247
1248 (void) get_process_comm(si->ssi_pid, &p);
1249
1250 log_full(level,
1251 "Received SIG%s from PID %"PRIu32" (%s).",
1252 signal_to_string(si->ssi_signo),
1253 si->ssi_pid, strna(p));
1254 } else
1255 log_full(level,
1256 "Received SIG%s.",
1257 signal_to_string(si->ssi_signo));
1258 }
1259
1260 int log_syntax_internal(
1261 const char *unit,
1262 int level,
1263 const char *config_file,
1264 unsigned config_line,
1265 int error,
1266 const char *file,
1267 int line,
1268 const char *func,
1269 const char *format, ...) {
1270
1271 PROTECT_ERRNO;
1272 char buffer[LINE_MAX];
1273 va_list ap;
1274 const char *unit_fmt = NULL;
1275
1276 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]) ||
1277 log_target == LOG_TARGET_NULL)
1278 return -ERRNO_VALUE(error);
1279
1280 errno = ERRNO_VALUE(error);
1281
1282 va_start(ap, format);
1283 (void) vsnprintf(buffer, sizeof buffer, format, ap);
1284 va_end(ap);
1285
1286 if (unit)
1287 unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1288
1289 if (config_file) {
1290 if (config_line > 0)
1291 return log_struct_internal(
1292 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1293 error,
1294 file, line, func,
1295 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1296 "CONFIG_FILE=%s", config_file,
1297 "CONFIG_LINE=%u", config_line,
1298 LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1299 unit_fmt, unit,
1300 NULL);
1301 else
1302 return log_struct_internal(
1303 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1304 error,
1305 file, line, func,
1306 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1307 "CONFIG_FILE=%s", config_file,
1308 LOG_MESSAGE("%s: %s", config_file, buffer),
1309 unit_fmt, unit,
1310 NULL);
1311 } else if (unit)
1312 return log_struct_internal(
1313 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1314 error,
1315 file, line, func,
1316 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1317 LOG_MESSAGE("%s: %s", unit, buffer),
1318 unit_fmt, unit,
1319 NULL);
1320 else
1321 return log_struct_internal(
1322 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1323 error,
1324 file, line, func,
1325 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1326 LOG_MESSAGE("%s", buffer),
1327 NULL);
1328 }
1329
1330 int log_syntax_invalid_utf8_internal(
1331 const char *unit,
1332 int level,
1333 const char *config_file,
1334 unsigned config_line,
1335 const char *file,
1336 int line,
1337 const char *func,
1338 const char *rvalue) {
1339
1340 _cleanup_free_ char *p = NULL;
1341
1342 if (rvalue)
1343 p = utf8_escape_invalid(rvalue);
1344
1345 log_syntax_internal(unit, level, config_file, config_line, 0, file, line, func,
1346 "String is not UTF-8 clean, ignoring assignment: %s", strna(p));
1347
1348 return -EINVAL;
1349 }
1350
1351 void log_set_upgrade_syslog_to_journal(bool b) {
1352 upgrade_syslog_to_journal = b;
1353
1354 /* Make the change effective immediately */
1355 if (b) {
1356 if (log_target == LOG_TARGET_SYSLOG)
1357 log_target = LOG_TARGET_JOURNAL;
1358 else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG)
1359 log_target = LOG_TARGET_JOURNAL_OR_KMSG;
1360 }
1361 }
1362
1363 void log_set_always_reopen_console(bool b) {
1364 always_reopen_console = b;
1365 }
1366
1367 void log_set_open_when_needed(bool b) {
1368 open_when_needed = b;
1369 }
1370
1371 void log_set_prohibit_ipc(bool b) {
1372 prohibit_ipc = b;
1373 }
1374
1375 int log_emergency_level(void) {
1376 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1377 * then the system of the whole system is obviously affected. */
1378
1379 return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;
1380 }
1381
1382 int log_dup_console(void) {
1383 int copy;
1384
1385 /* Duplicate the fd we use for fd logging if it's < 3 and use the copy from now on. This call is useful
1386 * whenever we want to continue logging through the original fd, but want to rearrange stderr. */
1387
1388 if (console_fd >= 3)
1389 return 0;
1390
1391 copy = fcntl(console_fd, F_DUPFD_CLOEXEC, 3);
1392 if (copy < 0)
1393 return -errno;
1394
1395 console_fd = copy;
1396 return 0;
1397 }
1398
1399 void log_setup_service(void) {
1400 /* Sets up logging the way it is most appropriate for running a program as a service. Note that using this
1401 * doesn't make the binary unsuitable for invocation on the command line, as log output will still go to the
1402 * terminal if invoked interactively. */
1403
1404 log_set_target(LOG_TARGET_AUTO);
1405 log_parse_environment();
1406 (void) log_open();
1407 }