diff --git a/execute.c b/execute.c index a36e52b34..12f514504 100644 --- a/execute.c +++ b/execute.c @@ -187,10 +187,12 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons dprintf(fd, "%s\n" "%i\n" - "%s\n", + "%s\n" + "%i\n", output == EXEC_OUTPUT_KERNEL ? "kmsg" : "syslog", context->syslog_priority, - context->syslog_identifier ? context->syslog_identifier : ident); + context->syslog_identifier ? context->syslog_identifier : ident, + !context->syslog_no_prefix); if (fd != nfd) { r = dup2(fd, nfd) < 0 ? -errno : nfd; diff --git a/execute.h b/execute.h index 5c2d15787..be73542d4 100644 --- a/execute.h +++ b/execute.h @@ -98,6 +98,7 @@ struct ExecContext { int syslog_priority; char *syslog_identifier; + bool syslog_no_prefix; char *tty_path; diff --git a/load-fragment.c b/load-fragment.c index deebba3e8..148a579d9 100644 --- a/load-fragment.c +++ b/load-fragment.c @@ -1198,6 +1198,7 @@ static int load_from_path(Unit *u, const char *path) { { "SyslogIdentifier", config_parse_string, &(context).syslog_identifier, section }, \ { "SyslogFacility", config_parse_facility, &(context).syslog_priority, section }, \ { "SyslogLevel", config_parse_level, &(context).syslog_priority, section }, \ + { "SyslogNoPrefix", config_parse_bool, &(context).syslog_no_prefix, section }, \ { "Capabilities", config_parse_capabilities, &(context), section }, \ { "SecureBits", config_parse_secure_bits, &(context), section }, \ { "CapabilityBoundingSetDrop", config_parse_bounding_set, &(context), section }, \ diff --git a/logger.c b/logger.c index b7c8ab850..f81d2c5c8 100644 --- a/logger.c +++ b/logger.c @@ -55,10 +55,16 @@ typedef struct Server { unsigned n_streams; } Server; +typedef enum StreamTarget { + STREAM_SYSLOG, + STREAM_KMSG +} StreamTarget; + typedef enum StreamState { - STREAM_LOG_TARGET, + STREAM_TARGET, STREAM_PRIORITY, STREAM_PROCESS, + STREAM_PREFIX, STREAM_RUNNING } StreamState; @@ -75,6 +81,8 @@ struct Stream { pid_t pid; uid_t uid; + bool prefix; + char buffer[STREAM_BUFFER]; size_t length; @@ -85,10 +93,24 @@ static int stream_log(Stream *s, char *p, usec_t timestamp) { char header_priority[16], header_time[64], header_pid[16]; struct iovec iovec[5]; + int priority; assert(s); assert(p); + priority = s->priority; + + if (s->prefix && + p[0] == '<' && + p[1] >= '0' && p[1] <= '7' && + p[2] == '>') { + + /* Detected priority prefix */ + priority = LOG_MAKEPRI(LOG_FAC(priority), (p[1] - '0')); + + p += 3; + } + if (*p == 0) return 0; @@ -105,10 +127,10 @@ static int stream_log(Stream *s, char *p, usec_t timestamp) { */ snprintf(header_priority, sizeof(header_priority), "<%i>", - s->target == LOG_TARGET_SYSLOG ? s->priority : LOG_PRI(s->priority)); + s->target == STREAM_SYSLOG ? priority : LOG_PRI(priority)); char_array_0(header_priority); - if (s->target == LOG_TARGET_SYSLOG) { + if (s->target == STREAM_SYSLOG) { time_t t; struct tm *tm; @@ -126,7 +148,7 @@ static int stream_log(Stream *s, char *p, usec_t timestamp) { zero(iovec); IOVEC_SET_STRING(iovec[0], header_priority); - if (s->target == LOG_TARGET_SYSLOG) { + if (s->target == STREAM_SYSLOG) { struct msghdr msghdr; IOVEC_SET_STRING(iovec[1], header_time); @@ -141,7 +163,7 @@ static int stream_log(Stream *s, char *p, usec_t timestamp) { if (sendmsg(s->server->syslog_fd, &msghdr, MSG_NOSIGNAL) < 0) return -errno; - } else if (s->target == LOG_TARGET_KMSG) { + } else if (s->target == STREAM_KMSG) { IOVEC_SET_STRING(iovec[1], s->process); IOVEC_SET_STRING(iovec[2], header_pid); IOVEC_SET_STRING(iovec[3], p); @@ -165,13 +187,13 @@ static int stream_line(Stream *s, char *p, usec_t timestamp) { switch (s->state) { - case STREAM_LOG_TARGET: + case STREAM_TARGET: if (streq(p, "syslog")) - s->target = LOG_TARGET_SYSLOG; + s->target = STREAM_SYSLOG; else if (streq(p, "kmsg")) { if (s->server->kmsg_fd >= 0 && s->uid == 0) - s->target = LOG_TARGET_KMSG; + s->target = STREAM_KMSG; else { log_warning("/dev/kmsg logging not available."); return -EPERM; @@ -201,6 +223,15 @@ static int stream_line(Stream *s, char *p, usec_t timestamp) { if (!(s->process = strdup(p))) return -ENOMEM; + s->state = STREAM_PREFIX; + return 0; + + case STREAM_PREFIX: + + if ((r = parse_boolean(p)) < 0) + return r; + + s->prefix = r; s->state = STREAM_RUNNING; return 0;