diff options
| author | Michael Biebl <biebl@debian.org> | 2016-03-01 16:55:22 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-03-01 16:55:22 +0100 |
| commit | c2de0d98ba39e0a1a970d066fd19be786092f376 (patch) | |
| tree | 3838363c06a6019db6cf1f882ea34ebded63c38b /src/nm-logging.c | |
| parent | 494f296a3baab08522617b24b1f126d8f9a17502 (diff) | |
Imported Upstream version 1.1.91 upstream/1.1.91
Diffstat (limited to 'src/nm-logging.c')
| -rw-r--r-- | src/nm-logging.c | 168 |
1 files changed, 132 insertions, 36 deletions
diff --git a/src/nm-logging.c b/src/nm-logging.c index 60ccb5cb..5bb3660f 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -19,7 +19,7 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#include "config.h" +#include "nm-default.h" #include <dlfcn.h> #include <syslog.h> @@ -32,15 +32,50 @@ #include <strings.h> #include <string.h> +#if defined (NO_SYSTEMD_JOURNAL) && defined (SYSTEMD_JOURNAL) +#undef SYSTEMD_JOURNAL +#define SYSTEMD_JOURNAL 0 +#endif + #if SYSTEMD_JOURNAL #define SD_JOURNAL_SUPPRESS_LOCATION #include <systemd/sd-journal.h> #endif -#include "nm-default.h" #include "nm-errors.h" -#include "NetworkManagerUtils.h" -#include "nm-linux-platform.h" +#include "nm-core-utils.h" + +typedef enum { + LOG_FORMAT_FLAG_NONE = 0, + LOG_FORMAT_FLAG_TIMESTAMP_DEBUG = (1LL << 0), + LOG_FORMAT_FLAG_TIMESTAMP_INFO = (1LL << 1), + LOG_FORMAT_FLAG_TIMESTAMP_ERROR = (1LL << 2), + LOG_FORMAT_FLAG_LOCATION_DEBUG = (1LL << 3), + LOG_FORMAT_FLAG_LOCATION_INFO = (1LL << 4), + LOG_FORMAT_FLAG_LOCATION_ERROR = (1LL << 5), + LOG_FORMAT_FLAG_ALIGN_LOCATION = (1LL << 6), + + _LOG_FORMAT_FLAG_TIMESTAMP = LOG_FORMAT_FLAG_TIMESTAMP_DEBUG | + LOG_FORMAT_FLAG_TIMESTAMP_INFO | + LOG_FORMAT_FLAG_TIMESTAMP_ERROR, + _LOG_FORMAT_FLAG_LOCATION = LOG_FORMAT_FLAG_LOCATION_DEBUG | + LOG_FORMAT_FLAG_LOCATION_INFO | + LOG_FORMAT_FLAG_LOCATION_ERROR, + + _LOG_FORMAT_FLAG_LEVEL_DEBUG = LOG_FORMAT_FLAG_TIMESTAMP_DEBUG | + LOG_FORMAT_FLAG_LOCATION_DEBUG, + _LOG_FORMAT_FLAG_LEVEL_INFO = LOG_FORMAT_FLAG_TIMESTAMP_INFO | + LOG_FORMAT_FLAG_LOCATION_INFO, + _LOG_FORMAT_FLAG_LEVEL_ERROR = LOG_FORMAT_FLAG_TIMESTAMP_ERROR | + LOG_FORMAT_FLAG_LOCATION_ERROR, + + _LOG_FORMAT_FLAG_SYSLOG = _LOG_FORMAT_FLAG_TIMESTAMP | + LOG_FORMAT_FLAG_LOCATION_DEBUG | + LOG_FORMAT_FLAG_LOCATION_ERROR | + LOG_FORMAT_FLAG_ALIGN_LOCATION, +} LogFormatFlags; + +void (*_nm_logging_clear_platform_logging_cache) (void); static void nm_log_handler (const gchar *log_domain, @@ -58,18 +93,18 @@ typedef struct { const char *level_str; int syslog_level; GLogLevelFlags g_log_level; - gboolean full_details; + LogFormatFlags log_format_level; } LogLevelDesc; static struct { NMLogLevel log_level; NMLogDomain logging[_LOGL_N_REAL]; gboolean logging_set_up; + LogFormatFlags log_format_flags; enum { LOG_BACKEND_GLIB, LOG_BACKEND_SYSLOG, LOG_BACKEND_JOURNAL, - LOG_BACKEND_JOURNAL_SYSLOG_STYLE, } log_backend; char *logging_domains_to_string; const LogLevelDesc level_desc[_LOGL_N]; @@ -82,13 +117,13 @@ static struct { .log_level = LOGL_INFO, .log_backend = LOG_BACKEND_GLIB, .level_desc = { - [LOGL_TRACE] = { "TRACE", "<trace>", LOG_DEBUG, G_LOG_LEVEL_DEBUG, TRUE }, - [LOGL_DEBUG] = { "DEBUG", "<debug>", LOG_INFO, G_LOG_LEVEL_DEBUG, TRUE }, - [LOGL_INFO] = { "INFO", "<info>", LOG_INFO, G_LOG_LEVEL_MESSAGE, FALSE }, - [LOGL_WARN] = { "WARN", "<warn>", LOG_WARNING, G_LOG_LEVEL_WARNING, FALSE }, - [LOGL_ERR] = { "ERR", "<error>", LOG_ERR, G_LOG_LEVEL_WARNING, TRUE }, - [_LOGL_OFF] = { "OFF", NULL, 0, 0, FALSE }, - [_LOGL_KEEP] = { "KEEP", NULL, 0, 0, FALSE }, + [LOGL_TRACE] = { "TRACE", "<trace>", LOG_DEBUG, G_LOG_LEVEL_DEBUG, _LOG_FORMAT_FLAG_LEVEL_DEBUG }, + [LOGL_DEBUG] = { "DEBUG", "<debug>", LOG_INFO, G_LOG_LEVEL_DEBUG, _LOG_FORMAT_FLAG_LEVEL_DEBUG }, + [LOGL_INFO] = { "INFO", "<info>", LOG_INFO, G_LOG_LEVEL_MESSAGE, _LOG_FORMAT_FLAG_LEVEL_INFO }, + [LOGL_WARN] = { "WARN", "<warn>", LOG_WARNING, G_LOG_LEVEL_WARNING, _LOG_FORMAT_FLAG_LEVEL_INFO }, + [LOGL_ERR] = { "ERR", "<error>", LOG_ERR, G_LOG_LEVEL_WARNING, _LOG_FORMAT_FLAG_LEVEL_ERROR }, + [_LOGL_OFF] = { "OFF", NULL, 0, 0, 0 }, + [_LOGL_KEEP] = { "KEEP", NULL, 0, 0, 0 }, }, .domain_desc = { { LOGD_PLATFORM, "PLATFORM" }, @@ -149,8 +184,14 @@ static char *_domains_to_string (gboolean include_level_override); static void _ensure_initialized (void) { - if (G_UNLIKELY (!global.logging_set_up)) + if (G_UNLIKELY (!global.logging_set_up)) { + int errsv = errno; + nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL); + + /* must ensure that errno is not modified. */ + errno = errsv; + } } static gboolean @@ -297,11 +338,12 @@ nm_logging_setup (const char *level, global.logging[i] = new_logging[i]; if ( had_platform_debug + && _nm_logging_clear_platform_logging_cache && !nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) { /* when debug logging is enabled, platform will cache all access to * sysctl. When the user disables debug-logging, we want to clear that * cache right away. */ - _nm_linux_platform_sysctl_clear_cache (); + _nm_logging_clear_platform_logging_cache (); } if (unrecognized) @@ -419,6 +461,7 @@ nm_logging_enabled (NMLogLevel level, NMLogDomain domain) if ((guint) level >= G_N_ELEMENTS (global.logging)) g_return_val_if_reached (FALSE); + /* This function is guaranteed not to modify errno. */ _ensure_initialized (); return !!(global.logging[level] & domain); @@ -448,7 +491,7 @@ _iovec_set_string (struct iovec *iov, gboolean *iov_free, int i, const char *str iov[i].iov_len = len; iov_free[i] = FALSE; } -#define _iovec_set_literal_string(iov, iov_free, i, str) _iovec_set_string ((iov), (iov_free), (i), (""str""), STRLEN (str)) +#define _iovec_set_literal_string(iov, iov_free, i, str) _iovec_set_string ((iov), (iov_free), (i), (""str""), NM_STRLEN (str)) #endif void @@ -463,7 +506,9 @@ _nm_log_impl (const char *file, { va_list args; char *msg; - char *fullmsg = NULL; + char *fullmsg; + char s_buf_timestamp[64]; + char s_buf_location[1024]; GTimeVal tv; if ((guint) level >= G_N_ELEMENTS (global.logging)) @@ -485,10 +530,55 @@ _nm_log_impl (const char *file, msg = g_strdup_vprintf (fmt, args); va_end (args); + if (NM_FLAGS_ANY (global.log_format_flags, global.level_desc[level].log_format_level & _LOG_FORMAT_FLAG_TIMESTAMP)) { + g_get_current_time (&tv); + nm_sprintf_buf (s_buf_timestamp, " [%ld.%06ld]", tv.tv_sec, tv.tv_usec); + } else + s_buf_timestamp[0] = '\0'; + + s_buf_location[0] = '\0'; + if (NM_FLAGS_ANY (global.log_format_flags, global.level_desc[level].log_format_level & _LOG_FORMAT_FLAG_LOCATION)) { +#define MAX_LEN_FILE 37 +#define MAX_LEN_FUNC 26 + gsize l = sizeof (s_buf_location); + char *p = s_buf_location, *p_buf; + gsize len; + char s_buf[MAX (MAX_LEN_FILE, MAX_LEN_FUNC) + 30]; + + if (file) { + if (NM_FLAGS_HAS (global.log_format_flags, LOG_FORMAT_FLAG_ALIGN_LOCATION)) { + /* left-align the "[file:line]" string, but truncate from left to MAX_LEN_FILE chars. */ + len = strlen (file); + nm_sprintf_buf (s_buf, "[%s:%u]", + len > MAX_LEN_FILE ? &file[len - MAX_LEN_FILE] : file, + line); + len = strlen (s_buf); + if (len > MAX_LEN_FILE) { + p_buf = &s_buf[len - MAX_LEN_FILE]; + p_buf[0] = '['; + } else + p_buf = s_buf; + nm_utils_strbuf_append (&p, &l, " %-"G_STRINGIFY (MAX_LEN_FILE)"s", p_buf); + } else + nm_utils_strbuf_append (&p, &l, " [%s:%u]", file, line); + } + if (func) { + if (NM_FLAGS_HAS (global.log_format_flags, LOG_FORMAT_FLAG_ALIGN_LOCATION)) { + /* left-align the "func():" string, but truncate from left to MAX_LEN_FUNC chars. */ + len = strlen (func); + nm_sprintf_buf (s_buf, "%s():", + len > MAX_LEN_FUNC ? &func[len - MAX_LEN_FUNC] : func); + len = strlen (s_buf); + nm_utils_strbuf_append (&p, &l, " %-"G_STRINGIFY (MAX_LEN_FUNC)"s", + len > MAX_LEN_FUNC ? &s_buf[len - MAX_LEN_FUNC] : s_buf); + } else + nm_utils_strbuf_append (&p, &l, " %s():", func); + } + } + switch (global.log_backend) { #if SYSTEMD_JOURNAL case LOG_BACKEND_JOURNAL: - case LOG_BACKEND_JOURNAL_SYSLOG_STYLE: { gint64 now, boottime; #define _NUM_MAX_FIELDS_SYSLOG_FACILITY 10 @@ -501,12 +591,12 @@ _nm_log_impl (const char *file, boottime = nm_utils_monotonic_timestamp_as_boottime (now, 1); _iovec_set_format (iov, iov_free, i_field++, "PRIORITY=%d", global.level_desc[level].syslog_level); - if ( global.log_backend == LOG_BACKEND_JOURNAL_SYSLOG_STYLE - && global.level_desc[level].full_details) { - g_get_current_time (&tv); - _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s [%ld.%06ld] [%s:%u] %s(): %s", global.level_desc[level].level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg); - } else - _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s %s", global.level_desc[level].level_str, msg); + _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=" + "%-7s%s%s %s", + global.level_desc[level].level_str, + s_buf_timestamp, + s_buf_location, + msg); _iovec_set_literal_string (iov, iov_free, i_field++, "SYSLOG_IDENTIFIER=" G_LOG_DOMAIN); _iovec_set_format (iov, iov_free, i_field++, "SYSLOG_PID=%ld", (long) getpid ()); { @@ -552,8 +642,8 @@ _nm_log_impl (const char *file, _iovec_set_format (iov, iov_free, i_field++, "NM_LOG_DOMAINS=%s", s_domain_1); } _iovec_set_format (iov, iov_free, i_field++, "NM_LOG_LEVEL=%s", global.level_desc[level].name); - _iovec_set_format (iov, iov_free, i_field++, "CODE_FUNC=%s", func); - _iovec_set_format (iov, iov_free, i_field++, "CODE_FILE=%s", file); + _iovec_set_format (iov, iov_free, i_field++, "CODE_FUNC=%s", func ?: ""); + _iovec_set_format (iov, iov_free, i_field++, "CODE_FILE=%s", file ?: ""); _iovec_set_format (iov, iov_free, i_field++, "CODE_LINE=%u", line); _iovec_set_format (iov, iov_free, i_field++, "TIMESTAMP_MONOTONIC=%lld.%06lld", (long long) (now / NM_UTILS_NS_PER_SECOND), (long long) ((now % NM_UTILS_NS_PER_SECOND) / 1000)); _iovec_set_format (iov, iov_free, i_field++, "TIMESTAMP_BOOTTIME=%lld.%06lld", (long long) (boottime / NM_UTILS_NS_PER_SECOND), (long long) ((boottime % NM_UTILS_NS_PER_SECOND) / 1000)); @@ -573,21 +663,21 @@ _nm_log_impl (const char *file, break; #endif default: - if (global.level_desc[level].full_details) { - g_get_current_time (&tv); - fullmsg = g_strdup_printf ("%-7s [%ld.%06ld] [%s:%u] %s(): %s", global.level_desc[level].level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg); - } else - fullmsg = g_strdup_printf ("%-7s %s", global.level_desc[level].level_str, msg); + fullmsg = g_strdup_printf ("%-7s%s%s %s", + global.level_desc[level].level_str, + s_buf_timestamp, + s_buf_location, + msg); if (global.log_backend == LOG_BACKEND_SYSLOG) syslog (global.level_desc[level].syslog_level, "%s", fullmsg); else g_log (G_LOG_DOMAIN, global.level_desc[level].g_log_level, "%s", fullmsg); + g_free (fullmsg); break; } g_free (msg); - g_free (fullmsg); } /************************************************************************/ @@ -625,7 +715,6 @@ nm_log_handler (const gchar *log_domain, switch (global.log_backend) { #if SYSTEMD_JOURNAL case LOG_BACKEND_JOURNAL: - case LOG_BACKEND_JOURNAL_SYSLOG_STYLE: { gint64 now, boottime; @@ -654,6 +743,8 @@ nm_log_handler (const gchar *log_domain, void nm_logging_syslog_openlog (const char *logging_backend) { + LogFormatFlags log_format_flags; + if (global.log_backend != LOG_BACKEND_GLIB) g_return_if_reached (); @@ -663,12 +754,14 @@ nm_logging_syslog_openlog (const char *logging_backend) if (strcmp (logging_backend, "debug") == 0) { global.log_backend = LOG_BACKEND_SYSLOG; openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); + log_format_flags = _LOG_FORMAT_FLAG_SYSLOG; #if SYSTEMD_JOURNAL } else if (strcmp (logging_backend, "syslog") != 0) { - if (strcmp (logging_backend, "journal-syslog-style") != 0) - global.log_backend = LOG_BACKEND_JOURNAL; + if (strcmp (logging_backend, "journal-syslog-style") == 0) + log_format_flags = _LOG_FORMAT_FLAG_SYSLOG; else - global.log_backend = LOG_BACKEND_JOURNAL_SYSLOG_STYLE; + log_format_flags = _LOG_FORMAT_FLAG_TIMESTAMP; + global.log_backend = LOG_BACKEND_JOURNAL; /* ensure we read a monotonic timestamp. Reading the timestamp the first * time causes a logging message. We don't want to do that during _nm_log_impl. */ @@ -676,9 +769,12 @@ nm_logging_syslog_openlog (const char *logging_backend) #endif } else { global.log_backend = LOG_BACKEND_SYSLOG; + log_format_flags = _LOG_FORMAT_FLAG_SYSLOG; openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON); } + global.log_format_flags = log_format_flags; + g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, nm_log_handler, |