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