[systemd-devel] [RFC][PATCH v3 2/2] journald: add support for wall forwarding
Sebastian Thorarensen
sebth at naju.se
Thu Mar 13 16:38:15 PDT 2014
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.
---
Makefile.am | 2 ++
man/journald.conf.xml | 40 ++++++++++++++---------
man/kernel-command-line.xml | 1 +
man/systemd-journald.service.xml | 5 +--
src/journal/journald-gperf.gperf | 2 ++
src/journal/journald-native.c | 4 +++
src/journal/journald-server.c | 8 +++++
src/journal/journald-server.h | 2 ++
src/journal/journald-stream.c | 4 +++
src/journal/journald-syslog.c | 4 +++
src/journal/journald-wall.c | 67 ++++++++++++++++++++++++++++++++++++++
src/journal/journald-wall.h | 26 +++++++++++++++
src/journal/journald.conf | 2 ++
13 files changed, 149 insertions(+), 18 deletions(-)
create mode 100644 src/journal/journald-wall.c
create mode 100644 src/journal/journald-wall.h
diff --git a/Makefile.am b/Makefile.am
index 2e4f857..48a3526 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3236,6 +3236,8 @@ libsystemd_journal_core_la_SOURCES = \
src/journal/journald-server.h \
src/journal/journald-console.c \
src/journal/journald-console.h \
+ src/journal/journald-wall.c \
+ src/journal/journald-wall.h \
src/journal/journald-native.c \
src/journal/journald-native.h \
src/journal/journald-rate-limit.c \
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
index a814ec1..239a2ec 100644
--- a/man/journald.conf.xml
+++ b/man/journald.conf.xml
@@ -381,24 +381,28 @@
<term><varname>ForwardToSyslog=</varname></term>
<term><varname>ForwardToKMsg=</varname></term>
<term><varname>ForwardToConsole=</varname></term>
+ <term><varname>ForwardToWall=</varname></term>
<listitem><para>Control whether log
messages received by the journal
daemon shall be forwarded to a
traditional syslog daemon, to the
- kernel log buffer (kmsg), or to the
- system console. These options take
- boolean arguments. If forwarding to
- syslog is enabled but no syslog daemon
- is running, the respective option has
- no effect. By default, only forwarding
- to syslog is enabled. These settings
- may be overridden at boot time with
- the kernel command line options
+ kernel log buffer (kmsg), to the
+ system console, or sent as wall
+ messages to all logged-in users. These
+ options take boolean arguments. If
+ forwarding to syslog is enabled but no
+ syslog daemon is running, the
+ respective option has no effect. By
+ default, only forwarding to syslog and
+ wall is enabled. These settings may be
+ overridden at boot time with the
+ kernel command line options
<literal>systemd.journald.forward_to_syslog=</literal>,
- <literal>systemd.journald.forward_to_kmsg=</literal>
+ <literal>systemd.journald.forward_to_kmsg=</literal>,
+ <literal>systemd.journald.forward_to_console=</literal>
and
- <literal>systemd.journald.forward_to_console=</literal>.
+ <literal>systemd.journald.forward_to_wall=</literal>.
When forwarding to the console, the
TTY to log to can be changed
with <varname>TTYPath=</varname>,
@@ -410,12 +414,14 @@
<term><varname>MaxLevelSyslog=</varname></term>
<term><varname>MaxLevelKMsg=</varname></term>
<term><varname>MaxLevelConsole=</varname></term>
+ <term><varname>MaxLevelWall=</varname></term>
<listitem><para>Controls the maximum
log level of messages that are stored
- on disk, forwarded to syslog, kmsg or
- the console (if that is enabled, see
- above). As argument, takes one of
+ on disk, forwarded to syslog, kmsg,
+ the console or wall (if that is
+ enabled, see above). As argument,
+ takes one of
<literal>emerg</literal>,
<literal>alert</literal>,
<literal>crit</literal>,
@@ -436,9 +442,11 @@
written to disk and forwarded to
syslog. Defaults to
<literal>notice</literal> for
- <varname>MaxLevelKMsg=</varname> and
+ <varname>MaxLevelKMsg=</varname>,
<literal>info</literal> for
- <varname>MaxLevelConsole=</varname>.</para></listitem>
+ <varname>MaxLevelConsole=</varname> and
+ <literal>emerg</literal> for
+ <varname>MaxLevelWall=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
index afcff7c..dbfec61 100644
--- a/man/kernel-command-line.xml
+++ b/man/kernel-command-line.xml
@@ -207,6 +207,7 @@
<term><varname>systemd.journald.forward_to_syslog=</varname></term>
<term><varname>systemd.journald.forward_to_kmsg=</varname></term>
<term><varname>systemd.journald.forward_to_console=</varname></term>
+ <term><varname>systemd.journald.forward_to_wall=</varname></term>
<listitem>
<para>Parameters understood by
diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml
index 4d2cb40..f0ce7aa 100644
--- a/man/systemd-journald.service.xml
+++ b/man/systemd-journald.service.xml
@@ -142,11 +142,12 @@
<term><varname>systemd.journald.forward_to_syslog=</varname></term>
<term><varname>systemd.journald.forward_to_kmsg=</varname></term>
<term><varname>systemd.journald.forward_to_console=</varname></term>
+ <term><varname>systemd.journald.forward_to_wall=</varname></term>
<listitem><para>Enables/disables
forwarding of collected log messages
- to syslog, the kernel log buffer or
- the system console.
+ to syslog, the kernel log buffer, the
+ system console or wall.
</para>
<para>See
diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf
index 83bbbc8..74554c1 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 359d962..0509c1e 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 8680650..f0117e7 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 2a81061..e468b82 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 36fc755..c46ffe5 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 241f7ed..cbb944f 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 0000000..1c42f49
--- /dev/null
+++ b/src/journal/journald-wall.c
@@ -0,0 +1,67 @@
+/*-*- 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;
+ char *l;
+
+ 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_debug("Failed to allocate wall message: %m");
+ return;
+ }
+
+ l = l_buf;
+ } else if (identifier) {
+ if (asprintf(&l_buf, "%s: %s", identifier, message) < 0) {
+ log_debug("Failed to allocate wall message: %m");
+ return;
+ }
+
+ l = l_buf;
+ } else {
+ l = message;
+ }
+
+ if (utmp_wall(l, "systemd-journald", NULL) < 0)
+ log_debug("Failed to send wall message: %m");
+}
diff --git a/src/journal/journald-wall.h b/src/journal/journald-wall.h
new file mode 100644
index 0000000..93c3cec
--- /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 54f6833..d106d00 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
--
1.7.10.4
More information about the systemd-devel
mailing list