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