summaryrefslogtreecommitdiff
path: root/src/journal
diff options
context:
space:
mode:
authorSebastian Thorarensen <sebth@naju.se>2014-03-14 00:38:15 +0100
committerLennart Poettering <lennart@poettering.net>2014-03-14 22:05:25 +0100
commit40b71e89bae4e51768db4dc50ec64c1e9c96eec4 (patch)
tree39de34bcee5d996a8e98ef792fc7201276b0cf63 /src/journal
parent9003d9b0d628be059922e522fd35f9c5b4d8b039 (diff)
journald: add support for wall forwarding
This will let journald forward logs as messages sent to all logged in users (like wall). Two options are added: * ForwardToWall (default yes) * MaxLevelWall (default emerg) 'ForwardToWall' is overridable by kernel command line option 'systemd.journald.forward_to_wall'. This is used to emulate the traditional syslogd behaviour of sending emergency messages to all logged in users.
Diffstat (limited to 'src/journal')
-rw-r--r--src/journal/journald-gperf.gperf2
-rw-r--r--src/journal/journald-native.c4
-rw-r--r--src/journal/journald-server.c8
-rw-r--r--src/journal/journald-server.h2
-rw-r--r--src/journal/journald-stream.c4
-rw-r--r--src/journal/journald-syslog.c4
-rw-r--r--src/journal/journald-wall.c69
-rw-r--r--src/journal/journald-wall.h26
-rw-r--r--src/journal/journald.conf2
9 files changed, 121 insertions, 0 deletions
diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf
index 83bbbc8d2..74554c1c3 100644
--- a/src/journal/journald-gperf.gperf
+++ b/src/journal/journald-gperf.gperf
@@ -32,9 +32,11 @@ Journal.MaxFileSec, config_parse_sec, 0, offsetof(Server, max_fil
Journal.ForwardToSyslog, config_parse_bool, 0, offsetof(Server, forward_to_syslog)
Journal.ForwardToKMsg, config_parse_bool, 0, offsetof(Server, forward_to_kmsg)
Journal.ForwardToConsole, config_parse_bool, 0, offsetof(Server, forward_to_console)
+Journal.ForwardToWall, config_parse_bool, 0, offsetof(Server, forward_to_wall)
Journal.TTYPath, config_parse_path, 0, offsetof(Server, tty_path)
Journal.MaxLevelStore, config_parse_log_level, 0, offsetof(Server, max_level_store)
Journal.MaxLevelSyslog, config_parse_log_level, 0, offsetof(Server, max_level_syslog)
Journal.MaxLevelKMsg, config_parse_log_level, 0, offsetof(Server, max_level_kmsg)
Journal.MaxLevelConsole, config_parse_log_level, 0, offsetof(Server, max_level_console)
+Journal.MaxLevelWall, config_parse_log_level, 0, offsetof(Server, max_level_wall)
Journal.SplitMode, config_parse_split_mode, 0, offsetof(Server, split_mode)
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 359d962c7..0509c1eae 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -31,6 +31,7 @@
#include "journald-kmsg.h"
#include "journald-console.h"
#include "journald-syslog.h"
+#include "journald-wall.h"
/* Make sure not to make this smaller than the maximum coredump
* size. See COREDUMP_MAX in coredump.c */
@@ -265,6 +266,9 @@ void server_process_native_message(
if (s->forward_to_console)
server_forward_console(s, priority, identifier, message, ucred);
+
+ if (s->forward_to_wall)
+ server_forward_wall(s, priority, identifier, message, ucred);
}
server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 868065075..f0117e742 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1319,6 +1319,12 @@ static int server_parse_proc_cmdline(Server *s) {
log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36);
else
s->forward_to_console = r;
+ } else if (startswith(word, "systemd.journald.forward_to_wall=")) {
+ r = parse_boolean(word + 33);
+ if (r < 0)
+ log_warning("Failed to parse forward to wall switch %s. Ignoring.", word + 33);
+ else
+ s->forward_to_wall = r;
} else if (startswith(word, "systemd.journald"))
log_warning("Invalid systemd.journald parameter. Ignoring.");
}
@@ -1466,11 +1472,13 @@ int server_init(Server *s) {
s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
s->forward_to_syslog = true;
+ s->forward_to_wall = true;
s->max_level_store = LOG_DEBUG;
s->max_level_syslog = LOG_DEBUG;
s->max_level_kmsg = LOG_NOTICE;
s->max_level_console = LOG_INFO;
+ s->max_level_wall = LOG_EMERG;
memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics));
memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics));
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index 2a81061f2..e468b8293 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -97,6 +97,7 @@ typedef struct Server {
bool forward_to_kmsg;
bool forward_to_syslog;
bool forward_to_console;
+ bool forward_to_wall;
unsigned n_forward_syslog_missed;
usec_t last_warn_forward_syslog_missed;
@@ -119,6 +120,7 @@ typedef struct Server {
int max_level_syslog;
int max_level_kmsg;
int max_level_console;
+ int max_level_wall;
Storage storage;
SplitMode split_mode;
diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
index 36fc75526..c46ffe5d4 100644
--- a/src/journal/journald-stream.c
+++ b/src/journal/journald-stream.c
@@ -35,6 +35,7 @@
#include "journald-syslog.h"
#include "journald-kmsg.h"
#include "journald-console.h"
+#include "journald-wall.h"
#define STDOUT_STREAMS_MAX 4096
@@ -106,6 +107,9 @@ static int stdout_stream_log(StdoutStream *s, const char *p) {
if (s->forward_to_console || s->server->forward_to_console)
server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
+ if (s->server->forward_to_wall)
+ server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);
+
IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 241f7edb6..cbb944f28 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -30,6 +30,7 @@
#include "journald-syslog.h"
#include "journald-kmsg.h"
#include "journald-console.h"
+#include "journald-wall.h"
/* Warn once every 30s if we missed syslog message */
#define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC)
@@ -380,6 +381,9 @@ void server_process_syslog_message(
if (s->forward_to_console)
server_forward_console(s, priority, identifier, buf, ucred);
+ if (s->forward_to_wall)
+ server_forward_wall(s, priority, identifier, buf, ucred);
+
IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog");
if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
diff --git a/src/journal/journald-wall.c b/src/journal/journald-wall.c
new file mode 100644
index 000000000..fcbd9183f
--- /dev/null
+++ b/src/journal/journald-wall.c
@@ -0,0 +1,69 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Sebastian Thorarensen
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "utmp-wtmp.h"
+#include "journald-server.h"
+#include "journald-wall.h"
+
+void server_forward_wall(
+ Server *s,
+ int priority,
+ const char *identifier,
+ const char *message,
+ struct ucred *ucred) {
+
+ _cleanup_free_ char *ident_buf = NULL, *l_buf = NULL;
+ const char *l;
+ int r;
+
+ assert(s);
+ assert(message);
+
+ if (LOG_PRI(priority) > s->max_level_wall)
+ return;
+
+ if (ucred) {
+ if (!identifier) {
+ get_process_comm(ucred->pid, &ident_buf);
+ identifier = ident_buf;
+ }
+
+ if (asprintf(&l_buf, "%s["PID_FMT"]: %s", strempty(identifier), ucred->pid, message) < 0) {
+ log_oom();
+ return;
+ }
+
+ l = l_buf;
+
+ } else if (identifier) {
+
+ l = l_buf = strjoin(identifier, ": ", message, NULL);
+ if (!l_buf) {
+ log_oom();
+ return;
+ }
+ } else
+ l = message;
+
+ r = utmp_wall(l, "systemd-journald", NULL);
+ if (r < 0)
+ log_debug("Failed to send wall message: %s", strerror(-r));
+}
diff --git a/src/journal/journald-wall.h b/src/journal/journald-wall.h
new file mode 100644
index 000000000..93c3cec1d
--- /dev/null
+++ b/src/journal/journald-wall.h
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Sebastian Thorarensen
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journald-server.h"
+
+void server_forward_wall(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred);
diff --git a/src/journal/journald.conf b/src/journal/journald.conf
index 54f6833a1..d106d00b5 100644
--- a/src/journal/journald.conf
+++ b/src/journal/journald.conf
@@ -26,8 +26,10 @@
#ForwardToSyslog=yes
#ForwardToKMsg=no
#ForwardToConsole=no
+#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
+#MaxLevelWall=emerg