diff --git a/src/lib/core/say.c b/src/lib/core/say.c index c6c1a69ff8afa79c90be80995a1e0163f42a49de..17bcfeb7b9239bc9ec818b6a02cdaf0757743736 100644 --- a/src/lib/core/say.c +++ b/src/lib/core/say.c @@ -83,10 +83,6 @@ static int say_format_boot(struct log *log, char *buf, int len, int level, const char *filename, int line, const char *error, const char *format, va_list ap); -static int -say_format_syslog(struct log *log, char *buf, int len, int level, - const char *filename, int line, const char *error, - const char *format, va_list ap); /** Default logger used before logging subsystem is initialized. */ static struct log log_boot = { @@ -406,7 +402,6 @@ log_pipe_init(struct log *log, const char *init_str) char args[] = { "-c" }; char *argv[] = { cmd, args, (char *) init_str, NULL }; log->type = SAY_LOGGER_PIPE; - log->format_func = say_format_plain; sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); @@ -489,7 +484,6 @@ log_file_init(struct log *log, const char *init_str) int fd; log->path = abspath(init_str); log->type = SAY_LOGGER_FILE; - log->format_func = say_format_plain; if (log->path == NULL) { diag_set(OutOfMemory, strlen(init_str), "malloc", "abspath"); return -1; @@ -619,8 +613,6 @@ log_syslog_init(struct log *log, const char *init_str) { struct say_syslog_opts opts; log->type = SAY_LOGGER_SYSLOG; - /* syslog supports only one formatting function */ - log->format_func = say_format_syslog; if (say_parse_syslog_opts(init_str, &opts) < 0) return -1; @@ -668,7 +660,7 @@ log_create(struct log *log, const char *init_str, int nonblock) log->pid = 0; log->syslog_ident = NULL; log->path = NULL; - log->format_func = NULL; + log->format_func = say_format_plain; log->level = S_INFO; log->rotating_threads = 0; log->on_log = NULL; @@ -812,18 +804,35 @@ say_format_boot(struct log *log, char *buf, int len, int level, const char *file } /** - * The common helper for say_format_plain() and say_format_syslog() + * Format the log message in Tarantool format: + * YYYY-MM-DD hh:mm:ss.ms [PID]: CORD/FID/FIBERNAME LEVEL> MSG */ -static int -say_format_plain_tail(char *buf, int len, int level, const char *filename, - int line, const char *error, const char *format, - va_list ap) +int +say_format_plain(struct log *log, char *buf, int len, int level, + const char *filename, int line, const char *error, + const char *format, va_list ap) { int total = 0; + /* + * Every message written to syslog has a header that contains + * the current time and pid (see format_syslog_header) so we + * exclude them from the message body. + */ + if (log->type != SAY_LOGGER_SYSLOG) { + struct tm tm; + double tm_sec; + get_current_time(&tm, &tm_sec); + /* Print time in format 2012-08-07 18:30:00.634 */ + SNPRINT(total, strftime, buf, len, "%F %H:%M", &tm); + SNPRINT(total, snprintf, buf, len, ":%06.3f ", tm_sec); + /* Print pid */ + SNPRINT(total, snprintf, buf, len, "[%i] ", getpid()); + } + struct cord *cord = cord(); if (cord) { - SNPRINT(total, snprintf, buf, len, " %s", cord->name); + SNPRINT(total, snprintf, buf, len, "%s", cord->name); if (fiber() && fiber()->fid != FIBER_ID_SCHED) { SNPRINT(total, snprintf, buf, len, "/%llu/%s", (long long)fiber()->fid, @@ -852,34 +861,6 @@ say_format_plain_tail(char *buf, int len, int level, const char *filename, return total; } -/** - * Format the log message in Tarantool format: - * YYYY-MM-DD hh:mm:ss.ms [PID]: CORD/FID/FIBERNAME LEVEL> MSG - */ -int -say_format_plain(struct log *log, char *buf, int len, int level, const char *filename, int line, - const char *error, const char *format, va_list ap) -{ - (void) log; - struct tm tm; - double tm_sec; - get_current_time(&tm, &tm_sec); - - /* Print time in format 2012-08-07 18:30:00.634 */ - int total = strftime(buf, len, "%F %H:%M", &tm); - buf += total, len -= total; - SNPRINT(total, snprintf, buf, len, ":%06.3f", tm_sec); - - /* Print pid */ - SNPRINT(total, snprintf, buf, len, " [%i]", getpid()); - - /* Print remaining parts */ - SNPRINT(total, say_format_plain_tail, buf, len, level, filename, line, - error, format, ap); - - return total; -} - /** * Format log message in json format: * {"time": 1507026445.23232, "level": "WARN", "message": <message>, @@ -965,8 +946,18 @@ say_format_json(struct log *log, char *buf, int len, int level, const char *file return total; } +/** Wrapper around log->format_func to be used with SNPRINT. */ +static int +format_log_entry(char *buf, int len, struct log *log, int level, + const char *filename, int line, const char *error, + const char *format, va_list ap) +{ + return log->format_func(log, buf, len, level, filename, line, error, + format, ap); +} + /** - * Format the log message in syslog format. + * Format the header of a log message in syslog format. * * See RFC 5424 and RFC 3164. RFC 3164 is compatible with RFC 5424, * so it is implemented. @@ -979,8 +970,8 @@ say_format_json(struct log *log, char *buf, int len, int level, const char *file * - Identation is application name. By default it is "tarantool"; */ static int -say_format_syslog(struct log *log, char *buf, int len, int level, const char *filename, - int line, const char *error, const char *format, va_list ap) +format_syslog_header(char *buf, int len, int level, + enum syslog_facility facility, const char *ident) { struct tm tm; double tm_sec; @@ -994,13 +985,10 @@ say_format_syslog(struct log *log, char *buf, int len, int level, const char *fi #define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri)) #endif SNPRINT(total, snprintf, buf, len, "<%d>", - LOG_MAKEPRI(8 * log->syslog_facility, prio)); + LOG_MAKEPRI(8 * facility, prio)); SNPRINT(total, strftime, buf, len, "%h %e %T ", &tm); - SNPRINT(total, snprintf, buf, len, "%s[%d]:", log->syslog_ident, getpid()); - - /* Format message */ - SNPRINT(total, say_format_plain_tail, buf, len, level, filename, line, - error, format, ap); + SNPRINT(total, snprintf, buf, len, "%s[%d]: ", ident, + getpid()); return total; } @@ -1273,8 +1261,15 @@ log_vsay(struct log *log, int level, const char *filename, int line, if (level > log->level) { return 0; } - int total = log->format_func(log, say_buf, sizeof(say_buf), level, - filename, line, error, format, ap); + char *buf = say_buf; + int len = SAY_BUF_LEN_MAX; + int total = 0; + if (log->type == SAY_LOGGER_SYSLOG) { + SNPRINT(total, format_syslog_header, buf, len, + level, log->syslog_facility, log->syslog_ident); + } + SNPRINT(total, format_log_entry, buf, len, log, level, filename, line, + error, format, ap); switch (log->type) { case SAY_LOGGER_FILE: case SAY_LOGGER_PIPE: