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