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.
This commit is contained in:
Sebastian Thorarensen 2014-03-14 00:38:15 +01:00 committed by Lennart Poettering
parent 9003d9b0d6
commit 40b71e89ba
13 changed files with 151 additions and 18 deletions

View File

@ -3247,6 +3247,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 \

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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));
}

View File

@ -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);

View File

@ -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