diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index c079274c32..aeb5367d24 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -112,7 +112,22 @@ see program_invocation_short_name3.) + + + SYSLOG_RAW= + + The original contents of the syslog line as received in the syslog + datagram. This field is only included if the MESSAGE= + field was modified compared to the original payload. This happens when the + message contains leading or trailing whitespace (trailing and leading + whitespace is stripped), or it contains an embedded + NUL byte (the NUL byte and + anything after it is not included). Thus, the original syslog line is + either stored as SYSLOG_RAW= or it can be recreated + based on the stored priority, timestamp, hostname, and the message payload + stored in MESSAGE=. + diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c index ea50bd766a..e2794ec30f 100644 --- a/src/journal/journald-syslog.c +++ b/src/journal/journald-syslog.c @@ -311,6 +311,7 @@ void server_process_syslog_message( ClientContext *context = NULL; struct iovec *iovec; size_t n = 0, m, i, leading_ws; + bool store_raw; assert(s); assert(buf); @@ -345,6 +346,10 @@ void server_process_syslog_message( t[i - leading_ws] = 0; } + /* We will add the SYSLOG_RAW= field when we stripped anything + * _or_ if the input message contained NUL bytes. */ + store_raw = msg != buf || strlen(msg) != raw_len; + syslog_parse_priority(&msg, &priority, true); if (!client_context_test_priority(context, priority)) @@ -365,7 +370,7 @@ void server_process_syslog_message( if (s->forward_to_wall) server_forward_wall(s, priority, identifier, msg, ucred); - m = N_IOVEC_META_FIELDS + 6 + client_context_extra_fields_n_iovec(context); + m = N_IOVEC_META_FIELDS + 7 + client_context_extra_fields_n_iovec(context); iovec = newa(struct iovec, m); iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=syslog"); @@ -389,8 +394,18 @@ void server_process_syslog_message( } message = strjoina("MESSAGE=", msg); - if (message) - iovec[n++] = IOVEC_MAKE_STRING(message); + iovec[n++] = IOVEC_MAKE_STRING(message); + + if (store_raw) { + const size_t hlen = strlen("SYSLOG_RAW="); + char *t; + + t = newa(char, hlen + raw_len); + memcpy(t, "SYSLOG_RAW=", hlen); + memcpy(t + hlen, buf, raw_len); + + iovec[n++] = IOVEC_MAKE(t, hlen + raw_len); + } server_dispatch_message(s, iovec, n, m, context, tv, priority, 0); }