]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/journald-console.c
journalctl: clean up how we log errors
[thirdparty/systemd.git] / src / journal / journald-console.c
CommitLineData
3b7124a8
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7
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.
12
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.
17
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/>.
20***/
21
ad79565d 22#include <time.h>
3b7124a8 23#include <fcntl.h>
4871690d 24#include <sys/socket.h>
3b7124a8 25
ad79565d 26#include "fileio.h"
d025f1e4 27#include "journald-server.h"
3b7124a8 28#include "journald-console.h"
6482f626 29#include "formats-util.h"
0b452006 30#include "process-util.h"
288a74cc 31#include "terminal-util.h"
3b7124a8 32
ad79565d
UTL
33static bool prefix_timestamp(void) {
34
35 static int cached_printk_time = -1;
36
37 if (_unlikely_(cached_printk_time < 0)) {
38 _cleanup_free_ char *p = NULL;
39
40 cached_printk_time =
41 read_one_line_file("/sys/module/printk/parameters/time", &p) >= 0
42 && parse_boolean(p) > 0;
43 }
44
45 return cached_printk_time;
46}
47
3b7124a8
LP
48void server_forward_console(
49 Server *s,
50 int priority,
51 const char *identifier,
52 const char *message,
3b3154df 53 const struct ucred *ucred) {
3b7124a8 54
ad79565d 55 struct iovec iovec[5];
ad79565d 56 struct timespec ts;
5ffa8c81
ZJS
57 char tbuf[sizeof("[] ")-1 + DECIMAL_STR_MAX(ts.tv_sec) + DECIMAL_STR_MAX(ts.tv_nsec)-3 + 1];
58 char header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t)];
3b7124a8 59 int n = 0, fd;
fb472900 60 _cleanup_free_ char *ident_buf = NULL;
3b7124a8
LP
61 const char *tty;
62
63 assert(s);
64 assert(message);
65
66 if (LOG_PRI(priority) > s->max_level_console)
67 return;
68
ad79565d
UTL
69 /* First: timestamp */
70 if (prefix_timestamp()) {
71 assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
5ffa8c81 72 xsprintf(tbuf, "[%5"PRI_TIME".%06ld] ",
de0671ee
ZJS
73 ts.tv_sec,
74 ts.tv_nsec / 1000);
ad79565d
UTL
75 IOVEC_SET_STRING(iovec[n++], tbuf);
76 }
77
78 /* Second: identifier and PID */
3b7124a8
LP
79 if (ucred) {
80 if (!identifier) {
81 get_process_comm(ucred->pid, &ident_buf);
82 identifier = ident_buf;
83 }
84
5ffa8c81 85 xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid);
3b7124a8
LP
86
87 if (identifier)
88 IOVEC_SET_STRING(iovec[n++], identifier);
89
90 IOVEC_SET_STRING(iovec[n++], header_pid);
91 } else if (identifier) {
92 IOVEC_SET_STRING(iovec[n++], identifier);
93 IOVEC_SET_STRING(iovec[n++], ": ");
94 }
95
ad79565d 96 /* Fourth: message */
3b7124a8
LP
97 IOVEC_SET_STRING(iovec[n++], message);
98 IOVEC_SET_STRING(iovec[n++], "\n");
99
100 tty = s->tty_path ? s->tty_path : "/dev/console";
101
102 fd = open_terminal(tty, O_WRONLY|O_NOCTTY|O_CLOEXEC);
103 if (fd < 0) {
56f64d95 104 log_debug_errno(errno, "Failed to open %s for logging: %m", tty);
fb472900 105 return;
3b7124a8
LP
106 }
107
108 if (writev(fd, iovec, n) < 0)
56f64d95 109 log_debug_errno(errno, "Failed to write to %s for logging: %m", tty);
3b7124a8 110
03e334a1 111 safe_close(fd);
3b7124a8 112}