]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/log.c
man/systemd-sysext: list ephemeral/ephemeral-import in the list of options
[thirdparty/systemd.git] / src / basic / log.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
a7334b09 2
16801e90 3#include <fcntl.h>
11c3a366 4#include <sys/signalfd.h>
bc694c06 5#include <sys/stat.h>
11c3a366 6#include <sys/uio.h>
e7537295 7#include <threads.h>
07630cea 8#include <unistd.h>
5899f3b7 9
158350e8 10#include "sd-messages.h"
07630cea 11
b5efdb8a 12#include "alloc-util.h"
b7120388 13#include "ansi-color.h"
ee617a4e 14#include "argv-util.h"
7c7a9138 15#include "env-util.h"
2b2fec7d 16#include "errno-util.h"
6553db60 17#include "extract-word.h"
3ffd4af2 18#include "fd-util.h"
f97b34a6 19#include "format-util.h"
bd1ae178 20#include "iovec-util.h"
4a52d26d 21#include "list.h"
3ffd4af2 22#include "log.h"
a4bff6ef 23#include "log-context.h"
4e731273
LP
24#include "parse-util.h"
25#include "proc-cmdline.h"
0b452006 26#include "process-util.h"
78158d13 27#include "ratelimit.h"
24882e06 28#include "signal-util.h"
07630cea 29#include "socket-util.h"
15a5e950 30#include "stdio-util.h"
8b43440b 31#include "string-table.h"
07630cea 32#include "string-util.h"
7c7a9138 33#include "strv.h"
7ccbd1ae 34#include "syslog-util.h"
07630cea 35#include "terminal-util.h"
93cc7779 36#include "time-util.h"
d04ce5a9 37#include "utf8.h"
5899f3b7 38
bb99a35a 39#define SNDBUF_SIZE (8*1024*1024)
81b3565e 40#define IOVEC_MAX 256U
bb99a35a 41
3cc3dc77
MG
42static log_syntax_callback_t log_syntax_callback = NULL;
43static void *log_syntax_callback_userdata = NULL;
44
16801e90 45static LogTarget log_target = LOG_TARGET_CONSOLE;
9fdee66f 46static int log_max_level = LOG_INFO;
4f4c37bc 47static int log_target_max_level[_LOG_TARGET_SINGLE_MAX] = {
e8815abf
DDM
48 [LOG_TARGET_CONSOLE] = INT_MAX,
49 [LOG_TARGET_KMSG] = INT_MAX,
50 [LOG_TARGET_SYSLOG] = INT_MAX,
51 [LOG_TARGET_JOURNAL] = INT_MAX,
52};
3eff4208 53static int log_facility = LOG_DAEMON;
8750a06b 54static bool ratelimit_kmsg = true;
16801e90 55
843d2643 56static int console_fd = STDERR_FILENO;
d19ddf91 57static int console_fd_is_tty = -1; /* tri-state: -1 means don't know */
254d1313
ZJS
58static int syslog_fd = -EBADF;
59static int kmsg_fd = -EBADF;
60static int journal_fd = -EBADF;
16801e90 61
c31e1495
LP
62static bool syslog_is_stream = false;
63
db987463 64static int show_color = -1; /* tristate */
bbe63281 65static bool show_location = false;
c5673ed0 66static bool show_time = false;
9ee806d1 67static bool show_tid = false;
bbe63281 68
c1dc6153 69static bool upgrade_syslog_to_journal = false;
48a601fe 70static bool always_reopen_console = false;
16e4fd87 71static bool open_when_needed = false;
adf47c91 72static bool prohibit_ipc = false;
185986c6 73
ee2975a9
DDM
74static thread_local const char *log_prefix = NULL;
75
011a03a3
ZJS
76#if LOG_MESSAGE_VERIFICATION || defined(__COVERITY__)
77bool _log_message_dummy = false; /* Always false */
78#endif
79
780747da
ZJS
80/* An assert to use in logging functions that does not call recursively
81 * into our logging functions (since that might lead to a loop). */
82#define assert_raw(expr) \
83 do { \
84 if (_unlikely_(!(expr))) { \
85 fputs(#expr "\n", stderr); \
86 abort(); \
87 } \
88 } while (false)
89
cc2b9e6b 90static void log_close_console(void) {
40cdb3b7
LB
91 /* See comment in log_close_journal() */
92 (void) safe_close_above_stdio(TAKE_FD(console_fd));
d19ddf91 93 console_fd_is_tty = -1;
16801e90
LP
94}
95
843d2643 96static int log_open_console(void) {
16801e90 97
cc2b9e6b
AJ
98 if (!always_reopen_console) {
99 console_fd = STDERR_FILENO;
d19ddf91 100 console_fd_is_tty = -1;
16801e90 101 return 0;
cc2b9e6b 102 }
843d2643 103
cc2b9e6b 104 if (console_fd < 3) {
d5a1c99b 105 int fd;
7fe2903c 106
d5a1c99b
LP
107 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
108 if (fd < 0)
109 return fd;
110
111 console_fd = fd_move_above_stdio(fd);
d19ddf91 112 console_fd_is_tty = true;
cc2b9e6b 113 }
843d2643
LP
114
115 return 0;
116}
117
cc2b9e6b 118static void log_close_kmsg(void) {
40cdb3b7
LB
119 /* See comment in log_close_journal() */
120 (void) safe_close(TAKE_FD(kmsg_fd));
843d2643
LP
121}
122
123static int log_open_kmsg(void) {
16801e90
LP
124
125 if (kmsg_fd >= 0)
126 return 0;
127
674f8283 128 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
cd15c418 129 if (kmsg_fd < 0)
16801e90 130 return -errno;
0dae83f9 131
7fe2903c 132 kmsg_fd = fd_move_above_stdio(kmsg_fd);
16801e90
LP
133 return 0;
134}
135
cc2b9e6b 136static void log_close_syslog(void) {
40cdb3b7
LB
137 /* See comment in log_close_journal() */
138 (void) safe_close(TAKE_FD(syslog_fd));
16801e90
LP
139}
140
c31e1495 141static int create_log_socket(int type) {
8b18fdc1 142 struct timeval tv;
95066a90 143 int fd;
c31e1495 144
8b18fdc1 145 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
5ba081b0 146 if (fd < 0)
c31e1495
LP
147 return -errno;
148
7fe2903c 149 fd = fd_move_above_stdio(fd);
0474ef7b 150 (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
bb99a35a 151
7fe2903c
LP
152 /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever
153 * in the unlikely case of a deadlock. */
df0ff127 154 if (getpid_cached() == 1)
4d89874a
ZJS
155 timeval_store(&tv, 10 * USEC_PER_MSEC);
156 else
157 timeval_store(&tv, 10 * USEC_PER_SEC);
086891e5 158 (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
8b18fdc1 159
c31e1495
LP
160 return fd;
161}
162
843d2643 163static int log_open_syslog(void) {
95066a90
LP
164 int r;
165
16801e90
LP
166 if (syslog_fd >= 0)
167 return 0;
168
5ba081b0
LP
169 syslog_fd = create_log_socket(SOCK_DGRAM);
170 if (syslog_fd < 0) {
171 r = syslog_fd;
843d2643 172 goto fail;
16801e90
LP
173 }
174
1861986a
LP
175 r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log");
176 if (r < 0) {
03e334a1 177 safe_close(syslog_fd);
c31e1495 178
1861986a
LP
179 /* Some legacy syslog systems still use stream sockets. They really shouldn't. But what can
180 * we do... */
5ba081b0
LP
181 syslog_fd = create_log_socket(SOCK_STREAM);
182 if (syslog_fd < 0) {
183 r = syslog_fd;
c31e1495
LP
184 goto fail;
185 }
186
1861986a
LP
187 r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log");
188 if (r < 0)
c31e1495 189 goto fail;
c31e1495
LP
190
191 syslog_is_stream = true;
192 } else
193 syslog_is_stream = false;
194
16801e90 195 return 0;
843d2643
LP
196
197fail:
198 log_close_syslog();
843d2643
LP
199 return r;
200}
201
cc2b9e6b 202static void log_close_journal(void) {
40cdb3b7
LB
203 /* If the journal FD is bad, safe_close will fail, and will try to log, which will fail, so we'll
204 * try to close the journal FD, which is bad, so safe_close will fail... Whether we can close it
205 * or not, invalidate it immediately so that we don't get in a recursive loop until we run out of
206 * stack. */
207 (void) safe_close(TAKE_FD(journal_fd));
5ba081b0
LP
208}
209
210static int log_open_journal(void) {
5ba081b0
LP
211 int r;
212
213 if (journal_fd >= 0)
214 return 0;
215
216 journal_fd = create_log_socket(SOCK_DGRAM);
217 if (journal_fd < 0) {
218 r = journal_fd;
219 goto fail;
220 }
221
1861986a
LP
222 r = connect_unix_path(journal_fd, AT_FDCWD, "/run/systemd/journal/socket");
223 if (r < 0)
5ba081b0 224 goto fail;
5ba081b0 225
5ba081b0
LP
226 return 0;
227
228fail:
229 log_close_journal();
5ba081b0
LP
230 return r;
231}
232
7a7d7a2e 233bool stderr_is_journal(void) {
bc694c06
DDM
234 _cleanup_free_ char *w = NULL;
235 const char *e;
236 uint64_t dev, ino;
237 struct stat st;
238
239 e = getenv("JOURNAL_STREAM");
240 if (!e)
241 return false;
242
243 if (extract_first_word(&e, &w, ":", EXTRACT_DONT_COALESCE_SEPARATORS) <= 0)
244 return false;
245 if (!e)
246 return false;
247
248 if (safe_atou64(w, &dev) < 0)
249 return false;
250 if (safe_atou64(e, &ino) < 0)
251 return false;
252
253 if (fstat(STDERR_FILENO, &st) < 0)
254 return false;
255
256 return st.st_dev == dev && st.st_ino == ino;
257}
258
843d2643
LP
259int log_open(void) {
260 int r;
261
e3e42fc2
ZJS
262 /* Do not call from library code. */
263
d2297047
ZJS
264 /* This function is often called in preparation for logging. Let's make sure we don't clobber errno,
265 * so that a call to a logging function immediately following a log_open() call can still easily
266 * reference an error that happened immediately before the log_open() call. */
0e557eef
SB
267 PROTECT_ERRNO;
268
d2297047
ZJS
269 /* If we don't use the console, we close it here to not get killed by SAK. If we don't use syslog, we
270 * close it here too, so that we are not confused by somebody deleting the socket in the fs, and to
271 * make sure we don't use it if prohibit_ipc is set. If we don't use /dev/kmsg we still keep it open,
843d2643
LP
272 * because there is no reason to close it. */
273
9fae33d2 274 if (log_target == LOG_TARGET_NULL) {
5ba081b0 275 log_close_journal();
9fae33d2
LP
276 log_close_syslog();
277 log_close_console();
278 return 0;
279 }
280
ef9bddb7
LP
281 if (getpid_cached() == 1 ||
282 stderr_is_journal() ||
283 IN_SET(log_target,
284 LOG_TARGET_KMSG,
285 LOG_TARGET_JOURNAL,
286 LOG_TARGET_JOURNAL_OR_KMSG,
287 LOG_TARGET_SYSLOG,
288 LOG_TARGET_SYSLOG_OR_KMSG)) {
289
290 if (!prohibit_ipc) {
291 if (IN_SET(log_target,
292 LOG_TARGET_AUTO,
293 LOG_TARGET_JOURNAL_OR_KMSG,
294 LOG_TARGET_JOURNAL)) {
295
296 r = log_open_journal();
297 if (r >= 0) {
298 log_close_syslog();
299 log_close_console();
300 return r;
301 }
bb7df0da 302 }
5ba081b0 303
ef9bddb7
LP
304 if (IN_SET(log_target,
305 LOG_TARGET_SYSLOG_OR_KMSG,
306 LOG_TARGET_SYSLOG)) {
307
308 r = log_open_syslog();
309 if (r >= 0) {
310 log_close_journal();
311 log_close_console();
312 return r;
313 }
5ba081b0
LP
314 }
315 }
316
5b5688af 317 if (IN_SET(log_target, LOG_TARGET_AUTO,
5b5688af
ZJS
318 LOG_TARGET_JOURNAL_OR_KMSG,
319 LOG_TARGET_SYSLOG_OR_KMSG,
320 LOG_TARGET_KMSG)) {
5ba081b0
LP
321 r = log_open_kmsg();
322 if (r >= 0) {
323 log_close_journal();
bb7df0da
LP
324 log_close_syslog();
325 log_close_console();
326 return r;
327 }
5ba081b0 328 }
bb7df0da 329 }
843d2643 330
5ba081b0 331 log_close_journal();
843d2643 332 log_close_syslog();
dcdf86bb 333
843d2643 334 return log_open_console();
16801e90
LP
335}
336
337void log_set_target(LogTarget target) {
338 assert(target >= 0);
339 assert(target < _LOG_TARGET_MAX);
340
c1dc6153
LP
341 if (upgrade_syslog_to_journal) {
342 if (target == LOG_TARGET_SYSLOG)
343 target = LOG_TARGET_JOURNAL;
344 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
345 target = LOG_TARGET_JOURNAL_OR_KMSG;
346 }
347
16801e90
LP
348 log_target = target;
349}
350
1e344c1d
LP
351void log_set_target_and_open(LogTarget target) {
352 log_set_target(target);
353 log_open();
354}
355
871e5809 356void log_close(void) {
e3e42fc2
ZJS
357 /* Do not call from library code. */
358
5ba081b0 359 log_close_journal();
871e5809 360 log_close_syslog();
5ba081b0
LP
361 log_close_kmsg();
362 log_close_console();
871e5809
LP
363}
364
4d8a7798 365void log_forget_fds(void) {
e3e42fc2
ZJS
366 /* Do not call from library code. */
367
254d1313 368 console_fd = kmsg_fd = syslog_fd = journal_fd = -EBADF;
d19ddf91 369 console_fd_is_tty = -1;
4d8a7798
MS
370}
371
7881f485 372int log_set_max_level(int level) {
adb556ab 373 assert(level == LOG_NULL || log_level_is_valid(level));
16801e90 374
7881f485 375 int old = log_max_level;
9fdee66f 376 log_max_level = level;
13f37e6e
LP
377
378 /* Also propagate max log level to libc's syslog(), just in case some other component loaded into our
379 * process logs directly via syslog(). You might wonder why we maintain our own log level variable if
380 * libc has the same functionality. This has multiple reasons, first and foremost that we want to
381 * apply this to all our log targets, not just syslog and console. Moreover, we cannot query the
382 * current log mask from glibc without changing it, but that's useful for testing the current log
383 * level before even entering the log functions like we do in our macros. */
384 setlogmask(LOG_UPTO(level));
385
386 /* Ensure that our own LOG_NULL define maps sanely to the log mask */
387 assert_cc(LOG_UPTO(LOG_NULL) == 0);
7881f485
DDM
388
389 return old;
16801e90
LP
390}
391
3eff4208
LP
392void log_set_facility(int facility) {
393 log_facility = facility;
394}
395
d19ddf91
LP
396static bool check_console_fd_is_tty(void) {
397 if (console_fd < 0)
398 return false;
399
400 if (console_fd_is_tty < 0)
dd9c8da8 401 console_fd_is_tty = isatty_safe(console_fd);
d19ddf91
LP
402
403 return console_fd_is_tty;
404}
405
843d2643 406static int write_to_console(
20c03b7b 407 int level,
086891e5 408 int error,
95066a90 409 const char *file,
20c03b7b
LP
410 int line,
411 const char *func,
412 const char *buffer) {
5899f3b7 413
1b889631
DDM
414 static int dumb = -1;
415
c5673ed0
DS
416 char location[256],
417 header_time[FORMAT_TIMESTAMP_MAX],
9ee806d1
LP
418 prefix[1 + DECIMAL_STR_MAX(int) + 2],
419 tid_string[3 + DECIMAL_STR_MAX(pid_t) + 1];
ee2975a9 420 struct iovec iovec[11];
37b8d2f6 421 const char *on = NULL, *off = NULL;
da6053d0 422 size_t n = 0;
5899f3b7 423
843d2643
LP
424 if (console_fd < 0)
425 return 0;
426
1b889631
DDM
427 if (dumb < 0)
428 dumb = getenv_terminal_is_dumb();
429
e8815abf
DDM
430 if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_CONSOLE])
431 return 0;
432
aca83a53 433 if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
0474ef7b 434 xsprintf(prefix, "<%i>", level);
e6a7ec4b 435 iovec[n++] = IOVEC_MAKE_STRING(prefix);
aca83a53
LP
436 }
437
5941112e
YW
438 if (show_time &&
439 format_timestamp(header_time, sizeof(header_time), now(CLOCK_REALTIME))) {
440 iovec[n++] = IOVEC_MAKE_STRING(header_time);
441 iovec[n++] = IOVEC_MAKE_STRING(" ");
c5673ed0
DS
442 }
443
9ee806d1
LP
444 if (show_tid) {
445 xsprintf(tid_string, "(" PID_FMT ") ", gettid());
446 iovec[n++] = IOVEC_MAKE_STRING(tid_string);
447 }
448
db987463 449 if (log_get_show_color())
37b8d2f6 450 get_log_colors(LOG_PRI(level), &on, &off, NULL);
843d2643 451
674f8283 452 if (show_location) {
d35305fe 453 const char *lon = "", *loff = "";
db987463 454 if (log_get_show_color()) {
25e4608b 455 lon = ansi_highlight_yellow4();
7b376b29 456 loff = ansi_normal();
d35305fe
ZJS
457 }
458
459 (void) snprintf(location, sizeof location, "%s%s:%i%s: ", lon, file, line, loff);
e6a7ec4b 460 iovec[n++] = IOVEC_MAKE_STRING(location);
674f8283
LP
461 }
462
37b8d2f6
ZJS
463 if (on)
464 iovec[n++] = IOVEC_MAKE_STRING(on);
ee2975a9
DDM
465 if (log_prefix) {
466 iovec[n++] = IOVEC_MAKE_STRING(log_prefix);
467 iovec[n++] = IOVEC_MAKE_STRING(": ");
468 }
e6a7ec4b 469 iovec[n++] = IOVEC_MAKE_STRING(buffer);
37b8d2f6
ZJS
470 if (off)
471 iovec[n++] = IOVEC_MAKE_STRING(off);
d19ddf91
LP
472
473 /* When writing to a TTY we output an extra '\r' (i.e. CR) first, to generate CRNL rather than just
474 * NL. This is a robustness thing in case the TTY is currently in raw mode (specifically: has the
475 * ONLCR flag off). We want that subsequent output definitely starts at the beginning of the line
1b889631
DDM
476 * again, after all. If the TTY is not in raw mode the extra CR should not hurt. If we're writing to
477 * a dumb terminal, only write NL as CRNL might be interpreted as a double newline. */
478 iovec[n++] = IOVEC_MAKE_STRING(check_console_fd_is_tty() && !dumb ? "\r\n" : "\n");
843d2643 479
0e6eaa2d
LP
480 if (writev(console_fd, iovec, n) < 0) {
481
df0ff127 482 if (errno == EIO && getpid_cached() == 1) {
0e6eaa2d 483
e11a5c72
LP
484 /* If somebody tried to kick us from our console tty (via vhangup() or suchlike), try
485 * to reconnect. */
0e6eaa2d
LP
486
487 log_close_console();
e11a5c72 488 (void) log_open_console();
0e6eaa2d
LP
489 if (console_fd < 0)
490 return 0;
491
492 if (writev(console_fd, iovec, n) < 0)
493 return -errno;
494 } else
495 return -errno;
496 }
5899f3b7 497
843d2643 498 return 1;
16801e90 499}
5899f3b7 500
16801e90 501static int write_to_syslog(
086891e5
LP
502 int level,
503 int error,
95066a90 504 const char *file,
086891e5
LP
505 int line,
506 const char *func,
086891e5 507 const char *buffer) {
16801e90 508
5ffa8c81
ZJS
509 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
510 header_time[64],
511 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
e0f691e1 512 struct tm tm;
6f5cf415 513 int r;
16801e90
LP
514
515 if (syslog_fd < 0)
843d2643 516 return 0;
16801e90 517
e8815abf
DDM
518 if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_SYSLOG])
519 return 0;
520
5ffa8c81 521 xsprintf(header_priority, "<%i>", level);
16801e90 522
6f5cf415
LP
523 r = localtime_or_gmtime_usec(now(CLOCK_REALTIME), /* utc= */ false, &tm);
524 if (r < 0)
525 return r;
16801e90 526
e0f691e1 527 if (strftime(header_time, sizeof(header_time), "%h %e %T ", &tm) <= 0)
16801e90
LP
528 return -EINVAL;
529
df0ff127 530 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
16801e90 531
905a0abd
ZJS
532 struct iovec iovec[] = {
533 IOVEC_MAKE_STRING(header_priority),
534 IOVEC_MAKE_STRING(header_time),
535 IOVEC_MAKE_STRING(program_invocation_short_name),
536 IOVEC_MAKE_STRING(header_pid),
ee2975a9
DDM
537 IOVEC_MAKE_STRING(strempty(log_prefix)),
538 IOVEC_MAKE_STRING(log_prefix ? ": " : ""),
905a0abd
ZJS
539 IOVEC_MAKE_STRING(buffer),
540 };
4dc2ecd2 541 const struct msghdr msghdr = {
905a0abd
ZJS
542 .msg_iov = iovec,
543 .msg_iovlen = ELEMENTSOF(iovec),
544 };
16801e90 545
c899f8c6 546 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
c31e1495 547 if (syslog_is_stream)
905a0abd 548 iovec[ELEMENTSOF(iovec) - 1].iov_len++;
c31e1495 549
c31e1495
LP
550 for (;;) {
551 ssize_t n;
552
8f7f7a1b
MS
553 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
554 if (n < 0)
c31e1495
LP
555 return -errno;
556
32f65484 557 if (!syslog_is_stream)
c31e1495
LP
558 break;
559
986235a9 560 if (iovec_increment(iovec, ELEMENTSOF(iovec), n))
32f65484 561 break;
c31e1495 562 }
16801e90 563
843d2643 564 return 1;
16801e90
LP
565}
566
567static int write_to_kmsg(
086891e5
LP
568 int level,
569 int error,
bcf5c276 570 const char *file,
086891e5
LP
571 int line,
572 const char *func,
086891e5 573 const char *buffer) {
16801e90 574
78158d13
ZJS
575 /* Set a ratelimit on the amount of messages logged to /dev/kmsg. This is mostly supposed to be a
576 * safety catch for the case where start indiscriminately logging in a loop. It will not catch cases
577 * where we log excessively, but not in a tight loop.
578 *
579 * Note that this ratelimit is per-emitter, so we might still overwhelm /dev/kmsg with multiple
580 * loggers.
581 */
582 static thread_local RateLimit ratelimit = { 5 * USEC_PER_SEC, 200 };
583
5ffa8c81
ZJS
584 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
585 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
16801e90
LP
586
587 if (kmsg_fd < 0)
843d2643 588 return 0;
16801e90 589
e8815abf
DDM
590 if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_KMSG])
591 return 0;
592
3fe07e95
DDM
593 if (ratelimit_kmsg && !ratelimit_below(&ratelimit)) {
594 if (ratelimit_num_dropped(&ratelimit) > 1)
595 return 0;
596
597 buffer = "Too many messages being logged to kmsg, ignoring";
598 }
78158d13 599
5ffa8c81 600 xsprintf(header_priority, "<%i>", level);
df0ff127 601 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
16801e90 602
905a0abd
ZJS
603 const struct iovec iovec[] = {
604 IOVEC_MAKE_STRING(header_priority),
605 IOVEC_MAKE_STRING(program_invocation_short_name),
606 IOVEC_MAKE_STRING(header_pid),
ee2975a9
DDM
607 IOVEC_MAKE_STRING(strempty(log_prefix)),
608 IOVEC_MAKE_STRING(log_prefix ? ": " : ""),
905a0abd
ZJS
609 IOVEC_MAKE_STRING(buffer),
610 IOVEC_MAKE_STRING("\n"),
611 };
16801e90
LP
612
613 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
614 return -errno;
615
843d2643 616 return 1;
16801e90
LP
617}
618
086891e5
LP
619static int log_do_header(
620 char *header,
621 size_t size,
622 int level,
623 int error,
624 const char *file, int line, const char *func,
4b58153d
LP
625 const char *object_field, const char *object,
626 const char *extra_field, const char *extra) {
f8e6f4aa 627 int r;
086891e5 628
52d86690
ZJS
629 error = IS_SYNTHETIC_ERRNO(error) ? 0 : ERRNO_VALUE(error);
630
f8e6f4aa
ZJS
631 r = snprintf(header, size,
632 "PRIORITY=%i\n"
633 "SYSLOG_FACILITY=%i\n"
38ffc7d1 634 "TID=" PID_FMT "\n"
f8e6f4aa
ZJS
635 "%s%.256s%s" /* CODE_FILE */
636 "%s%.*i%s" /* CODE_LINE */
637 "%s%.256s%s" /* CODE_FUNC */
638 "%s%.*i%s" /* ERRNO */
639 "%s%.256s%s" /* object */
640 "%s%.256s%s" /* extra */
641 "SYSLOG_IDENTIFIER=%.256s\n",
642 LOG_PRI(level),
643 LOG_FAC(level),
38ffc7d1 644 gettid(),
f8e6f4aa
ZJS
645 isempty(file) ? "" : "CODE_FILE=",
646 isempty(file) ? "" : file,
647 isempty(file) ? "" : "\n",
648 line ? "CODE_LINE=" : "",
649 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
650 line ? "\n" : "",
651 isempty(func) ? "" : "CODE_FUNC=",
652 isempty(func) ? "" : func,
653 isempty(func) ? "" : "\n",
654 error ? "ERRNO=" : "",
655 error ? 1 : 0, error,
656 error ? "\n" : "",
7e91a68b 657 isempty(object) ? "" : ASSERT_PTR(object_field),
f8e6f4aa
ZJS
658 isempty(object) ? "" : object,
659 isempty(object) ? "" : "\n",
7e91a68b 660 isempty(extra) ? "" : ASSERT_PTR(extra_field),
f8e6f4aa
ZJS
661 isempty(extra) ? "" : extra,
662 isempty(extra) ? "" : "\n",
663 program_invocation_short_name);
780747da 664 assert_raw((size_t) r < size);
086891e5 665
41a79f10
ZJS
666 return 0;
667}
5ba081b0 668
7c7a9138
DDM
669static void log_do_context(struct iovec *iovec, size_t iovec_len, size_t *n) {
670 assert(iovec);
671 assert(n);
672
a4bff6ef 673 LIST_FOREACH(ll, c, log_context_head()) {
7c7a9138
DDM
674 STRV_FOREACH(s, c->fields) {
675 if (*n + 2 >= iovec_len)
676 return;
677
678 iovec[(*n)++] = IOVEC_MAKE_STRING(*s);
679 iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
680 }
2461943b
LB
681
682 for (size_t i = 0; i < c->n_input_iovec; i++) {
683 if (*n + 2 >= iovec_len)
684 return;
685
686 iovec[(*n)++] = c->input_iovec[i];
687 iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
688 }
81b3565e
DDM
689
690 if (c->key && c->value) {
691 if (*n + 3 >= iovec_len)
692 return;
693
694 iovec[(*n)++] = IOVEC_MAKE_STRING(c->key);
695 iovec[(*n)++] = IOVEC_MAKE_STRING(c->value);
696 iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
697 }
2461943b 698 }
7c7a9138
DDM
699}
700
41a79f10 701static int write_to_journal(
086891e5
LP
702 int level,
703 int error,
bcf5c276 704 const char *file,
086891e5
LP
705 int line,
706 const char *func,
707 const char *object_field,
708 const char *object,
4b58153d
LP
709 const char *extra_field,
710 const char *extra,
086891e5 711 const char *buffer) {
41a79f10
ZJS
712
713 char header[LINE_MAX];
7c7a9138
DDM
714 size_t n = 0, iovec_len;
715 struct iovec *iovec;
41a79f10
ZJS
716
717 if (journal_fd < 0)
718 return 0;
719
e8815abf
DDM
720 if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_JOURNAL])
721 return 0;
722
a4bff6ef 723 iovec_len = MIN(6 + log_context_num_fields() * 3, IOVEC_MAX);
7c7a9138
DDM
724 iovec = newa(struct iovec, iovec_len);
725
4b58153d 726 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
5ba081b0 727
7c7a9138
DDM
728 iovec[n++] = IOVEC_MAKE_STRING(header);
729 iovec[n++] = IOVEC_MAKE_STRING("MESSAGE=");
ee2975a9
DDM
730 if (log_prefix) {
731 iovec[n++] = IOVEC_MAKE_STRING(log_prefix);
732 iovec[n++] = IOVEC_MAKE_STRING(": ");
733 }
7c7a9138
DDM
734 iovec[n++] = IOVEC_MAKE_STRING(buffer);
735 iovec[n++] = IOVEC_MAKE_STRING("\n");
736
737 log_do_context(iovec, iovec_len, &n);
738
4dc2ecd2
ZJS
739 const struct msghdr msghdr = {
740 .msg_iov = iovec,
7c7a9138 741 .msg_iovlen = n,
4dc2ecd2 742 };
5ba081b0 743
4dc2ecd2 744 if (sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL) < 0)
5ba081b0
LP
745 return -errno;
746
747 return 1;
748}
749
93484b47 750int log_dispatch_internal(
086891e5
LP
751 int level,
752 int error,
95066a90 753 const char *file,
086891e5
LP
754 int line,
755 const char *func,
756 const char *object_field,
757 const char *object,
4b58153d 758 const char *extra_field,
4dd09c6a 759 const char *extra,
086891e5 760 char *buffer) {
843d2643 761
780747da 762 assert_raw(buffer);
843d2643 763
9fae33d2 764 if (log_target == LOG_TARGET_NULL)
52d86690 765 return -ERRNO_VALUE(error);
9fae33d2 766
29db5834 767 /* Patch in LOG_DAEMON facility if necessary */
c1db424d 768 if (LOG_FAC(level) == 0)
52d86690 769 level |= log_facility;
29db5834 770
16e4fd87 771 if (open_when_needed)
e11a5c72 772 (void) log_open();
16e4fd87 773
9726b29e
LP
774 do {
775 char *e;
9499b235 776 int k = 0;
843d2643 777
9726b29e 778 buffer += strspn(buffer, NEWLINE);
843d2643 779
9726b29e
LP
780 if (buffer[0] == 0)
781 break;
843d2643 782
9726b29e
LP
783 if ((e = strpbrk(buffer, NEWLINE)))
784 *(e++) = 0;
843d2643 785
5b5688af
ZJS
786 if (IN_SET(log_target, LOG_TARGET_AUTO,
787 LOG_TARGET_JOURNAL_OR_KMSG,
788 LOG_TARGET_JOURNAL)) {
5ba081b0 789
4b58153d 790 k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
e38b8a40
LP
791 if (k < 0 && k != -EAGAIN)
792 log_close_journal();
5ba081b0
LP
793 }
794
5b5688af
ZJS
795 if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
796 LOG_TARGET_SYSLOG)) {
9726b29e 797
4b58153d 798 k = write_to_syslog(level, error, file, line, func, buffer);
e38b8a40
LP
799 if (k < 0 && k != -EAGAIN)
800 log_close_syslog();
9726b29e
LP
801 }
802
9499b235 803 if (k <= 0 &&
5b5688af 804 IN_SET(log_target, LOG_TARGET_AUTO,
5b5688af
ZJS
805 LOG_TARGET_SYSLOG_OR_KMSG,
806 LOG_TARGET_JOURNAL_OR_KMSG,
807 LOG_TARGET_KMSG)) {
9726b29e 808
e38b8a40
LP
809 if (k < 0)
810 log_open_kmsg();
811
4b58153d 812 k = write_to_kmsg(level, error, file, line, func, buffer);
4e7bc3f3
LP
813 if (k < 0) {
814 log_close_kmsg();
e11a5c72 815 (void) log_open_console();
bf371116 816 }
9726b29e
LP
817 }
818
bf371116 819 if (k <= 0)
4b58153d 820 (void) write_to_console(level, error, file, line, func, buffer);
9726b29e
LP
821
822 buffer = e;
823 } while (buffer);
824
16e4fd87
LP
825 if (open_when_needed)
826 log_close();
827
52d86690 828 return -ERRNO_VALUE(error);
843d2643
LP
829}
830
2149e37c 831int log_dump_internal(
ff524019
ZJS
832 int level,
833 int error,
834 const char *file,
835 int line,
836 const char *func,
837 char *buffer) {
2149e37c 838
5c0aa72a 839 PROTECT_ERRNO;
2149e37c
LP
840
841 /* This modifies the buffer... */
842
9fdee66f 843 if (_likely_(LOG_PRI(level) > log_max_level))
52d86690 844 return -ERRNO_VALUE(error);
2149e37c 845
93484b47 846 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
2149e37c
LP
847}
848
9fdee66f 849int log_internalv(
086891e5
LP
850 int level,
851 int error,
bcf5c276 852 const char *file,
086891e5
LP
853 int line,
854 const char *func,
855 const char *format,
856 va_list ap) {
16801e90 857
9fdee66f 858 if (_likely_(LOG_PRI(level) > log_max_level))
52d86690 859 return -ERRNO_VALUE(error);
16801e90 860
b29f6480 861 /* Make sure that %m maps to the specified error (or "Success"). */
50c5b991
ZJS
862 char buffer[LINE_MAX];
863 LOCAL_ERRNO(ERRNO_VALUE(error));
086891e5 864
4ad2b562 865 (void) vsnprintf(buffer, sizeof buffer, format, ap);
843d2643 866
93484b47 867 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
185986c6 868}
16801e90 869
9fdee66f 870int log_internal(
086891e5
LP
871 int level,
872 int error,
bcf5c276 873 const char *file,
086891e5
LP
874 int line,
875 const char *func,
876 const char *format, ...) {
17a94911 877
17a94911 878 va_list ap;
bf371116 879 int r;
17a94911
LP
880
881 va_start(ap, format);
9fdee66f 882 r = log_internalv(level, error, file, line, func, format, ap);
17a94911
LP
883 va_end(ap);
884
885 return r;
886}
887
f6d6d532 888int log_object_internalv(
086891e5
LP
889 int level,
890 int error,
bcf5c276 891 const char *file,
086891e5
LP
892 int line,
893 const char *func,
894 const char *object_field,
895 const char *object,
4b58153d
LP
896 const char *extra_field,
897 const char *extra,
086891e5
LP
898 const char *format,
899 va_list ap) {
fdf9f9bb 900
f2341e0a 901 char *buffer, *b;
fdf9f9bb 902
9fdee66f 903 if (_likely_(LOG_PRI(level) > log_max_level))
52d86690 904 return -ERRNO_VALUE(error);
fdf9f9bb 905
d1a1f0aa 906 /* Make sure that %m maps to the specified error (or "Success"). */
50c5b991 907 LOCAL_ERRNO(ERRNO_VALUE(error));
086891e5 908
ee2975a9 909 LOG_SET_PREFIX(object);
f2341e0a 910
ee2975a9 911 b = buffer = newa(char, LINE_MAX);
4ad2b562 912 (void) vsnprintf(b, LINE_MAX, format, ap);
fdf9f9bb 913
93484b47
ZJS
914 return log_dispatch_internal(level, error, file, line, func,
915 object_field, object, extra_field, extra, buffer);
fdf9f9bb
ZJS
916}
917
79008bdd 918int log_object_internal(
086891e5
LP
919 int level,
920 int error,
bcf5c276 921 const char *file,
086891e5
LP
922 int line,
923 const char *func,
924 const char *object_field,
925 const char *object,
4b58153d
LP
926 const char *extra_field,
927 const char *extra,
086891e5 928 const char *format, ...) {
fdf9f9bb 929
fdf9f9bb 930 va_list ap;
bf371116 931 int r;
fdf9f9bb
ZJS
932
933 va_start(ap, format);
4b58153d 934 r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
fdf9f9bb
ZJS
935 va_end(ap);
936
937 return r;
938}
939
b3a79158 940int log_oom_internal(int level, const char *file, int line, const char *func) {
9fdee66f 941 return log_internal(level, ENOMEM, file, line, func, "Out of memory.");
6dc1e7e0
MS
942}
943
8a03c9ef
ZJS
944int log_format_iovec(
945 struct iovec *iovec,
d3070fbd
LP
946 size_t iovec_len,
947 size_t *n,
8a03c9ef
ZJS
948 bool newline_separator,
949 int error,
950 const char *format,
951 va_list ap) {
952
953 static const char nl = '\n';
954
955 while (format && *n + 1 < iovec_len) {
956 va_list aq;
957 char *m;
958 int r;
959
960 /* We need to copy the va_list structure,
961 * since vasprintf() leaves it afterwards at
962 * an undefined location */
963
52d86690 964 errno = ERRNO_VALUE(error);
8a03c9ef
ZJS
965
966 va_copy(aq, ap);
967 r = vasprintf(&m, format, aq);
968 va_end(aq);
969 if (r < 0)
970 return -EINVAL;
971
972 /* Now, jump enough ahead, so that we point to
973 * the next format string */
974 VA_FORMAT_ADVANCE(format, ap);
975
e6a7ec4b 976 iovec[(*n)++] = IOVEC_MAKE_STRING(m);
2fec408e
ZJS
977 if (newline_separator)
978 iovec[(*n)++] = IOVEC_MAKE((char *)&nl, 1);
8a03c9ef
ZJS
979
980 format = va_arg(ap, char *);
981 }
982 return 0;
983}
984
877d54e9
LP
985int log_struct_internal(
986 int level,
086891e5 987 int error,
877d54e9
LP
988 const char *file,
989 int line,
990 const char *func,
991 const char *format, ...) {
992
bf371116
LP
993 char buf[LINE_MAX];
994 bool found = false;
5c0aa72a 995 PROTECT_ERRNO;
877d54e9 996 va_list ap;
bf371116 997
9fdee66f 998 if (_likely_(LOG_PRI(level) > log_max_level) ||
52d86690
ZJS
999 log_target == LOG_TARGET_NULL)
1000 return -ERRNO_VALUE(error);
877d54e9 1001
c1db424d 1002 if (LOG_FAC(level) == 0)
52d86690 1003 level |= log_facility;
877d54e9 1004
16e4fd87
LP
1005 if (IN_SET(log_target,
1006 LOG_TARGET_AUTO,
1007 LOG_TARGET_JOURNAL_OR_KMSG,
1008 LOG_TARGET_JOURNAL)) {
1009
1010 if (open_when_needed)
1011 log_open_journal();
1012
1013 if (journal_fd >= 0) {
1014 char header[LINE_MAX];
7c7a9138
DDM
1015 struct iovec *iovec;
1016 size_t n = 0, m, iovec_len;
16e4fd87 1017 int r;
16e4fd87
LP
1018 bool fallback = false;
1019
a4bff6ef 1020 iovec_len = MIN(17 + log_context_num_fields() * 3, IOVEC_MAX);
7c7a9138
DDM
1021 iovec = newa(struct iovec, iovec_len);
1022
52d86690
ZJS
1023 /* If the journal is available do structured logging.
1024 * Do not report the errno if it is synthetic. */
16e4fd87
LP
1025 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
1026 iovec[n++] = IOVEC_MAKE_STRING(header);
1027
1028 va_start(ap, format);
3cf6a3a3 1029 DISABLE_WARNING_FORMAT_NONLITERAL;
7c7a9138 1030 r = log_format_iovec(iovec, iovec_len, &n, true, error, format, ap);
3cf6a3a3 1031 REENABLE_WARNING;
7c7a9138 1032 m = n;
16e4fd87
LP
1033 if (r < 0)
1034 fallback = true;
1035 else {
7c7a9138
DDM
1036 log_do_context(iovec, iovec_len, &n);
1037
4dc2ecd2
ZJS
1038 const struct msghdr msghdr = {
1039 .msg_iov = iovec,
1040 .msg_iovlen = n,
1041 };
1042
1043 (void) sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL);
16e4fd87 1044 }
877d54e9 1045
16e4fd87 1046 va_end(ap);
7c7a9138 1047 for (size_t i = 1; i < m; i += 2)
16e4fd87 1048 free(iovec[i].iov_base);
877d54e9 1049
16e4fd87
LP
1050 if (!fallback) {
1051 if (open_when_needed)
1052 log_close();
877d54e9 1053
52d86690 1054 return -ERRNO_VALUE(error);
16e4fd87
LP
1055 }
1056 }
bf371116 1057 }
877d54e9 1058
bf371116 1059 /* Fallback if journal logging is not available or didn't work. */
6357ac66 1060
bf371116
LP
1061 va_start(ap, format);
1062 while (format) {
1063 va_list aq;
877d54e9 1064
52d86690 1065 errno = ERRNO_VALUE(error);
877d54e9 1066
bf371116 1067 va_copy(aq, ap);
3cf6a3a3 1068 DISABLE_WARNING_FORMAT_NONLITERAL;
4ad2b562 1069 (void) vsnprintf(buf, sizeof buf, format, aq);
3cf6a3a3 1070 REENABLE_WARNING;
bf371116 1071 va_end(aq);
963ddb91 1072
bf371116
LP
1073 if (startswith(buf, "MESSAGE=")) {
1074 found = true;
1075 break;
877d54e9 1076 }
877d54e9 1077
bf371116
LP
1078 VA_FORMAT_ADVANCE(format, ap);
1079
1080 format = va_arg(ap, char *);
877d54e9 1081 }
bf371116 1082 va_end(ap);
877d54e9 1083
16e4fd87
LP
1084 if (!found) {
1085 if (open_when_needed)
1086 log_close();
1087
52d86690 1088 return -ERRNO_VALUE(error);
16e4fd87 1089 }
bf371116 1090
93484b47 1091 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
877d54e9
LP
1092}
1093
915b1d01
LP
1094int log_struct_iovec_internal(
1095 int level,
1096 int error,
1097 const char *file,
1098 int line,
1099 const char *func,
1100 const struct iovec input_iovec[],
1101 size_t n_input_iovec) {
1102
915b1d01 1103 PROTECT_ERRNO;
915b1d01 1104
9fdee66f 1105 if (_likely_(LOG_PRI(level) > log_max_level) ||
52d86690
ZJS
1106 log_target == LOG_TARGET_NULL)
1107 return -ERRNO_VALUE(error);
915b1d01 1108
c1db424d 1109 if (LOG_FAC(level) == 0)
52d86690 1110 level |= log_facility;
915b1d01
LP
1111
1112 if (IN_SET(log_target, LOG_TARGET_AUTO,
1113 LOG_TARGET_JOURNAL_OR_KMSG,
1114 LOG_TARGET_JOURNAL) &&
1115 journal_fd >= 0) {
1116
915b1d01 1117 char header[LINE_MAX];
7c7a9138
DDM
1118 struct iovec *iovec;
1119 size_t n = 0, iovec_len;
1120
a4bff6ef 1121 iovec_len = MIN(1 + n_input_iovec * 2 + log_context_num_fields() * 3, IOVEC_MAX);
7c7a9138
DDM
1122 iovec = newa(struct iovec, iovec_len);
1123
915b1d01 1124 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
915b1d01 1125
7c7a9138 1126 iovec[n++] = IOVEC_MAKE_STRING(header);
2fec408e 1127 for (size_t i = 0; i < n_input_iovec; i++) {
7c7a9138
DDM
1128 iovec[n++] = input_iovec[i];
1129 iovec[n++] = IOVEC_MAKE_STRING("\n");
915b1d01
LP
1130 }
1131
7c7a9138
DDM
1132 log_do_context(iovec, iovec_len, &n);
1133
4dc2ecd2
ZJS
1134 const struct msghdr msghdr = {
1135 .msg_iov = iovec,
7c7a9138 1136 .msg_iovlen = n,
4dc2ecd2
ZJS
1137 };
1138
1139 if (sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL) >= 0)
52d86690 1140 return -ERRNO_VALUE(error);
915b1d01
LP
1141 }
1142
2fec408e
ZJS
1143 for (size_t i = 0; i < n_input_iovec; i++)
1144 if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE=")) {
2f82562b
LP
1145 char *m;
1146
1147 m = strndupa_safe((char*) input_iovec[i].iov_base + STRLEN("MESSAGE="),
1148 input_iovec[i].iov_len - STRLEN("MESSAGE="));
915b1d01 1149
2fec408e
ZJS
1150 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
1151 }
915b1d01 1152
2fec408e
ZJS
1153 /* Couldn't find MESSAGE=. */
1154 return -ERRNO_VALUE(error);
915b1d01
LP
1155}
1156
34f0e866
LP
1157int log_set_target_from_string(const char *e) {
1158 LogTarget t;
1159
5ba081b0
LP
1160 t = log_target_from_string(e);
1161 if (t < 0)
7211c853 1162 return t;
34f0e866
LP
1163
1164 log_set_target(t);
1165 return 0;
1166}
1167
9fdee66f 1168int log_set_max_level_from_string(const char *e) {
25ac30bd 1169 int r;
34f0e866 1170
e8815abf
DDM
1171 for (;;) {
1172 _cleanup_free_ char *word = NULL, *prefix = NULL;
1173 LogTarget target;
1174 const char *colon;
1175
1176 r = extract_first_word(&e, &word, ",", 0);
1177 if (r < 0)
1178 return r;
1179 if (r == 0)
1180 break;
1181
1182 colon = strchr(word, ':');
1183 if (!colon) {
1184 r = log_level_from_string(word);
1185 if (r < 0)
1186 return r;
1187
1188 log_set_max_level(r);
1189 continue;
1190 }
1191
1192 prefix = strndup(word, colon - word);
1193 if (!prefix)
1194 return -ENOMEM;
1195
1196 target = log_target_from_string(prefix);
1197 if (target < 0)
1198 return target;
1199
1200 if (target >= _LOG_TARGET_SINGLE_MAX)
1201 return -EINVAL;
1202
1203 r = log_level_from_string(colon + 1);
1204 if (r < 0)
1205 return r;
1206
1207 log_target_max_level[target] = r;
1208 }
1209
1210 return 0;
1211}
1212
1213int log_max_levels_to_string(int level, char **ret) {
1214 _cleanup_free_ char *s = NULL;
1215 int r;
1216
1217 assert(ret);
1218
1219 r = log_level_to_string_alloc(level, &s);
25ac30bd
YW
1220 if (r < 0)
1221 return r;
34f0e866 1222
e8815abf
DDM
1223 for (LogTarget target = 0; target < _LOG_TARGET_SINGLE_MAX; target++) {
1224 _cleanup_free_ char *l = NULL;
1225
1226 if (log_target_max_level[target] == INT_MAX)
1227 continue;
1228
1229 r = log_level_to_string_alloc(log_target_max_level[target], &l);
1230 if (r < 0)
1231 return r;
1232
1233 r = strextendf_with_separator(&s, ",", "%s:%s", log_target_to_string(target), l);
1234 if (r < 0)
1235 return r;
1236 }
1237
1238 *ret = TAKE_PTR(s);
34f0e866
LP
1239 return 0;
1240}
1241
8750a06b
DDM
1242static int log_set_ratelimit_kmsg_from_string(const char *e) {
1243 int r;
1244
1245 r = parse_boolean(e);
1246 if (r < 0)
1247 return r;
1248
1249 ratelimit_kmsg = r;
1250 return 0;
1251}
1252
96287a49 1253static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
1de1c9c3
LP
1254
1255 /*
1256 * The systemd.log_xyz= settings are parsed by all tools, and
1257 * so is "debug".
1258 *
5e07a79e
LP
1259 * However, "quiet" is only parsed by PID 1, and only turns of
1260 * status output to /dev/console, but does not alter the log
1261 * level.
1de1c9c3
LP
1262 */
1263
1264 if (streq(key, "debug") && !value)
1265 log_set_max_level(LOG_DEBUG);
1266
1d84ad94
LP
1267 else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1268
1269 if (proc_cmdline_value_missing(key, value))
1270 return 0;
1de1c9c3
LP
1271
1272 if (log_set_target_from_string(value) < 0)
2e52b6c6 1273 log_warning("Failed to parse log target '%s', ignoring.", value);
1de1c9c3 1274
1d84ad94
LP
1275 } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1276
1277 if (proc_cmdline_value_missing(key, value))
1278 return 0;
1de1c9c3
LP
1279
1280 if (log_set_max_level_from_string(value) < 0)
e8815abf 1281 log_warning("Failed to parse log level setting '%s', ignoring.", value);
1de1c9c3 1282
1d84ad94 1283 } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1de1c9c3 1284
1d84ad94 1285 if (log_show_color_from_string(value ?: "1") < 0)
2e52b6c6 1286 log_warning("Failed to parse log color setting '%s', ignoring.", value);
1de1c9c3 1287
1d84ad94 1288 } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1de1c9c3 1289
1d84ad94 1290 if (log_show_location_from_string(value ?: "1") < 0)
2e52b6c6 1291 log_warning("Failed to parse log location setting '%s', ignoring.", value);
c5673ed0 1292
9ee806d1
LP
1293 } else if (proc_cmdline_key_streq(key, "systemd.log_tid")) {
1294
1295 if (log_show_tid_from_string(value ?: "1") < 0)
2e52b6c6 1296 log_warning("Failed to parse log tid setting '%s', ignoring.", value);
9ee806d1 1297
c5673ed0
DS
1298 } else if (proc_cmdline_key_streq(key, "systemd.log_time")) {
1299
1300 if (log_show_time_from_string(value ?: "1") < 0)
2e52b6c6 1301 log_warning("Failed to parse log time setting '%s', ignoring.", value);
c5673ed0 1302
8750a06b
DDM
1303 } else if (proc_cmdline_key_streq(key, "systemd.log_ratelimit_kmsg")) {
1304
1305 if (log_set_ratelimit_kmsg_from_string(value ?: "1") < 0)
2e52b6c6 1306 log_warning("Failed to parse log ratelimit kmsg boolean '%s', ignoring.", value);
1de1c9c3
LP
1307 }
1308
1309 return 0;
1310}
1311
85cf96e3 1312static bool should_parse_proc_cmdline(void) {
85cf96e3
YW
1313 /* PID1 always reads the kernel command line. */
1314 if (getpid_cached() == 1)
1315 return true;
1316
7c52d523 1317 /* Otherwise, parse the command line if invoked directly by systemd. */
494f4ee9 1318 return invoked_by_systemd();
85cf96e3
YW
1319}
1320
a7d15a24 1321void log_parse_environment_variables(void) {
74189020 1322 const char *e;
3e32e5a4 1323 int r;
74189020 1324
a99e002c 1325 e = getenv("SYSTEMD_LOG_TARGET");
88fae6e0 1326 if (e && log_set_target_from_string(e) < 0)
2e52b6c6 1327 log_warning("Failed to parse log target '%s', ignoring.", e);
34f0e866 1328
a99e002c 1329 e = getenv("SYSTEMD_LOG_LEVEL");
3e32e5a4
LP
1330 if (e) {
1331 r = log_set_max_level_from_string(e);
1332 if (r < 0)
1333 log_warning_errno(r, "Failed to parse log level '%s', ignoring: %m", e);
1334 } else {
1335 /* If no explicit log level is specified then let's see if this is a debug invocation, and if
1336 * so raise the log level to debug too. Note that this is not symmetric: just because
1337 * DEBUG_INVOCATION is explicitly set to 0 we won't lower the log level below debug. This
1338 * follows the logic that debug logging is an opt-in thing anyway, and if there's any reason
1339 * to enable it we should not disable it here automatically. */
1340 r = getenv_bool("DEBUG_INVOCATION");
1341 if (r < 0 && r != -ENXIO)
1342 log_warning_errno(r, "Failed to parse $DEBUG_INVOCATION value, ignoring: %m");
1343 else if (r > 0)
1344 log_set_max_level(LOG_DEBUG);
1345 }
bbe63281 1346
a99e002c 1347 e = getenv("SYSTEMD_LOG_COLOR");
88fae6e0 1348 if (e && log_show_color_from_string(e) < 0)
2e52b6c6 1349 log_warning("Failed to parse log color '%s', ignoring.", e);
bbe63281 1350
a99e002c 1351 e = getenv("SYSTEMD_LOG_LOCATION");
88fae6e0 1352 if (e && log_show_location_from_string(e) < 0)
2e52b6c6 1353 log_warning("Failed to parse log location '%s', ignoring.", e);
c5673ed0
DS
1354
1355 e = getenv("SYSTEMD_LOG_TIME");
1356 if (e && log_show_time_from_string(e) < 0)
2e52b6c6 1357 log_warning("Failed to parse log time '%s', ignoring.", e);
9ee806d1
LP
1358
1359 e = getenv("SYSTEMD_LOG_TID");
1360 if (e && log_show_tid_from_string(e) < 0)
2e52b6c6 1361 log_warning("Failed to parse log tid '%s', ignoring.", e);
8750a06b
DDM
1362
1363 e = getenv("SYSTEMD_LOG_RATELIMIT_KMSG");
1364 if (e && log_set_ratelimit_kmsg_from_string(e) < 0)
2e52b6c6 1365 log_warning("Failed to parse log ratelimit kmsg boolean '%s', ignoring.", e);
34f0e866
LP
1366}
1367
a7d15a24
ZJS
1368void log_parse_environment(void) {
1369 /* Do not call from library code. */
1370
1371 if (should_parse_proc_cmdline())
1372 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1373
1374 log_parse_environment_variables();
1375}
1376
1adf1049
LP
1377LogTarget log_get_target(void) {
1378 return log_target;
a3b00f91
DDM
1379}
1380
1381void log_settle_target(void) {
1382
1383 /* If we're using LOG_TARGET_AUTO and opening the log again on every single log call, we'll check if
1384 * stderr is attached to the journal every single log call. However, if we then close all file
1385 * descriptors later, that will stop working because stderr will be closed as well. To avoid that
1386 * problem, this function is used to permanently change the log target depending on whether stderr is
1387 * connected to the journal or not. */
1388
1389 LogTarget t = log_get_target();
1390
1391 if (t != LOG_TARGET_AUTO)
1392 return;
1393
1394 t = getpid_cached() == 1 || stderr_is_journal() ? (prohibit_ipc ? LOG_TARGET_KMSG : LOG_TARGET_JOURNAL_OR_KMSG)
1395 : LOG_TARGET_CONSOLE;
1396 log_set_target(t);
1adf1049
LP
1397}
1398
9fdee66f
YW
1399int log_get_max_level(void) {
1400 return log_max_level;
1adf1049
LP
1401}
1402
92e8e2b0
IK
1403int log_get_target_max_level(LogTarget target) {
1404 assert(target >= 0);
1405 assert(target < _LOG_TARGET_SINGLE_MAX);
1406 return log_target_max_level[target];
1407}
1408
bbe63281
LP
1409void log_show_color(bool b) {
1410 show_color = b;
1411}
1412
b1e90ec5 1413bool log_get_show_color(void) {
db987463 1414 return show_color > 0; /* Defaults to false. */
b1e90ec5
ZJS
1415}
1416
bbe63281
LP
1417void log_show_location(bool b) {
1418 show_location = b;
1419}
1420
b1e90ec5
ZJS
1421bool log_get_show_location(void) {
1422 return show_location;
1423}
1424
c5673ed0
DS
1425void log_show_time(bool b) {
1426 show_time = b;
1427}
1428
1429bool log_get_show_time(void) {
1430 return show_time;
1431}
1432
9ee806d1
LP
1433void log_show_tid(bool b) {
1434 show_tid = b;
1435}
1436
1437bool log_get_show_tid(void) {
1438 return show_tid;
1439}
1440
bbe63281 1441int log_show_color_from_string(const char *e) {
25ac30bd 1442 int r;
bbe63281 1443
25ac30bd
YW
1444 r = parse_boolean(e);
1445 if (r < 0)
1446 return r;
bbe63281 1447
25ac30bd 1448 log_show_color(r);
bbe63281
LP
1449 return 0;
1450}
1451
1452int log_show_location_from_string(const char *e) {
25ac30bd 1453 int r;
bbe63281 1454
25ac30bd
YW
1455 r = parse_boolean(e);
1456 if (r < 0)
1457 return r;
bbe63281 1458
25ac30bd 1459 log_show_location(r);
bbe63281
LP
1460 return 0;
1461}
1462
c5673ed0 1463int log_show_time_from_string(const char *e) {
25ac30bd 1464 int r;
c5673ed0 1465
25ac30bd
YW
1466 r = parse_boolean(e);
1467 if (r < 0)
1468 return r;
c5673ed0 1469
25ac30bd 1470 log_show_time(r);
c5673ed0
DS
1471 return 0;
1472}
1473
9ee806d1 1474int log_show_tid_from_string(const char *e) {
25ac30bd 1475 int r;
9ee806d1 1476
25ac30bd
YW
1477 r = parse_boolean(e);
1478 if (r < 0)
1479 return r;
9ee806d1 1480
25ac30bd 1481 log_show_tid(r);
9ee806d1
LP
1482 return 0;
1483}
1484
81270860 1485bool log_on_console(void) {
5b5688af
ZJS
1486 if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1487 LOG_TARGET_CONSOLE_PREFIXED))
81270860
LP
1488 return true;
1489
1490 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1491}
1492
2c5859af 1493static const char *const log_target_table[_LOG_TARGET_MAX] = {
969524fa 1494 [LOG_TARGET_CONSOLE] = "console",
aca83a53 1495 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
969524fa
ZJS
1496 [LOG_TARGET_KMSG] = "kmsg",
1497 [LOG_TARGET_JOURNAL] = "journal",
1498 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1499 [LOG_TARGET_SYSLOG] = "syslog",
1500 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1501 [LOG_TARGET_AUTO] = "auto",
1502 [LOG_TARGET_NULL] = "null",
34f0e866
LP
1503};
1504
1505DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
4daf54a8
ZJS
1506
1507void log_received_signal(int level, const struct signalfd_siginfo *si) {
a6ab2365
LP
1508 assert(si);
1509
1105f8d2 1510 if (si_code_from_process(si->ssi_code) && pid_is_valid(si->ssi_pid)) {
4daf54a8
ZJS
1511 _cleanup_free_ char *p = NULL;
1512
d7d74854 1513 (void) pid_get_comm(si->ssi_pid, &p);
4daf54a8
ZJS
1514
1515 log_full(level,
1fa2f38f 1516 "Received SIG%s from PID %"PRIu32" (%s).",
4daf54a8
ZJS
1517 signal_to_string(si->ssi_signo),
1518 si->ssi_pid, strna(p));
1519 } else
1520 log_full(level,
1521 "Received SIG%s.",
1522 signal_to_string(si->ssi_signo));
4daf54a8 1523}
c1dc6153 1524
3cc3dc77
MG
1525void set_log_syntax_callback(log_syntax_callback_t cb, void *userdata) {
1526 assert(!log_syntax_callback || !cb);
1527 assert(!log_syntax_callback_userdata || !userdata);
1528
1529 log_syntax_callback = cb;
1530 log_syntax_callback_userdata = userdata;
1531}
1532
158350e8
LP
1533int log_syntax_internal(
1534 const char *unit,
1535 int level,
1536 const char *config_file,
1537 unsigned config_line,
1538 int error,
1539 const char *file,
1540 int line,
1541 const char *func,
1542 const char *format, ...) {
1543
6b7834fe
ZJS
1544 PROTECT_ERRNO;
1545
3cc3dc77
MG
1546 if (log_syntax_callback)
1547 log_syntax_callback(unit, level, log_syntax_callback_userdata);
1548
9fdee66f 1549 if (_likely_(LOG_PRI(level) > log_max_level) ||
52d86690
ZJS
1550 log_target == LOG_TARGET_NULL)
1551 return -ERRNO_VALUE(error);
158350e8 1552
6b7834fe
ZJS
1553 char buffer[LINE_MAX];
1554 va_list ap;
1555 const char *unit_fmt = NULL;
1556
ee96382f 1557 errno = ERRNO_VALUE(error);
158350e8
LP
1558
1559 va_start(ap, format);
4ad2b562 1560 (void) vsnprintf(buffer, sizeof buffer, format, ap);
158350e8
LP
1561 va_end(ap);
1562
1563 if (unit)
df0ff127 1564 unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
c2dec702 1565
bdc34268
ZJS
1566 if (config_file) {
1567 if (config_line > 0)
1568 return log_struct_internal(
9fdee66f 1569 level,
bdc34268
ZJS
1570 error,
1571 file, line, func,
3cf6a3a3
YW
1572 LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION_STR),
1573 LOG_ITEM("CONFIG_FILE=%s", config_file),
1574 LOG_ITEM("CONFIG_LINE=%u", config_line),
bdc34268
ZJS
1575 LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1576 unit_fmt, unit,
1577 NULL);
1578 else
1579 return log_struct_internal(
9fdee66f 1580 level,
bdc34268
ZJS
1581 error,
1582 file, line, func,
3cf6a3a3
YW
1583 LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION_STR),
1584 LOG_ITEM("CONFIG_FILE=%s", config_file),
bdc34268
ZJS
1585 LOG_MESSAGE("%s: %s", config_file, buffer),
1586 unit_fmt, unit,
1587 NULL);
1588 } else if (unit)
6bfb1daf 1589 return log_struct_internal(
9fdee66f 1590 level,
6bfb1daf
ZJS
1591 error,
1592 file, line, func,
3cf6a3a3 1593 LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION_STR),
6bfb1daf
ZJS
1594 LOG_MESSAGE("%s: %s", unit, buffer),
1595 unit_fmt, unit,
1596 NULL);
1597 else
1598 return log_struct_internal(
9fdee66f 1599 level,
6bfb1daf
ZJS
1600 error,
1601 file, line, func,
3cf6a3a3 1602 LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION_STR),
6bfb1daf
ZJS
1603 LOG_MESSAGE("%s", buffer),
1604 NULL);
158350e8 1605}
48a601fe 1606
d04ce5a9
LP
1607int log_syntax_invalid_utf8_internal(
1608 const char *unit,
1609 int level,
1610 const char *config_file,
1611 unsigned config_line,
1612 const char *file,
1613 int line,
1614 const char *func,
1615 const char *rvalue) {
1616
382886fe 1617 PROTECT_ERRNO;
d04ce5a9
LP
1618 _cleanup_free_ char *p = NULL;
1619
1620 if (rvalue)
1621 p = utf8_escape_invalid(rvalue);
1622
07b3075f
ZJS
1623 return log_syntax_internal(unit, level, config_file, config_line,
1624 SYNTHETIC_ERRNO(EINVAL), file, line, func,
1625 "String is not UTF-8 clean, ignoring assignment: %s", strna(p));
d04ce5a9
LP
1626}
1627
1e04eb00
YW
1628int log_syntax_parse_error_internal(
1629 const char *unit,
1630 const char *config_file,
1631 unsigned config_line,
1632 int error,
1633 bool critical,
1634 const char *file,
1635 int line,
1636 const char *func,
1637 const char *lvalue,
1638 const char *rvalue) {
1639
1640 PROTECT_ERRNO;
1641 _cleanup_free_ char *escaped = NULL;
1642
1643 /* OOM is always handled as critical. */
1644 if (ERRNO_VALUE(error) == ENOMEM)
1645 return log_oom_internal(LOG_ERR, file, line, func);
1646
1647 if (rvalue && !utf8_is_valid(rvalue)) {
1648 escaped = utf8_escape_invalid(rvalue);
1649 if (!escaped)
1650 rvalue = "(oom)";
1651 else
1652 rvalue = " (escaped)";
1653 }
1654
1655 log_syntax_internal(unit, critical ? LOG_ERR : LOG_WARNING, config_file, config_line, error,
1656 file, line, func,
1657 "Failed to parse %s=%s%s%s%s%s",
1658 strna(lvalue), strempty(escaped), strempty(rvalue),
1659 critical ? "" : ", ignoring",
1660 error == 0 ? "." : ": ",
1661 error == 0 ? "" : STRERROR(error));
1662
1663 return critical ? -ERRNO_VALUE(error) : 0;
1664}
1665
16e4fd87
LP
1666void log_set_upgrade_syslog_to_journal(bool b) {
1667 upgrade_syslog_to_journal = b;
6fdb8de4
LP
1668
1669 /* Make the change effective immediately */
1670 if (b) {
1671 if (log_target == LOG_TARGET_SYSLOG)
1672 log_target = LOG_TARGET_JOURNAL;
1673 else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG)
1674 log_target = LOG_TARGET_JOURNAL_OR_KMSG;
1675 }
16e4fd87
LP
1676}
1677
48a601fe
LP
1678void log_set_always_reopen_console(bool b) {
1679 always_reopen_console = b;
1680}
16e4fd87
LP
1681
1682void log_set_open_when_needed(bool b) {
1683 open_when_needed = b;
1684}
dccca82b 1685
adf47c91
LP
1686void log_set_prohibit_ipc(bool b) {
1687 prohibit_ipc = b;
1688}
1689
dccca82b
LP
1690int log_emergency_level(void) {
1691 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1692 * then the system of the whole system is obviously affected. */
1693
1694 return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;
1695}
17cac366
LP
1696
1697int log_dup_console(void) {
1698 int copy;
1699
1700 /* Duplicate the fd we use for fd logging if it's < 3 and use the copy from now on. This call is useful
1701 * whenever we want to continue logging through the original fd, but want to rearrange stderr. */
1702
f1ee0668 1703 if (console_fd < 0 || console_fd >= 3)
17cac366
LP
1704 return 0;
1705
1706 copy = fcntl(console_fd, F_DUPFD_CLOEXEC, 3);
1707 if (copy < 0)
1708 return -errno;
1709
1710 console_fd = copy;
1711 return 0;
1712}
6bf3c61c 1713
d2acb93d 1714void log_setup(void) {
13ee9397 1715 log_set_target(LOG_TARGET_AUTO);
74189020 1716 log_parse_environment();
41d1f469 1717 (void) log_open();
13ee9397
YW
1718 if (log_on_console() && show_color < 0)
1719 log_show_color(true);
41d1f469 1720}
7c7a9138 1721
bfd5a068 1722const char* _log_set_prefix(const char *prefix, bool force) {
ee2975a9
DDM
1723 const char *old = log_prefix;
1724
1725 if (prefix || force)
1726 log_prefix = prefix;
1727
1728 return old;
1729}