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