From: Timo Sirainen Date: Fri, 31 Aug 2018 12:01:38 +0000 (+0300) Subject: lib, log: Add log prefix length to internal logging protocol X-Git-Tag: 2.3.9~1468 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fcd9bcd9fd74a574fab9b5c7add537b703caaddd;p=thirdparty%2Fdovecot%2Fcore.git lib, log: Add log prefix length to internal logging protocol This way log process knows which part of the text is the log prefix, and which part is the logged text. --- diff --git a/src/lib/failures.c b/src/lib/failures.c index a5381e2fca..bc4841839b 100644 --- a/src/lib/failures.c +++ b/src/lib/failures.c @@ -18,6 +18,7 @@ #include #include +#define LOG_TYPE_FLAG_PREFIX_LEN 0x40 #define LOG_TYPE_FLAG_DISABLE_LOG_PREFIX 0x80 const char *failure_log_type_prefixes[LOG_TYPE_COUNT] = { @@ -765,12 +766,12 @@ static int internal_send_split(string_t *full_str, size_t prefix_len) static bool line_parse_prefix(const char *line, enum log_type *log_type_r, - bool *replace_prefix_r) + bool *replace_prefix_r, bool *have_prefix_len_r) { if (*line != 1) return FALSE; - unsigned char log_type = (line[1] & 0x7f); + unsigned char log_type = (line[1] & 0x3f); if (log_type == '\0') { i_warning("Broken log line follows (type=NUL)"); return FALSE; @@ -783,15 +784,18 @@ static bool line_parse_prefix(const char *line, enum log_type *log_type_r, } *log_type_r = log_type; *replace_prefix_r = (line[1] & LOG_TYPE_FLAG_DISABLE_LOG_PREFIX) != 0; + *have_prefix_len_r = (line[1] & LOG_TYPE_FLAG_PREFIX_LEN) != 0; return TRUE; } void i_failure_parse_line(const char *line, struct failure_line *failure) { + bool have_prefix_len = FALSE; i_zero(failure); if (!line_parse_prefix(line, &failure->log_type, - &failure->disable_log_prefix)) { + &failure->disable_log_prefix, + &have_prefix_len)) { failure->log_type = LOG_TYPE_ERROR; failure->text = line; return; @@ -808,7 +812,21 @@ void i_failure_parse_line(const char *line, struct failure_line *failure) failure->pid = 0; return; } - failure->text = line + 1; + line++; + + if (have_prefix_len) { + if (str_parse_uint(line, &failure->log_prefix_len, &line) < 0 || + line[0] != ' ') { + /* unexpected, but ignore */ + } else { + line++; + if (failure->log_prefix_len > strlen(line)) { + /* invalid */ + failure->log_prefix_len = 0; + } + } + } + failure->text = line; } static void ATTR_NORETURN ATTR_FORMAT(2, 0) diff --git a/src/lib/failures.h b/src/lib/failures.h index bcc369ead2..7e163668fd 100644 --- a/src/lib/failures.h +++ b/src/lib/failures.h @@ -29,6 +29,10 @@ enum log_type { struct failure_line { pid_t pid; enum log_type log_type; + /* If non-zero, the first log_prefix_len bytes in text indicate + the log prefix. This implies disable_log_prefix=TRUE. */ + unsigned int log_prefix_len; + /* Disable the global log prefix. */ bool disable_log_prefix; const char *text; }; diff --git a/src/log/log-connection.c b/src/log/log-connection.c index fa460e5a27..3d8ed93553 100644 --- a/src/log/log-connection.c +++ b/src/log/log-connection.c @@ -243,7 +243,7 @@ log_it(struct log_connection *log, const char *line, struct failure_line failure; struct failure_context failure_ctx; struct log_client *client = NULL; - const char *prefix; + const char *prefix = ""; if (log->master) { log_parse_master_line(line, log_time, tm); @@ -274,11 +274,16 @@ log_it(struct log_connection *log, const char *line, failure_ctx.type = failure.log_type; failure_ctx.timestamp = tm; failure_ctx.timestamp_usecs = log_time->tv_usec; - if (failure.disable_log_prefix) + if (failure.log_prefix_len != 0) { + failure_ctx.log_prefix = + t_strndup(failure.text, failure.log_prefix_len); + failure.text += failure.log_prefix_len; + } else if (failure.disable_log_prefix) { failure_ctx.log_prefix = ""; - - prefix = client != NULL && client->prefix != NULL ? - client->prefix : log->default_prefix; + } else { + prefix = client != NULL && client->prefix != NULL ? + client->prefix : log->default_prefix; + } client_log_ctx(log, &failure_ctx, log_time, prefix, failure.text); }