From 99978b9ad2157e66e857b4dc08b98dff47b43343 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Apr 2013 10:19:57 -0500 Subject: core: rework logging code to remove log message truncation (bgo #698312) Use a static GString which will resize itself if the log message is bigger than the current string size, but will also ensure we don't do a ton of memory reallocation on every log message. Previously all log messages were trucated at 512 bytes due to the log buffer char array being 512 bytes long. --- src/mm-log.c | 71 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/src/mm-log.c b/src/mm-log.c index 5e02ff9b..92e16c2c 100644 --- a/src/mm-log.c +++ b/src/mm-log.c @@ -50,6 +50,9 @@ static const LogDesc level_descs[] = { { 0, NULL } }; +static GString *msgbuf = NULL; +static volatile gsize msgbuf_once = 0; + void _mm_log (const char *loc, const char *func, @@ -58,24 +61,35 @@ _mm_log (const char *loc, ...) { va_list args; - char *msg; GTimeVal tv; - char tsbuf[100] = { 0 }; - char msgbuf[512] = { 0 }; int syslog_priority = LOG_INFO; - const char *prefix = NULL; ssize_t ign; if (!(log_level & level)) return; - va_start (args, fmt); - msg = g_strdup_vprintf (fmt, args); - va_end (args); + if (g_once_init_enter (&msgbuf_once)) { + msgbuf = g_string_sized_new (512); + g_once_init_leave (&msgbuf_once, 1); + } else + g_string_truncate (msgbuf, 0); + + if ((log_level & LOGL_DEBUG) && (level == LOGL_DEBUG)) + g_string_append (msgbuf, " "); + else if ((log_level & LOGL_INFO) && (level == LOGL_INFO)) + g_string_append (msgbuf, " "); + else if ((log_level & LOGL_WARN) && (level == LOGL_WARN)) { + g_string_append (msgbuf, " "); + syslog_priority = LOG_WARNING; + } else if ((log_level & LOGL_ERR) && (level == LOGL_ERR)) { + g_string_append (msgbuf, " "); + syslog_priority = LOG_ERR; + } else + return; if (ts_flags == TS_FLAG_WALL) { g_get_current_time (&tv); - snprintf (&tsbuf[0], sizeof (tsbuf), " [%09ld.%06ld]", tv.tv_sec, tv.tv_usec); + g_string_append_printf (msgbuf, "[%09ld.%06ld] ", tv.tv_sec, tv.tv_usec); } else if (ts_flags == TS_FLAG_REL) { glong secs; glong usecs; @@ -88,39 +102,26 @@ _mm_log (const char *loc, usecs += 1000000; } - snprintf (&tsbuf[0], sizeof (tsbuf), " [%06ld.%06ld]", secs, usecs); + g_string_append_printf (msgbuf, "[%06ld.%06ld] ", secs, usecs); } - if ((log_level & LOGL_DEBUG) && (level == LOGL_DEBUG)) - prefix = ""; - else if ((log_level & LOGL_INFO) && (level == LOGL_INFO)) - prefix = " "; - else if ((log_level & LOGL_WARN) && (level == LOGL_WARN)) { - prefix = " "; - syslog_priority = LOG_WARNING; - } else if ((log_level & LOGL_ERR) && (level == LOGL_ERR)) { - prefix = ""; - syslog_priority = LOG_ERR; - } else - g_warn_if_reached (); + if (log_level & LOGL_DEBUG) + g_string_append_printf (msgbuf, "[%s] %s(): ", loc, func); + + va_start (args, fmt); + g_string_append_vprintf (msgbuf, fmt, args); + va_end (args); - if (prefix) { - if (log_level & LOGL_DEBUG) - snprintf (msgbuf, sizeof (msgbuf), "%s%s [%s] %s(): %s\n", prefix, tsbuf, loc, func, msg); - else - snprintf (msgbuf, sizeof (msgbuf), "%s%s %s\n", prefix, tsbuf, msg); + g_string_append_c (msgbuf, '\n'); - if (logfd < 0) - syslog (syslog_priority, "%s", msgbuf); - else { - ign = write (logfd, msgbuf, strlen (msgbuf)); - if (ign) {} /* whatever; really shut up about unused result */ + if (logfd < 0) + syslog (syslog_priority, "%s", msgbuf->str); + else { + ign = write (logfd, msgbuf->str, msgbuf->len); + if (ign) {} /* whatever; really shut up about unused result */ - fsync (logfd); /* Make sure output is dumped to disk immediately */ - } + fsync (logfd); /* Make sure output is dumped to disk immediately */ } - - g_free (msg); } static void -- cgit v1.2.3