]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/log.c
basic: log: Increase static buffer for source file location (#3674)
[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 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 *object_field,
334 const char *object,
335 const char *buffer) {
336
337 char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2];
338 struct iovec iovec[6] = {};
339 unsigned n = 0;
340 bool highlight;
341
342 if (console_fd < 0)
343 return 0;
344
345 if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
346 sprintf(prefix, "<%i>", level);
347 IOVEC_SET_STRING(iovec[n++], prefix);
348 }
349
350 highlight = LOG_PRI(level) <= LOG_ERR && show_color;
351
352 if (show_location) {
353 snprintf(location, sizeof(location), "(%s:%i) ", file, line);
354 IOVEC_SET_STRING(iovec[n++], location);
355 }
356
357 if (highlight)
358 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED);
359 IOVEC_SET_STRING(iovec[n++], buffer);
360 if (highlight)
361 IOVEC_SET_STRING(iovec[n++], ANSI_NORMAL);
362 IOVEC_SET_STRING(iovec[n++], "\n");
363
364 if (writev(console_fd, iovec, n) < 0) {
365
366 if (errno == EIO && getpid() == 1) {
367
368 /* If somebody tried to kick us from our
369 * console tty (via vhangup() or suchlike),
370 * try to reconnect */
371
372 log_close_console();
373 log_open_console();
374
375 if (console_fd < 0)
376 return 0;
377
378 if (writev(console_fd, iovec, n) < 0)
379 return -errno;
380 } else
381 return -errno;
382 }
383
384 return 1;
385 }
386
387 static int write_to_syslog(
388 int level,
389 int error,
390 const char *file,
391 int line,
392 const char *func,
393 const char *object_field,
394 const char *object,
395 const char *buffer) {
396
397 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
398 header_time[64],
399 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
400 struct iovec iovec[5] = {};
401 struct msghdr msghdr = {
402 .msg_iov = iovec,
403 .msg_iovlen = ELEMENTSOF(iovec),
404 };
405 time_t t;
406 struct tm *tm;
407
408 if (syslog_fd < 0)
409 return 0;
410
411 xsprintf(header_priority, "<%i>", level);
412
413 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
414 tm = localtime(&t);
415 if (!tm)
416 return -EINVAL;
417
418 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
419 return -EINVAL;
420
421 xsprintf(header_pid, "["PID_FMT"]: ", getpid());
422
423 IOVEC_SET_STRING(iovec[0], header_priority);
424 IOVEC_SET_STRING(iovec[1], header_time);
425 IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
426 IOVEC_SET_STRING(iovec[3], header_pid);
427 IOVEC_SET_STRING(iovec[4], buffer);
428
429 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
430 if (syslog_is_stream)
431 iovec[4].iov_len++;
432
433 for (;;) {
434 ssize_t n;
435
436 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
437 if (n < 0)
438 return -errno;
439
440 if (!syslog_is_stream ||
441 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
442 break;
443
444 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
445 }
446
447 return 1;
448 }
449
450 static int write_to_kmsg(
451 int level,
452 int error,
453 const char *file,
454 int line,
455 const char *func,
456 const char *object_field,
457 const char *object,
458 const char *buffer) {
459
460 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
461 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
462 struct iovec iovec[5] = {};
463
464 if (kmsg_fd < 0)
465 return 0;
466
467 xsprintf(header_priority, "<%i>", level);
468 xsprintf(header_pid, "["PID_FMT"]: ", getpid());
469
470 IOVEC_SET_STRING(iovec[0], header_priority);
471 IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
472 IOVEC_SET_STRING(iovec[2], header_pid);
473 IOVEC_SET_STRING(iovec[3], buffer);
474 IOVEC_SET_STRING(iovec[4], "\n");
475
476 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
477 return -errno;
478
479 return 1;
480 }
481
482 static int log_do_header(
483 char *header,
484 size_t size,
485 int level,
486 int error,
487 const char *file, int line, const char *func,
488 const char *object_field, const char *object) {
489
490 snprintf(header, size,
491 "PRIORITY=%i\n"
492 "SYSLOG_FACILITY=%i\n"
493 "%s%s%s"
494 "%s%.*i%s"
495 "%s%s%s"
496 "%s%.*i%s"
497 "%s%s%s"
498 "SYSLOG_IDENTIFIER=%s\n",
499 LOG_PRI(level),
500 LOG_FAC(level),
501 isempty(file) ? "" : "CODE_FILE=",
502 isempty(file) ? "" : file,
503 isempty(file) ? "" : "\n",
504 line ? "CODE_LINE=" : "",
505 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
506 line ? "\n" : "",
507 isempty(func) ? "" : "CODE_FUNCTION=",
508 isempty(func) ? "" : func,
509 isempty(func) ? "" : "\n",
510 error ? "ERRNO=" : "",
511 error ? 1 : 0, error,
512 error ? "\n" : "",
513 isempty(object) ? "" : object_field,
514 isempty(object) ? "" : object,
515 isempty(object) ? "" : "\n",
516 program_invocation_short_name);
517
518 return 0;
519 }
520
521 static int write_to_journal(
522 int level,
523 int error,
524 const char *file,
525 int line,
526 const char *func,
527 const char *object_field,
528 const char *object,
529 const char *buffer) {
530
531 char header[LINE_MAX];
532 struct iovec iovec[4] = {};
533 struct msghdr mh = {};
534
535 if (journal_fd < 0)
536 return 0;
537
538 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object);
539
540 IOVEC_SET_STRING(iovec[0], header);
541 IOVEC_SET_STRING(iovec[1], "MESSAGE=");
542 IOVEC_SET_STRING(iovec[2], buffer);
543 IOVEC_SET_STRING(iovec[3], "\n");
544
545 mh.msg_iov = iovec;
546 mh.msg_iovlen = ELEMENTSOF(iovec);
547
548 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
549 return -errno;
550
551 return 1;
552 }
553
554 static int log_dispatch(
555 int level,
556 int error,
557 const char *file,
558 int line,
559 const char *func,
560 const char *object_field,
561 const char *object,
562 char *buffer) {
563
564 assert(buffer);
565
566 if (log_target == LOG_TARGET_NULL)
567 return -error;
568
569 /* Patch in LOG_DAEMON facility if necessary */
570 if ((level & LOG_FACMASK) == 0)
571 level = log_facility | LOG_PRI(level);
572
573 if (error < 0)
574 error = -error;
575
576 do {
577 char *e;
578 int k = 0;
579
580 buffer += strspn(buffer, NEWLINE);
581
582 if (buffer[0] == 0)
583 break;
584
585 if ((e = strpbrk(buffer, NEWLINE)))
586 *(e++) = 0;
587
588 if (log_target == LOG_TARGET_AUTO ||
589 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
590 log_target == LOG_TARGET_JOURNAL) {
591
592 k = write_to_journal(level, error, file, line, func, object_field, object, buffer);
593 if (k < 0) {
594 if (k != -EAGAIN)
595 log_close_journal();
596 log_open_kmsg();
597 }
598 }
599
600 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
601 log_target == LOG_TARGET_SYSLOG) {
602
603 k = write_to_syslog(level, error, file, line, func, object_field, object, buffer);
604 if (k < 0) {
605 if (k != -EAGAIN)
606 log_close_syslog();
607 log_open_kmsg();
608 }
609 }
610
611 if (k <= 0 &&
612 (log_target == LOG_TARGET_AUTO ||
613 log_target == LOG_TARGET_SAFE ||
614 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
615 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
616 log_target == LOG_TARGET_KMSG)) {
617
618 k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer);
619 if (k < 0) {
620 log_close_kmsg();
621 log_open_console();
622 }
623 }
624
625 if (k <= 0)
626 (void) write_to_console(level, error, file, line, func, object_field, object, buffer);
627
628 buffer = e;
629 } while (buffer);
630
631 return -error;
632 }
633
634 int log_dump_internal(
635 int level,
636 int error,
637 const char *file,
638 int line,
639 const char *func,
640 char *buffer) {
641
642 PROTECT_ERRNO;
643
644 /* This modifies the buffer... */
645
646 if (error < 0)
647 error = -error;
648
649 if (_likely_(LOG_PRI(level) > log_max_level))
650 return -error;
651
652 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
653 }
654
655 int log_internalv(
656 int level,
657 int error,
658 const char *file,
659 int line,
660 const char *func,
661 const char *format,
662 va_list ap) {
663
664 PROTECT_ERRNO;
665 char buffer[LINE_MAX];
666
667 if (error < 0)
668 error = -error;
669
670 if (_likely_(LOG_PRI(level) > log_max_level))
671 return -error;
672
673 /* Make sure that %m maps to the specified error */
674 if (error != 0)
675 errno = error;
676
677 vsnprintf(buffer, sizeof(buffer), format, ap);
678
679 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
680 }
681
682 int log_internal(
683 int level,
684 int error,
685 const char *file,
686 int line,
687 const char *func,
688 const char *format, ...) {
689
690 va_list ap;
691 int r;
692
693 va_start(ap, format);
694 r = log_internalv(level, error, file, line, func, format, ap);
695 va_end(ap);
696
697 return r;
698 }
699
700 int log_object_internalv(
701 int level,
702 int error,
703 const char *file,
704 int line,
705 const char *func,
706 const char *object_field,
707 const char *object,
708 const char *format,
709 va_list ap) {
710
711 PROTECT_ERRNO;
712 char *buffer, *b;
713 size_t l;
714
715 if (error < 0)
716 error = -error;
717
718 if (_likely_(LOG_PRI(level) > log_max_level))
719 return -error;
720
721 /* Make sure that %m maps to the specified error */
722 if (error != 0)
723 errno = error;
724
725 /* Prepend the object name before the message */
726 if (object) {
727 size_t n;
728
729 n = strlen(object);
730 l = n + 2 + LINE_MAX;
731
732 buffer = newa(char, l);
733 b = stpcpy(stpcpy(buffer, object), ": ");
734 } else {
735 l = LINE_MAX;
736 b = buffer = newa(char, l);
737 }
738
739 vsnprintf(b, l, format, ap);
740
741 return log_dispatch(level, error, file, line, func, object_field, object, buffer);
742 }
743
744 int log_object_internal(
745 int level,
746 int error,
747 const char *file,
748 int line,
749 const char *func,
750 const char *object_field,
751 const char *object,
752 const char *format, ...) {
753
754 va_list ap;
755 int r;
756
757 va_start(ap, format);
758 r = log_object_internalv(level, error, file, line, func, object_field, object, format, ap);
759 va_end(ap);
760
761 return r;
762 }
763
764 static void log_assert(
765 int level,
766 const char *text,
767 const char *file,
768 int line,
769 const char *func,
770 const char *format) {
771
772 static char buffer[LINE_MAX];
773
774 if (_likely_(LOG_PRI(level) > log_max_level))
775 return;
776
777 DISABLE_WARNING_FORMAT_NONLITERAL;
778 xsprintf(buffer, format, text, file, line, func);
779 REENABLE_WARNING;
780
781 log_abort_msg = buffer;
782
783 log_dispatch(level, 0, file, line, func, NULL, NULL, buffer);
784 }
785
786 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
787 log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
788 abort();
789 }
790
791 noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
792 log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
793 abort();
794 }
795
796 void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
797 PROTECT_ERRNO;
798 log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
799 }
800
801 int log_oom_internal(const char *file, int line, const char *func) {
802 log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
803 return -ENOMEM;
804 }
805
806 int log_format_iovec(
807 struct iovec *iovec,
808 unsigned iovec_len,
809 unsigned *n,
810 bool newline_separator,
811 int error,
812 const char *format,
813 va_list ap) {
814
815 static const char nl = '\n';
816
817 while (format && *n + 1 < iovec_len) {
818 va_list aq;
819 char *m;
820 int r;
821
822 /* We need to copy the va_list structure,
823 * since vasprintf() leaves it afterwards at
824 * an undefined location */
825
826 if (error != 0)
827 errno = error;
828
829 va_copy(aq, ap);
830 r = vasprintf(&m, format, aq);
831 va_end(aq);
832 if (r < 0)
833 return -EINVAL;
834
835 /* Now, jump enough ahead, so that we point to
836 * the next format string */
837 VA_FORMAT_ADVANCE(format, ap);
838
839 IOVEC_SET_STRING(iovec[(*n)++], m);
840
841 if (newline_separator) {
842 iovec[*n].iov_base = (char*) &nl;
843 iovec[*n].iov_len = 1;
844 (*n)++;
845 }
846
847 format = va_arg(ap, char *);
848 }
849 return 0;
850 }
851
852 int log_struct_internal(
853 int level,
854 int error,
855 const char *file,
856 int line,
857 const char *func,
858 const char *format, ...) {
859
860 char buf[LINE_MAX];
861 bool found = false;
862 PROTECT_ERRNO;
863 va_list ap;
864
865 if (error < 0)
866 error = -error;
867
868 if (_likely_(LOG_PRI(level) > log_max_level))
869 return -error;
870
871 if (log_target == LOG_TARGET_NULL)
872 return -error;
873
874 if ((level & LOG_FACMASK) == 0)
875 level = log_facility | LOG_PRI(level);
876
877 if ((log_target == LOG_TARGET_AUTO ||
878 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
879 log_target == LOG_TARGET_JOURNAL) &&
880 journal_fd >= 0) {
881 char header[LINE_MAX];
882 struct iovec iovec[17] = {};
883 unsigned n = 0, i;
884 int r;
885 struct msghdr mh = {
886 .msg_iov = iovec,
887 };
888 bool fallback = false;
889
890 /* If the journal is available do structured logging */
891 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
892 IOVEC_SET_STRING(iovec[n++], header);
893
894 va_start(ap, format);
895 r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
896 if (r < 0)
897 fallback = true;
898 else {
899 mh.msg_iovlen = n;
900 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
901 }
902
903 va_end(ap);
904 for (i = 1; i < n; i += 2)
905 free(iovec[i].iov_base);
906
907 if (!fallback)
908 return -error;
909 }
910
911 /* Fallback if journal logging is not available or didn't work. */
912
913 va_start(ap, format);
914 while (format) {
915 va_list aq;
916
917 if (error != 0)
918 errno = error;
919
920 va_copy(aq, ap);
921 vsnprintf(buf, sizeof(buf), format, aq);
922 va_end(aq);
923
924 if (startswith(buf, "MESSAGE=")) {
925 found = true;
926 break;
927 }
928
929 VA_FORMAT_ADVANCE(format, ap);
930
931 format = va_arg(ap, char *);
932 }
933 va_end(ap);
934
935 if (!found)
936 return -error;
937
938 return log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
939 }
940
941 int log_set_target_from_string(const char *e) {
942 LogTarget t;
943
944 t = log_target_from_string(e);
945 if (t < 0)
946 return -EINVAL;
947
948 log_set_target(t);
949 return 0;
950 }
951
952 int log_set_max_level_from_string(const char *e) {
953 int t;
954
955 t = log_level_from_string(e);
956 if (t < 0)
957 return -EINVAL;
958
959 log_set_max_level(t);
960 return 0;
961 }
962
963 static int parse_proc_cmdline_item(const char *key, const char *value) {
964
965 /*
966 * The systemd.log_xyz= settings are parsed by all tools, and
967 * so is "debug".
968 *
969 * However, "quiet" is only parsed by PID 1, and only turns of
970 * status output to /dev/console, but does not alter the log
971 * level.
972 */
973
974 if (streq(key, "debug") && !value)
975 log_set_max_level(LOG_DEBUG);
976
977 else if (streq(key, "systemd.log_target") && value) {
978
979 if (log_set_target_from_string(value) < 0)
980 log_warning("Failed to parse log target '%s'. Ignoring.", value);
981
982 } else if (streq(key, "systemd.log_level") && value) {
983
984 if (log_set_max_level_from_string(value) < 0)
985 log_warning("Failed to parse log level '%s'. Ignoring.", value);
986
987 } else if (streq(key, "systemd.log_color") && value) {
988
989 if (log_show_color_from_string(value) < 0)
990 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
991
992 } else if (streq(key, "systemd.log_location") && value) {
993
994 if (log_show_location_from_string(value) < 0)
995 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
996 }
997
998 return 0;
999 }
1000
1001 void log_parse_environment(void) {
1002 const char *e;
1003
1004 if (get_ctty_devnr(0, NULL) < 0)
1005 /* Only try to read the command line in daemons.
1006 We assume that anything that has a controlling
1007 tty is user stuff. */
1008 (void) parse_proc_cmdline(parse_proc_cmdline_item);
1009
1010 e = secure_getenv("SYSTEMD_LOG_TARGET");
1011 if (e && log_set_target_from_string(e) < 0)
1012 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1013
1014 e = secure_getenv("SYSTEMD_LOG_LEVEL");
1015 if (e && log_set_max_level_from_string(e) < 0)
1016 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1017
1018 e = secure_getenv("SYSTEMD_LOG_COLOR");
1019 if (e && log_show_color_from_string(e) < 0)
1020 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1021
1022 e = secure_getenv("SYSTEMD_LOG_LOCATION");
1023 if (e && log_show_location_from_string(e) < 0)
1024 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1025 }
1026
1027 LogTarget log_get_target(void) {
1028 return log_target;
1029 }
1030
1031 int log_get_max_level(void) {
1032 return log_max_level;
1033 }
1034
1035 void log_show_color(bool b) {
1036 show_color = b;
1037 }
1038
1039 bool log_get_show_color(void) {
1040 return show_color;
1041 }
1042
1043 void log_show_location(bool b) {
1044 show_location = b;
1045 }
1046
1047 bool log_get_show_location(void) {
1048 return show_location;
1049 }
1050
1051 int log_show_color_from_string(const char *e) {
1052 int t;
1053
1054 t = parse_boolean(e);
1055 if (t < 0)
1056 return t;
1057
1058 log_show_color(t);
1059 return 0;
1060 }
1061
1062 int log_show_location_from_string(const char *e) {
1063 int t;
1064
1065 t = parse_boolean(e);
1066 if (t < 0)
1067 return t;
1068
1069 log_show_location(t);
1070 return 0;
1071 }
1072
1073 bool log_on_console(void) {
1074 if (log_target == LOG_TARGET_CONSOLE ||
1075 log_target == LOG_TARGET_CONSOLE_PREFIXED)
1076 return true;
1077
1078 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1079 }
1080
1081 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1082 [LOG_TARGET_CONSOLE] = "console",
1083 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1084 [LOG_TARGET_KMSG] = "kmsg",
1085 [LOG_TARGET_JOURNAL] = "journal",
1086 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1087 [LOG_TARGET_SYSLOG] = "syslog",
1088 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1089 [LOG_TARGET_AUTO] = "auto",
1090 [LOG_TARGET_SAFE] = "safe",
1091 [LOG_TARGET_NULL] = "null"
1092 };
1093
1094 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1095
1096 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1097 if (si->ssi_pid > 0) {
1098 _cleanup_free_ char *p = NULL;
1099
1100 get_process_comm(si->ssi_pid, &p);
1101
1102 log_full(level,
1103 "Received SIG%s from PID %"PRIu32" (%s).",
1104 signal_to_string(si->ssi_signo),
1105 si->ssi_pid, strna(p));
1106 } else
1107 log_full(level,
1108 "Received SIG%s.",
1109 signal_to_string(si->ssi_signo));
1110
1111 }
1112
1113 void log_set_upgrade_syslog_to_journal(bool b) {
1114 upgrade_syslog_to_journal = b;
1115 }
1116
1117 int log_syntax_internal(
1118 const char *unit,
1119 int level,
1120 const char *config_file,
1121 unsigned config_line,
1122 int error,
1123 const char *file,
1124 int line,
1125 const char *func,
1126 const char *format, ...) {
1127
1128 PROTECT_ERRNO;
1129 char buffer[LINE_MAX];
1130 int r;
1131 va_list ap;
1132
1133 if (error < 0)
1134 error = -error;
1135
1136 if (_likely_(LOG_PRI(level) > log_max_level))
1137 return -error;
1138
1139 if (log_target == LOG_TARGET_NULL)
1140 return -error;
1141
1142 if (error != 0)
1143 errno = error;
1144
1145 va_start(ap, format);
1146 vsnprintf(buffer, sizeof(buffer), format, ap);
1147 va_end(ap);
1148
1149 if (unit)
1150 r = log_struct_internal(
1151 level, error,
1152 file, line, func,
1153 getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit,
1154 LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION),
1155 "CONFIG_FILE=%s", config_file,
1156 "CONFIG_LINE=%u", config_line,
1157 LOG_MESSAGE("[%s:%u] %s", config_file, config_line, buffer),
1158 NULL);
1159 else
1160 r = log_struct_internal(
1161 level, error,
1162 file, line, func,
1163 LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION),
1164 "CONFIG_FILE=%s", config_file,
1165 "CONFIG_LINE=%u", config_line,
1166 LOG_MESSAGE("[%s:%u] %s", config_file, config_line, buffer),
1167 NULL);
1168
1169 return r;
1170 }