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