diff options
| author | Michael Biebl <biebl@debian.org> | 2014-07-06 02:16:10 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2014-07-06 02:16:10 +0200 |
| commit | 33491bc4279481db8ae47213e34a6d695a0e8830 (patch) | |
| tree | 097d2b0fdff3fae6885381ae5e57a182cd8cbbba /src/logging/nm-logging.c | |
| parent | 59c3714a494c3b3765657c0551ad82842d98a7d2 (diff) | |
Imported Upstream version 0.9.10.0 upstream/0.9.10.0
Diffstat (limited to 'src/logging/nm-logging.c')
| -rw-r--r-- | src/logging/nm-logging.c | 358 |
1 files changed, 256 insertions, 102 deletions
diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c index 79d47f13..1577f6ec 100644 --- a/src/logging/nm-logging.c +++ b/src/logging/nm-logging.c @@ -36,31 +36,40 @@ #include "nm-logging.h" +static void +nm_log_handler (const gchar *log_domain, + GLogLevelFlags level, + const gchar *message, + gpointer ignored); + #define LOGD_ALL \ (LOGD_PLATFORM | LOGD_RFKILL | LOGD_ETHER | LOGD_WIFI | LOGD_BT | LOGD_MB | \ LOGD_DHCP4 | LOGD_DHCP6 | LOGD_PPP | LOGD_WIFI_SCAN | LOGD_IP4 | \ LOGD_IP6 | LOGD_AUTOIP4 | LOGD_DNS | LOGD_VPN | LOGD_SHARING | \ LOGD_SUPPLICANT | LOGD_AGENTS | LOGD_SETTINGS | LOGD_SUSPEND | \ - LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH | LOGD_WIMAX | \ + LOGD_CORE | LOGD_DEVICE | LOGD_OLPC | LOGD_WIMAX | \ LOGD_INFINIBAND | LOGD_FIREWALL | LOGD_ADSL | LOGD_BOND | \ - LOGD_VLAN | LOGD_BRIDGE | LOGD_CONCHECK) + LOGD_VLAN | LOGD_BRIDGE | LOGD_DBUS_PROPS | LOGD_TEAM | LOGD_CONCHECK | \ + LOGD_DCB | LOGD_DISPATCH) -#define LOGD_DEFAULT (LOGD_ALL & ~LOGD_WIFI_SCAN) +#define LOGD_DEFAULT (LOGD_ALL & ~(LOGD_WIFI_SCAN | LOGD_DBUS_PROPS)) -static guint32 log_level = LOGL_INFO | LOGL_WARN | LOGL_ERR; -static guint32 log_domains = LOGD_DEFAULT; +static guint32 log_level = LOGL_INFO; +static char *log_domains; +static guint64 logging[LOGL_MAX]; +static gboolean logging_set_up; +static gboolean syslog_opened; typedef struct { - guint32 num; + guint64 num; const char *name; } LogDesc; -static const LogDesc level_descs[] = { - { LOGL_ERR, "ERR" }, - { LOGL_WARN | LOGL_ERR, "WARN" }, - { LOGL_INFO | LOGL_WARN | LOGL_ERR, "INFO" }, - { LOGL_DEBUG | LOGL_INFO | LOGL_WARN | LOGL_ERR, "DEBUG" }, - { 0, NULL } +static const char *level_names[LOGL_MAX] = { + [LOGL_DEBUG] = "DEBUG", + [LOGL_INFO] = "INFO", + [LOGL_WARN] = "WARN", + [LOGL_ERR] = "ERR", }; static const LogDesc domain_descs[] = { @@ -87,7 +96,7 @@ static const LogDesc domain_descs[] = { { LOGD_SUSPEND, "SUSPEND" }, { LOGD_CORE, "CORE" }, { LOGD_DEVICE, "DEVICE" }, - { LOGD_OLPC_MESH, "OLPC" }, + { LOGD_OLPC, "OLPC" }, { LOGD_WIMAX, "WIMAX" }, { LOGD_INFINIBAND,"INFINIBAND" }, { LOGD_FIREWALL, "FIREWALL" }, @@ -95,7 +104,11 @@ static const LogDesc domain_descs[] = { { LOGD_BOND, "BOND" }, { LOGD_VLAN, "VLAN" }, { LOGD_BRIDGE, "BRIDGE" }, + { LOGD_DBUS_PROPS,"DBUS_PROPS" }, + { LOGD_TEAM, "TEAM" }, { LOGD_CONCHECK, "CONCHECK" }, + { LOGD_DCB, "DCB" }, + { LOGD_DISPATCH, "DISPATCH" }, { 0, NULL } }; @@ -119,95 +132,157 @@ nm_logging_error_quark (void) /************************************************************************/ +static gboolean +match_log_level (const char *level, + guint32 *out_level, + GError **error) +{ + int i; + + for (i = 0; i < LOGL_MAX; i++) { + if (!g_ascii_strcasecmp (level_names[i], level)) { + *out_level = i; + return TRUE; + } + } + + g_set_error (error, NM_LOGGING_ERROR, NM_LOGGING_ERROR_UNKNOWN_LEVEL, + _("Unknown log level '%s'"), level); + return FALSE; +} + gboolean -nm_logging_setup (const char *level, const char *domains, GError **error) +nm_logging_setup (const char *level, + const char *domains, + char **bad_domains, + GError **error) { + GString *unrecognized = NULL; + guint64 new_logging[LOGL_MAX]; + guint32 new_log_level = log_level; char **tmp, **iter; - guint32 new_domains = 0; + int i; - /* levels */ - if (level && strlen (level)) { - gboolean found = FALSE; - const LogDesc *diter; + logging_set_up = TRUE; - for (diter = &level_descs[0]; diter->name; diter++) { - if (!strcasecmp (diter->name, level)) { - log_level = diter->num; - found = TRUE; - break; - } - } + for (i = 0; i < LOGL_MAX; i++) + new_logging[i] = 0; - if (!found) { - g_set_error (error, NM_LOGGING_ERROR, NM_LOGGING_ERROR_UNKNOWN_LEVEL, - _("Unknown log level '%s'"), level); + /* levels */ + if (level && *level) { + if (!match_log_level (level, &new_log_level, error)) return FALSE; - } } /* domains */ - if (domains && strlen (domains)) { - tmp = g_strsplit_set (domains, ", ", 0); - for (iter = tmp; iter && *iter; iter++) { - const LogDesc *diter; - gboolean found = FALSE; - - if (!strlen (*iter)) - continue; + if (!domains || !*domains) + domains = log_domains ? log_domains : "DEFAULT"; + tmp = g_strsplit_set (domains, ", ", 0); + for (iter = tmp; iter && *iter; iter++) { + const LogDesc *diter; + guint32 domain_log_level; + guint64 bits; + char *p; + + if (!strlen (*iter)) + continue; + + p = strchr (*iter, ':'); + if (p) { + *p = '\0'; + if (!match_log_level (p + 1, &domain_log_level, error)) { + g_strfreev (tmp); + return FALSE; + } + } else + domain_log_level = new_log_level; + + bits = 0; + + /* Check for combined domains */ + if (!g_ascii_strcasecmp (*iter, LOGD_ALL_STRING)) + bits = LOGD_ALL; + else if (!g_ascii_strcasecmp (*iter, LOGD_DEFAULT_STRING)) + bits = LOGD_DEFAULT; + else if (!g_ascii_strcasecmp (*iter, LOGD_DHCP_STRING)) + bits = LOGD_DHCP; + else if (!g_ascii_strcasecmp (*iter, LOGD_IP_STRING)) + bits = LOGD_IP; + + /* Check for compatibility domains */ + else if (!g_ascii_strcasecmp (*iter, "HW")) + bits = LOGD_PLATFORM; + + else { for (diter = &domain_descs[0]; diter->name; diter++) { - if (!strcasecmp (diter->name, *iter)) { - new_domains |= diter->num; - found = TRUE; + if (!g_ascii_strcasecmp (diter->name, *iter)) { + bits = diter->num; break; } } + } - /* Check for combined domains */ - if (!strcasecmp (*iter, LOGD_ALL_STRING)) { - new_domains = LOGD_ALL; - found = TRUE; - } else if (!strcasecmp (*iter, LOGD_DEFAULT_STRING)) { - new_domains = LOGD_DEFAULT; - found = TRUE; - } else if (!strcasecmp (*iter, LOGD_DHCP_STRING)) { - new_domains |= LOGD_DHCP; - found = TRUE; - } else if (!strcasecmp (*iter, LOGD_IP_STRING)) { - new_domains |= LOGD_IP; - found = TRUE; - } - - /* Check for compatibility domains */ - if (!strcasecmp (*iter, "HW")) { - new_domains |= LOGD_PLATFORM; - found = TRUE; - } - - if (!found) { + if (!bits) { + if (!bad_domains) { g_set_error (error, NM_LOGGING_ERROR, NM_LOGGING_ERROR_UNKNOWN_DOMAIN, _("Unknown log domain '%s'"), *iter); return FALSE; } + + if (unrecognized) + g_string_append (unrecognized, ", "); + else + unrecognized = g_string_new (NULL); + g_string_append (unrecognized, *iter); + continue; } - g_strfreev (tmp); - log_domains = new_domains; + + for (i = 0; i < domain_log_level; i++) + new_logging[i] &= ~bits; + for (i = domain_log_level; i < LOGL_MAX; i++) + new_logging[i] |= bits; + } + g_strfreev (tmp); + + if (log_domains != (char *)domains) { + g_free (log_domains); + log_domains = g_strdup (domains); } + log_level = new_log_level; + for (i = 0; i < LOGL_MAX; i++) + logging[i] = new_logging[i]; + + if (unrecognized) + *bad_domains = g_string_free (unrecognized, FALSE); + return TRUE; } -const char * +char * nm_logging_level_to_string (void) { - const LogDesc *diter; + return g_strdup (level_names[log_level]); +} + +const char * +nm_logging_all_levels_to_string (void) +{ + static GString *str; + + if (G_UNLIKELY (!str)) { + int i; - for (diter = &level_descs[0]; diter->name; diter++) { - if (diter->num == log_level) - return diter->name; + str = g_string_new (NULL); + for (i = 0; i < LOGL_MAX; i++) { + if (str->len) + g_string_append_c (str, ','); + g_string_append (str, level_names[i]); + } } - g_warn_if_reached (); - return ""; + + return str->str; } char * @@ -215,61 +290,135 @@ nm_logging_domains_to_string (void) { const LogDesc *diter; GString *str; + int i; + + /* We don't just return g_strdup (log_domains) because we want to expand + * "DEFAULT" and "ALL". + */ str = g_string_sized_new (75); for (diter = &domain_descs[0]; diter->name; diter++) { - if (diter->num & log_domains) { - if (str->len) - g_string_append_c (str, ','); - g_string_append (str, diter->name); + /* If it's set for any lower level, it will also be set for LOGL_ERR */ + if (!(diter->num & logging[LOGL_ERR])) + continue; + + if (str->len) + g_string_append_c (str, ','); + g_string_append (str, diter->name); + + /* Check if it's logging at a lower level than the default. */ + for (i = 0; i < log_level; i++) { + if (diter->num & logging[i]) { + g_string_append_printf (str, ":%s", level_names[i]); + break; + } + } + /* Check if it's logging at a higher level than the default. */ + if (!(diter->num & logging[log_level])) { + for (i = log_level + 1; i < LOGL_MAX; i++) { + if (diter->num & logging[i]) { + g_string_append_printf (str, ":%s", level_names[i]); + break; + } + } } } return g_string_free (str, FALSE); } -gboolean -nm_logging_level_enabled (guint32 level) +const char * +nm_logging_all_domains_to_string (void) { - return !!(log_level & level); + static GString *str; + + if (G_UNLIKELY (!str)) { + const LogDesc *diter; + + str = g_string_new (LOGD_DEFAULT_STRING); + for (diter = &domain_descs[0]; diter->name; diter++) { + g_string_append_c (str, ','); + g_string_append (str, diter->name); + if (diter->num == LOGD_DHCP6) + g_string_append (str, "," LOGD_DHCP_STRING); + else if (diter->num == LOGD_IP6) + g_string_append (str, "," LOGD_IP_STRING); + } + g_string_append (str, "," LOGD_ALL_STRING); + } + + return str->str; } gboolean -nm_logging_domain_enabled (guint32 domain) +nm_logging_enabled (guint32 level, guint64 domain) { - return !!(log_domains & domain); + g_return_val_if_fail (level < LOGL_MAX, FALSE); + + return !!(logging[level] & domain); } void _nm_log (const char *loc, const char *func, - guint32 domain, + guint64 domain, guint32 level, const char *fmt, ...) { va_list args; char *msg; + char *fullmsg = NULL; GTimeVal tv; + int syslog_level = LOG_INFO; + int g_log_level = G_LOG_LEVEL_INFO; - if (!(log_level & level) || !(log_domains & domain)) + g_return_if_fail (level < LOGL_MAX); + + if (G_UNLIKELY (!logging_set_up)) + nm_logging_setup ("INFO", "DEFAULT", NULL, NULL); + + if (!(logging[level] & domain)) return; va_start (args, fmt); msg = g_strdup_vprintf (fmt, args); va_end (args); - if ((log_level & LOGL_DEBUG) && (level == LOGL_DEBUG)) { + switch (level) { + case LOGL_DEBUG: g_get_current_time (&tv); - syslog (LOG_INFO, "<debug> [%ld.%ld] [%s] %s(): %s", tv.tv_sec, tv.tv_usec, loc, func, msg); - } else if ((log_level & LOGL_INFO) && (level == LOGL_INFO)) - syslog (LOG_INFO, "<info> %s", msg); - else if ((log_level & LOGL_WARN) && (level == LOGL_WARN)) - syslog (LOG_WARNING, "<warn> %s", msg); - else if ((log_level & LOGL_ERR) && (level == LOGL_ERR)) { + syslog_level = LOG_INFO; + g_log_level = G_LOG_LEVEL_DEBUG; + fullmsg = g_strdup_printf ("<debug> [%ld.%06ld] [%s] %s(): %s", tv.tv_sec, tv.tv_usec, loc, func, msg); + break; + case LOGL_INFO: + syslog_level = LOG_INFO; + g_log_level = G_LOG_LEVEL_MESSAGE; + fullmsg = g_strconcat ("<info> ", msg, NULL); + break; + case LOGL_WARN: + syslog_level = LOG_WARNING; + g_log_level = G_LOG_LEVEL_WARNING; + fullmsg = g_strconcat ("<warn> ", msg, NULL); + break; + case LOGL_ERR: + syslog_level = LOG_ERR; + /* g_log_level is still WARNING, because ERROR is fatal */ + g_log_level = G_LOG_LEVEL_WARNING; g_get_current_time (&tv); - syslog (LOG_ERR, "<error> [%ld.%ld] [%s] %s(): %s", tv.tv_sec, tv.tv_usec, loc, func, msg); + fullmsg = g_strdup_printf ("<error> [%ld.%06ld] [%s] %s(): %s", tv.tv_sec, tv.tv_usec, loc, func, msg); + break; + default: + g_assert_not_reached (); } + + if (syslog_opened) + syslog (syslog_level, "%s", fullmsg); + else + g_log (G_LOG_DOMAIN, g_log_level, "%s", fullmsg); + g_free (msg); + g_free (fullmsg); } /************************************************************************/ @@ -282,7 +431,7 @@ nm_log_handler (const gchar *log_domain, { int syslog_priority; - switch (level) { + switch (level & G_LOG_LEVEL_MASK) { case G_LOG_LEVEL_ERROR: syslog_priority = LOG_CRIT; break; @@ -308,21 +457,26 @@ nm_log_handler (const gchar *log_domain, } void -nm_logging_start (gboolean become_daemon) +nm_logging_syslog_openlog (gboolean debug) { - if (become_daemon) - openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON); - else + if (debug) openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); + else + openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON); - g_log_set_handler (G_LOG_DOMAIN, - G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, - nm_log_handler, - NULL); + if (!syslog_opened) { + syslog_opened = TRUE; + + g_log_set_handler (G_LOG_DOMAIN, + G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + nm_log_handler, + NULL); + } } void -nm_logging_shutdown (void) +nm_logging_syslog_closelog (void) { - closelog (); + if (syslog_opened) + closelog (); } |