1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include <sys/socket.h>
36 #include "socket-util.h"
38 #define SNDBUF_SIZE (8*1024*1024)
40 static LogTarget log_target
= LOG_TARGET_CONSOLE
;
41 static int log_max_level
= LOG_INFO
;
42 static int log_facility
= LOG_DAEMON
;
44 static int console_fd
= STDERR_FILENO
;
45 static int syslog_fd
= -1;
46 static int kmsg_fd
= -1;
47 static int journal_fd
= -1;
49 static bool syslog_is_stream
= false;
51 static bool show_color
= false;
52 static bool show_location
= false;
54 static bool upgrade_syslog_to_journal
= false;
56 /* Akin to glibc's __abort_msg; which is private and we hence cannot
58 static char *log_abort_msg
= NULL
;
60 void log_close_console(void) {
67 safe_close(console_fd
);
73 static int log_open_console(void) {
79 console_fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
83 console_fd
= STDERR_FILENO
;
88 void log_close_kmsg(void) {
89 kmsg_fd
= safe_close(kmsg_fd
);
92 static int log_open_kmsg(void) {
97 kmsg_fd
= open("/dev/kmsg", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
104 void log_close_syslog(void) {
105 syslog_fd
= safe_close(syslog_fd
);
108 static int create_log_socket(int type
) {
112 fd
= socket(AF_UNIX
, type
|SOCK_CLOEXEC
, 0);
116 fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
118 /* We need a blocking fd here since we'd otherwise lose
119 messages way too early. However, let's not hang forever in the
120 unlikely case of a deadlock. */
122 timeval_store(&tv
, 10 * USEC_PER_MSEC
);
124 timeval_store(&tv
, 10 * USEC_PER_SEC
);
125 (void) setsockopt(fd
, SOL_SOCKET
, SO_SNDTIMEO
, &tv
, sizeof(tv
));
130 static int log_open_syslog(void) {
132 union sockaddr_union sa
= {
133 .un
.sun_family
= AF_UNIX
,
134 .un
.sun_path
= "/dev/log",
140 syslog_fd
= create_log_socket(SOCK_DGRAM
);
146 if (connect(syslog_fd
, &sa
.sa
, offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.un
.sun_path
)) < 0) {
147 safe_close(syslog_fd
);
149 /* Some legacy syslog systems still use stream
150 * sockets. They really shouldn't. But what can we
152 syslog_fd
= create_log_socket(SOCK_STREAM
);
158 if (connect(syslog_fd
, &sa
.sa
, offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.un
.sun_path
)) < 0) {
163 syslog_is_stream
= true;
165 syslog_is_stream
= false;
174 void log_close_journal(void) {
175 journal_fd
= safe_close(journal_fd
);
178 static int log_open_journal(void) {
179 union sockaddr_union sa
= {
180 .un
.sun_family
= AF_UNIX
,
181 .un
.sun_path
= "/run/systemd/journal/socket",
188 journal_fd
= create_log_socket(SOCK_DGRAM
);
189 if (journal_fd
< 0) {
194 if (connect(journal_fd
, &sa
.sa
, offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.un
.sun_path
)) < 0) {
209 /* If we don't use the console we close it here, to not get
210 * killed by SAK. If we don't use syslog we close it here so
211 * that we are not confused by somebody deleting the socket in
212 * the fs. If we don't use /dev/kmsg we still keep it open,
213 * because there is no reason to close it. */
215 if (log_target
== LOG_TARGET_NULL
) {
222 if ((log_target
!= LOG_TARGET_AUTO
&& log_target
!= LOG_TARGET_SAFE
) ||
224 isatty(STDERR_FILENO
) <= 0) {
226 if (log_target
== LOG_TARGET_AUTO
||
227 log_target
== LOG_TARGET_JOURNAL_OR_KMSG
||
228 log_target
== LOG_TARGET_JOURNAL
) {
229 r
= log_open_journal();
237 if (log_target
== LOG_TARGET_SYSLOG_OR_KMSG
||
238 log_target
== LOG_TARGET_SYSLOG
) {
239 r
= log_open_syslog();
247 if (log_target
== LOG_TARGET_AUTO
||
248 log_target
== LOG_TARGET_SAFE
||
249 log_target
== LOG_TARGET_JOURNAL_OR_KMSG
||
250 log_target
== LOG_TARGET_SYSLOG_OR_KMSG
||
251 log_target
== LOG_TARGET_KMSG
) {
265 return log_open_console();
268 void log_set_target(LogTarget target
) {
270 assert(target
< _LOG_TARGET_MAX
);
272 if (upgrade_syslog_to_journal
) {
273 if (target
== LOG_TARGET_SYSLOG
)
274 target
= LOG_TARGET_JOURNAL
;
275 else if (target
== LOG_TARGET_SYSLOG_OR_KMSG
)
276 target
= LOG_TARGET_JOURNAL_OR_KMSG
;
282 void log_close(void) {
289 void log_forget_fds(void) {
290 console_fd
= kmsg_fd
= syslog_fd
= journal_fd
= -1;
293 void log_set_max_level(int level
) {
294 assert((level
& LOG_PRIMASK
) == level
);
296 log_max_level
= level
;
299 void log_set_facility(int facility
) {
300 log_facility
= facility
;
303 static int write_to_console(
309 const char *object_field
,
311 const char *buffer
) {
314 struct iovec iovec
[5] = {};
321 highlight
= LOG_PRI(level
) <= LOG_ERR
&& show_color
;
324 snprintf(location
, sizeof(location
), "(%s:%u) ", file
, line
);
325 char_array_0(location
);
326 IOVEC_SET_STRING(iovec
[n
++], location
);
330 IOVEC_SET_STRING(iovec
[n
++], ANSI_HIGHLIGHT_RED_ON
);
331 IOVEC_SET_STRING(iovec
[n
++], buffer
);
333 IOVEC_SET_STRING(iovec
[n
++], ANSI_HIGHLIGHT_OFF
);
334 IOVEC_SET_STRING(iovec
[n
++], "\n");
336 if (writev(console_fd
, iovec
, n
) < 0) {
338 if (errno
== EIO
&& getpid() == 1) {
340 /* If somebody tried to kick us from our
341 * console tty (via vhangup() or suchlike),
342 * try to reconnect */
350 if (writev(console_fd
, iovec
, n
) < 0)
359 static int write_to_syslog(
365 const char *object_field
,
367 const char *buffer
) {
369 char header_priority
[1 + DECIMAL_STR_MAX(int) + 2], header_time
[64], header_pid
[1 + DECIMAL_STR_MAX(pid_t
) + 4];
370 struct iovec iovec
[5] = {};
371 struct msghdr msghdr
= {
373 .msg_iovlen
= ELEMENTSOF(iovec
),
381 snprintf(header_priority
, sizeof(header_priority
), "<%i>", level
);
382 char_array_0(header_priority
);
384 t
= (time_t) (now(CLOCK_REALTIME
) / USEC_PER_SEC
);
389 if (strftime(header_time
, sizeof(header_time
), "%h %e %T ", tm
) <= 0)
392 snprintf(header_pid
, sizeof(header_pid
), "["PID_FMT
"]: ", getpid());
393 char_array_0(header_pid
);
395 IOVEC_SET_STRING(iovec
[0], header_priority
);
396 IOVEC_SET_STRING(iovec
[1], header_time
);
397 IOVEC_SET_STRING(iovec
[2], program_invocation_short_name
);
398 IOVEC_SET_STRING(iovec
[3], header_pid
);
399 IOVEC_SET_STRING(iovec
[4], buffer
);
401 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
402 if (syslog_is_stream
)
408 n
= sendmsg(syslog_fd
, &msghdr
, MSG_NOSIGNAL
);
412 if (!syslog_is_stream
||
413 (size_t) n
>= IOVEC_TOTAL_SIZE(iovec
, ELEMENTSOF(iovec
)))
416 IOVEC_INCREMENT(iovec
, ELEMENTSOF(iovec
), n
);
422 static int write_to_kmsg(
428 const char *object_field
,
430 const char *buffer
) {
432 char header_priority
[1 + DECIMAL_STR_MAX(int) + 2], header_pid
[1 + DECIMAL_STR_MAX(pid_t
) + 4];
433 struct iovec iovec
[5] = {};
438 snprintf(header_priority
, sizeof(header_priority
), "<%i>", level
);
439 char_array_0(header_priority
);
441 snprintf(header_pid
, sizeof(header_pid
), "["PID_FMT
"]: ", getpid());
442 char_array_0(header_pid
);
444 IOVEC_SET_STRING(iovec
[0], header_priority
);
445 IOVEC_SET_STRING(iovec
[1], program_invocation_short_name
);
446 IOVEC_SET_STRING(iovec
[2], header_pid
);
447 IOVEC_SET_STRING(iovec
[3], buffer
);
448 IOVEC_SET_STRING(iovec
[4], "\n");
450 if (writev(kmsg_fd
, iovec
, ELEMENTSOF(iovec
)) < 0)
456 static int log_do_header(
461 const char *file
, int line
, const char *func
,
462 const char *object_field
, const char *object
) {
464 snprintf(header
, size
,
466 "SYSLOG_FACILITY=%i\n"
472 "SYSLOG_IDENTIFIER=%s\n",
475 isempty(file
) ? "" : "CODE_FILE=",
476 isempty(file
) ? "" : file
,
477 isempty(file
) ? "" : "\n",
478 line
? "CODE_LINE=" : "",
479 line
? 1 : 0, line
, /* %.0d means no output too, special case for 0 */
481 isempty(func
) ? "" : "CODE_FUNCTION=",
482 isempty(func
) ? "" : func
,
483 isempty(func
) ? "" : "\n",
484 error
? "ERRNO=" : "",
485 error
? 1 : 0, error
,
487 isempty(object
) ? "" : object_field
,
488 isempty(object
) ? "" : object
,
489 isempty(object
) ? "" : "\n",
490 program_invocation_short_name
);
491 header
[size
- 1] = '\0';
496 static int write_to_journal(
502 const char *object_field
,
504 const char *buffer
) {
506 char header
[LINE_MAX
];
507 struct iovec iovec
[4] = {};
508 struct msghdr mh
= {};
513 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, object_field
, object
);
515 IOVEC_SET_STRING(iovec
[0], header
);
516 IOVEC_SET_STRING(iovec
[1], "MESSAGE=");
517 IOVEC_SET_STRING(iovec
[2], buffer
);
518 IOVEC_SET_STRING(iovec
[3], "\n");
521 mh
.msg_iovlen
= ELEMENTSOF(iovec
);
523 if (sendmsg(journal_fd
, &mh
, MSG_NOSIGNAL
) < 0)
529 static int log_dispatch(
535 const char *object_field
,
541 if (log_target
== LOG_TARGET_NULL
)
544 /* Patch in LOG_DAEMON facility if necessary */
545 if ((level
& LOG_FACMASK
) == 0)
546 level
= log_facility
| LOG_PRI(level
);
552 buffer
+= strspn(buffer
, NEWLINE
);
557 if ((e
= strpbrk(buffer
, NEWLINE
)))
560 if (log_target
== LOG_TARGET_AUTO
||
561 log_target
== LOG_TARGET_JOURNAL_OR_KMSG
||
562 log_target
== LOG_TARGET_JOURNAL
) {
564 k
= write_to_journal(level
, error
, file
, line
, func
, object_field
, object
, buffer
);
573 if (log_target
== LOG_TARGET_SYSLOG_OR_KMSG
||
574 log_target
== LOG_TARGET_SYSLOG
) {
576 k
= write_to_syslog(level
, error
, file
, line
, func
, object_field
, object
, buffer
);
586 (log_target
== LOG_TARGET_AUTO
||
587 log_target
== LOG_TARGET_SAFE
||
588 log_target
== LOG_TARGET_SYSLOG_OR_KMSG
||
589 log_target
== LOG_TARGET_JOURNAL_OR_KMSG
||
590 log_target
== LOG_TARGET_KMSG
)) {
592 k
= write_to_kmsg(level
, error
, file
, line
, func
, object_field
, object
, buffer
);
601 k
= write_to_console(level
, error
, file
, line
, func
, object_field
, object
, buffer
);
612 int log_dump_internal(
622 /* This modifies the buffer... */
624 if (_likely_(LOG_PRI(level
) > log_max_level
))
627 return log_dispatch(level
, error
, file
, line
, func
, NULL
, NULL
, buffer
);
640 char buffer
[LINE_MAX
];
642 if (_likely_(LOG_PRI(level
) > log_max_level
))
645 /* Make sure that %m maps to the specified error */
649 vsnprintf(buffer
, sizeof(buffer
), format
, ap
);
650 char_array_0(buffer
);
652 return log_dispatch(level
, error
, file
, line
, func
, NULL
, NULL
, buffer
);
661 const char *format
, ...) {
666 va_start(ap
, format
);
667 r
= log_internalv(level
, error
, file
, line
, func
, format
, ap
);
673 int log_object_internalv(
679 const char *object_field
,
685 char buffer
[LINE_MAX
];
687 if (_likely_(LOG_PRI(level
) > log_max_level
))
690 /* Make sure that %m maps to the specified error */
694 vsnprintf(buffer
, sizeof(buffer
), format
, ap
);
695 char_array_0(buffer
);
697 return log_dispatch(level
, error
, file
, line
, func
, object_field
, object
, buffer
);
700 int log_object_internal(
706 const char *object_field
,
708 const char *format
, ...) {
713 va_start(ap
, format
);
714 r
= log_object_internalv(level
, error
, file
, line
, func
, object_field
, object
, format
, ap
);
720 static void log_assert(
726 const char *format
) {
728 static char buffer
[LINE_MAX
];
730 if (_likely_(LOG_PRI(level
) > log_max_level
))
733 DISABLE_WARNING_FORMAT_NONLITERAL
;
734 snprintf(buffer
, sizeof(buffer
), format
, text
, file
, line
, func
);
737 char_array_0(buffer
);
738 log_abort_msg
= buffer
;
740 log_dispatch(level
, 0, file
, line
, func
, NULL
, NULL
, buffer
);
743 noreturn
void log_assert_failed(const char *text
, const char *file
, int line
, const char *func
) {
744 log_assert(LOG_CRIT
, text
, file
, line
, func
, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
748 noreturn
void log_assert_failed_unreachable(const char *text
, const char *file
, int line
, const char *func
) {
749 log_assert(LOG_CRIT
, text
, file
, line
, func
, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
753 void log_assert_failed_return(const char *text
, const char *file
, int line
, const char *func
) {
755 log_assert(LOG_DEBUG
, text
, file
, line
, func
, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
758 int log_oom_internal(const char *file
, int line
, const char *func
) {
759 log_internal(LOG_ERR
, ENOMEM
, file
, line
, func
, "Out of memory.");
763 int log_struct_internal(
769 const char *format
, ...) {
775 if (_likely_(LOG_PRI(level
) > log_max_level
))
778 if (log_target
== LOG_TARGET_NULL
)
781 if ((level
& LOG_FACMASK
) == 0)
782 level
= log_facility
| LOG_PRI(level
);
784 if ((log_target
== LOG_TARGET_AUTO
||
785 log_target
== LOG_TARGET_JOURNAL_OR_KMSG
||
786 log_target
== LOG_TARGET_JOURNAL
) &&
789 char header
[LINE_MAX
];
790 struct iovec iovec
[17] = {};
795 static const char nl
= '\n';
797 /* If the journal is available do structured logging */
798 log_do_header(header
, sizeof(header
), level
, error
, file
, line
, func
, NULL
, NULL
);
799 IOVEC_SET_STRING(iovec
[n
++], header
);
801 va_start(ap
, format
);
802 while (format
&& n
+ 1 < ELEMENTSOF(iovec
)) {
806 /* We need to copy the va_list structure,
807 * since vasprintf() leaves it afterwards at
808 * an undefined location */
811 if (vasprintf(&buf
, format
, aq
) < 0) {
818 /* Now, jump enough ahead, so that we point to
819 * the next format string */
820 VA_FORMAT_ADVANCE(format
, ap
);
822 IOVEC_SET_STRING(iovec
[n
++], buf
);
824 iovec
[n
].iov_base
= (char*) &nl
;
825 iovec
[n
].iov_len
= 1;
828 format
= va_arg(ap
, char *);
833 if (sendmsg(journal_fd
, &mh
, MSG_NOSIGNAL
) < 0)
840 for (i
= 1; i
< n
; i
+= 2)
841 free(iovec
[i
].iov_base
);
847 /* Fallback if journal logging is not available */
849 va_start(ap
, format
);
854 vsnprintf(buf
, sizeof(buf
), format
, aq
);
858 if (startswith(buf
, "MESSAGE=")) {
863 VA_FORMAT_ADVANCE(format
, ap
);
865 format
= va_arg(ap
, char *);
870 r
= log_dispatch(level
, error
, file
, line
, func
, NULL
, NULL
, buf
+ 8);
878 int log_set_target_from_string(const char *e
) {
881 t
= log_target_from_string(e
);
889 int log_set_max_level_from_string(const char *e
) {
892 t
= log_level_from_string(e
);
896 log_set_max_level(t
);
900 static int parse_proc_cmdline_item(const char *key
, const char *value
) {
903 * The systemd.log_xyz= settings are parsed by all tools, and
906 * However, "quiet" is only parsed by PID 1!
909 if (streq(key
, "debug") && !value
)
910 log_set_max_level(LOG_DEBUG
);
912 else if (streq(key
, "systemd.log_target") && value
) {
914 if (log_set_target_from_string(value
) < 0)
915 log_warning("Failed to parse log target '%s'. Ignoring.", value
);
917 } else if (streq(key
, "systemd.log_level") && value
) {
919 if (log_set_max_level_from_string(value
) < 0)
920 log_warning("Failed to parse log level '%s'. Ignoring.", value
);
922 } else if (streq(key
, "systemd.log_color") && value
) {
924 if (log_show_color_from_string(value
) < 0)
925 log_warning("Failed to parse log color setting '%s'. Ignoring.", value
);
927 } else if (streq(key
, "systemd.log_location") && value
) {
929 if (log_show_location_from_string(value
) < 0)
930 log_warning("Failed to parse log location setting '%s'. Ignoring.", value
);
936 void log_parse_environment(void) {
939 (void) parse_proc_cmdline(parse_proc_cmdline_item
);
941 e
= secure_getenv("SYSTEMD_LOG_TARGET");
942 if (e
&& log_set_target_from_string(e
) < 0)
943 log_warning("Failed to parse log target '%s'. Ignoring.", e
);
945 e
= secure_getenv("SYSTEMD_LOG_LEVEL");
946 if (e
&& log_set_max_level_from_string(e
) < 0)
947 log_warning("Failed to parse log level '%s'. Ignoring.", e
);
949 e
= secure_getenv("SYSTEMD_LOG_COLOR");
950 if (e
&& log_show_color_from_string(e
) < 0)
951 log_warning("Failed to parse bool '%s'. Ignoring.", e
);
953 e
= secure_getenv("SYSTEMD_LOG_LOCATION");
954 if (e
&& log_show_location_from_string(e
) < 0)
955 log_warning("Failed to parse bool '%s'. Ignoring.", e
);
958 LogTarget
log_get_target(void) {
962 int log_get_max_level(void) {
963 return log_max_level
;
966 void log_show_color(bool b
) {
970 bool log_get_show_color(void) {
974 void log_show_location(bool b
) {
978 bool log_get_show_location(void) {
979 return show_location
;
982 int log_show_color_from_string(const char *e
) {
985 t
= parse_boolean(e
);
993 int log_show_location_from_string(const char *e
) {
996 t
= parse_boolean(e
);
1000 log_show_location(t
);
1004 bool log_on_console(void) {
1005 if (log_target
== LOG_TARGET_CONSOLE
)
1008 return syslog_fd
< 0 && kmsg_fd
< 0 && journal_fd
< 0;
1011 static const char *const log_target_table
[_LOG_TARGET_MAX
] = {
1012 [LOG_TARGET_CONSOLE
] = "console",
1013 [LOG_TARGET_KMSG
] = "kmsg",
1014 [LOG_TARGET_JOURNAL
] = "journal",
1015 [LOG_TARGET_JOURNAL_OR_KMSG
] = "journal-or-kmsg",
1016 [LOG_TARGET_SYSLOG
] = "syslog",
1017 [LOG_TARGET_SYSLOG_OR_KMSG
] = "syslog-or-kmsg",
1018 [LOG_TARGET_AUTO
] = "auto",
1019 [LOG_TARGET_SAFE
] = "safe",
1020 [LOG_TARGET_NULL
] = "null"
1023 DEFINE_STRING_TABLE_LOOKUP(log_target
, LogTarget
);
1025 void log_received_signal(int level
, const struct signalfd_siginfo
*si
) {
1026 if (si
->ssi_pid
> 0) {
1027 _cleanup_free_
char *p
= NULL
;
1029 get_process_comm(si
->ssi_pid
, &p
);
1032 "Received SIG%s from PID "PID_FMT
" (%s).",
1033 signal_to_string(si
->ssi_signo
),
1034 si
->ssi_pid
, strna(p
));
1038 signal_to_string(si
->ssi_signo
));
1042 void log_set_upgrade_syslog_to_journal(bool b
) {
1043 upgrade_syslog_to_journal
= b
;