[systemd-devel] [RFC][PATCH 2/2] journald: add support for wall forwarding
Zbigniew Jędrzejewski-Szmek
zbyszek at in.waw.pl
Wed Mar 5 05:50:28 PST 2014
On Wed, Mar 05, 2014 at 01:45:51PM +0100, Sebastian Thorarensen wrote:
> This will let journald forward logs as messages sent to all logged in
> users (like wall).
>
> Two options are added:
> * ForwardToWall (default no)
Is there a good reason not to set it to yes by default?
> * MaxLevelWall (default emerg)
> 'ForwardToWall' is overridable by kernel command line option
> 'systemd.journald.forward_to_wall'.
>
> This can be used to emulate the traditional syslogd behaviour of sending
> emergency messages to all logged in users.
> ---
> Makefile.am | 2 ++
> man/journald.conf.xml | 40 +++++++++++++++-----------
> src/journal/journald-gperf.gperf | 2 ++
> src/journal/journald-native.c | 4 +++
> src/journal/journald-server.c | 7 +++++
> src/journal/journald-server.h | 2 ++
> src/journal/journald-stream.c | 4 +++
> src/journal/journald-syslog.c | 4 +++
> src/journal/journald-wall.c | 59 ++++++++++++++++++++++++++++++++++++++
> src/journal/journald-wall.h | 26 +++++++++++++++++
> src/journal/journald.conf | 2 ++
> 11 files changed, 136 insertions(+), 16 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 f99cef7..02a2fbf 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -3227,6 +3227,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..723d445 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 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/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 2a90b44..2fcb4d7 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.");
> }
> @@ -1471,6 +1477,7 @@ int server_init(Server *s) {
> 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..55a44bd
> --- /dev/null
> +++ b/src/journal/journald-wall.c
> @@ -0,0 +1,59 @@
> +/*-*- 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) {
> +
> + char header_pid[16];
header_pid[DECIMAL_STR_MAX(pid_t) + sizeof("[]"];
> + _cleanup_free_ char *ident_buf = NULL, *l = NULL;
> +
> + 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;
> + }
> +
> + snprintf(header_pid, sizeof(header_pid), "[%lu]", (unsigned long) ucred->pid);
Use "["PID_FMT"]" for the format.
> + char_array_0(header_pid);
Remove this.
> + }
> +
> + if (asprintf(&l, "%s%s: %s", strempty(identifier), strempty(header_pid), message) < 0) {
> + log_debug("Failed to allocate wall message: %m");
> + return;
> + }
> +
> + 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..16ea1f1 100644
> --- a/src/journal/journald.conf
> +++ b/src/journal/journald.conf
> @@ -26,8 +26,10 @@
> #ForwardToSyslog=yes
> #ForwardToKMsg=no
> #ForwardToConsole=no
> +#ForwardToWall=no
> #TTYPath=/dev/console
> #MaxLevelStore=debug
> #MaxLevelSyslog=debug
> #MaxLevelKMsg=notice
> #MaxLevelConsole=info
> +#MaxLevelWall=emerg
Zbyszek
More information about the systemd-devel
mailing list