From aa54d5a36eb329e4a9b9fb6e62633cd58c431f96 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 19:24:49 +0200 Subject: config: add nm_config_data_get_value_cached() function nm_config_data_get_value() returns an allocated string. This is inconvenient for the caller. Add a utility function nm_config_data_get_value_cached() that caches the returned value. Of course, use with care as the returned string will be invalidated by each call to nm_config_data_get_value_cached(). --- src/nm-config-data.c | 21 +++++++++++++++++++++ src/nm-config-data.h | 1 + 2 files changed, 22 insertions(+) diff --git a/src/nm-config-data.c b/src/nm-config-data.c index 03cae638c7..5e015f016e 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -72,6 +72,9 @@ typedef struct { char *dns_mode; char *rc_manager; + + /* mutable field */ + char *value_cached; } NMConfigDataPrivate; @@ -138,6 +141,22 @@ nm_config_data_get_value (const NMConfigData *self, const char *group, const cha return nm_config_keyfile_get_value (NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile, group, key, flags); } +const char *nm_config_data_get_value_cached (const NMConfigData *self, const char *group, const char *key, NMConfigGetValueFlags flags) +{ + NMConfigDataPrivate *priv; + + g_return_val_if_fail (NM_IS_CONFIG_DATA (self), NULL); + g_return_val_if_fail (group && *group, NULL); + g_return_val_if_fail (key && *key, NULL); + + priv = NM_CONFIG_DATA_GET_PRIVATE (self); + + /* we modify @value_cached. In C++ jargon, the field is mutable. */ + g_free (priv->value_cached); + priv->value_cached = nm_config_keyfile_get_value (priv->keyfile, group, key, flags); + return priv->value_cached; +} + gboolean nm_config_data_has_value (const NMConfigData *self, const char *group, const char *key, NMConfigGetValueFlags flags) { @@ -801,6 +820,8 @@ finalize (GObject *gobject) g_key_file_unref (priv->keyfile_intern); G_OBJECT_CLASS (nm_config_data_parent_class)->finalize (gobject); + + g_free (priv->value_cached); } static void diff --git a/src/nm-config-data.h b/src/nm-config-data.h index 0dfdf531ec..36aa66af95 100644 --- a/src/nm-config-data.h +++ b/src/nm-config-data.h @@ -111,6 +111,7 @@ const char *nm_config_data_get_config_description (const NMConfigData *config_da gboolean nm_config_data_has_group (const NMConfigData *self, const char *group); gboolean nm_config_data_has_value (const NMConfigData *self, const char *group, const char *key, NMConfigGetValueFlags flags); char *nm_config_data_get_value (const NMConfigData *config_data, const char *group, const char *key, NMConfigGetValueFlags flags); +const char *nm_config_data_get_value_cached (const NMConfigData *config_data, const char *group, const char *key, NMConfigGetValueFlags flags); gint nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, const char *key, gint default_value); const char *nm_config_data_get_connectivity_uri (const NMConfigData *config_data); -- cgit v1.2.1 From 09ba572174e9109988ede039342b6098d61bc7e0 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 19:39:00 +0200 Subject: config: move debug command line option to NMConfig Whether NM runs in debug mode is also interesting to other components outside of "main.c". Expose global_opt.debug via a new nm_config_get_is_debug() function. Actually, we should move parsing of all command line options to NMConfig, as NMConfig is the central instance to provide such information. --- src/main.c | 6 ++---- src/nm-config.c | 10 ++++++++++ src/nm-config.h | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 65ba7a61d7..ad44471df6 100644 --- a/src/main.c +++ b/src/main.c @@ -70,7 +70,6 @@ static gboolean configure_and_quit = FALSE; static struct { gboolean show_version; gboolean become_daemon; - gboolean debug; gboolean g_fatal_warnings; gboolean run_from_build_dir; char *opt_log_level; @@ -231,7 +230,6 @@ do_early_setup (int *argc, char **argv[], NMConfigCmdLineOptions *config_cli) GOptionEntry options[] = { { "version", 'V', 0, G_OPTION_ARG_NONE, &global_opt.show_version, N_("Print NetworkManager version and exit"), NULL }, { "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &global_opt.become_daemon, N_("Don't become a daemon"), NULL }, - { "debug", 'd', 0, G_OPTION_ARG_NONE, &global_opt.debug, N_("Don't become a daemon, and log to stderr"), NULL }, { "log-level", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_level, N_("Log level: one of [%s]"), "INFO" }, { "log-domains", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_domains, N_("Log domains separated by ',': any combination of [%s]"), @@ -372,7 +370,7 @@ main (int argc, char *argv[]) } } - if (global_opt.become_daemon && !global_opt.debug) { + if (global_opt.become_daemon && !nm_config_get_is_debug (config)) { if (daemon (0, 0) < 0) { int saved_errno; @@ -388,7 +386,7 @@ main (int argc, char *argv[]) /* Set up unix signal handling - before creating threads, but after daemonizing! */ nm_main_utils_setup_signals (main_loop); - nm_logging_syslog_openlog (global_opt.debug); + nm_logging_syslog_openlog (nm_config_get_is_debug (config)); nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting..."); diff --git a/src/nm-config.c b/src/nm-config.c index 07ea26980e..3490959a7c 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -53,6 +53,7 @@ struct NMConfigCmdLineOptions { char *no_auto_default_file; char *plugins; gboolean configure_and_quit; + gboolean is_debug; char *connectivity_uri; /* We store interval as signed internally to track whether it's @@ -318,6 +319,12 @@ nm_config_get_configure_and_quit (NMConfig *config) return NM_CONFIG_GET_PRIVATE (config)->configure_and_quit; } +gboolean +nm_config_get_is_debug (NMConfig *config) +{ + return NM_CONFIG_GET_PRIVATE (config)->cli.is_debug; +} + /************************************************************************/ static char ** @@ -432,6 +439,7 @@ _nm_config_cmd_line_options_clear (NMConfigCmdLineOptions *cli) g_clear_pointer (&cli->intern_config_file, g_free); g_clear_pointer (&cli->plugins, g_free); cli->configure_and_quit = FALSE; + cli->is_debug = FALSE; g_clear_pointer (&cli->connectivity_uri, g_free); g_clear_pointer (&cli->connectivity_response, g_free); cli->connectivity_interval = -1; @@ -452,6 +460,7 @@ _nm_config_cmd_line_options_copy (const NMConfigCmdLineOptions *cli, NMConfigCmd dst->intern_config_file = g_strdup (cli->intern_config_file); dst->plugins = g_strdup (cli->plugins); dst->configure_and_quit = cli->configure_and_quit; + dst->is_debug = cli->is_debug; dst->connectivity_uri = g_strdup (cli->connectivity_uri); dst->connectivity_response = g_strdup (cli->connectivity_response); dst->connectivity_interval = cli->connectivity_interval; @@ -491,6 +500,7 @@ nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli, { "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli->no_auto_default_file, N_("State file for no-auto-default devices"), N_(DEFAULT_NO_AUTO_DEFAULT_FILE) }, { "plugins", 0, 0, G_OPTION_ARG_STRING, &cli->plugins, N_("List of plugins separated by ','"), N_(CONFIG_PLUGINS_DEFAULT) }, { "configure-and-quit", 0, 0, G_OPTION_ARG_NONE, &cli->configure_and_quit, N_("Quit after initial configuration"), NULL }, + { "debug", 'd', 0, G_OPTION_ARG_NONE, &cli->is_debug, N_("Don't become a daemon, and log to stderr"), NULL }, /* These three are hidden for now, and should eventually just go away. */ { "connectivity-uri", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli->connectivity_uri, N_("An http(s) address for checking internet connectivity"), "http://example.com" }, diff --git a/src/nm-config.h b/src/nm-config.h index 3caf0c5c31..113664e79e 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -102,6 +102,7 @@ const char *nm_config_get_log_level (NMConfig *config); const char *nm_config_get_log_domains (NMConfig *config); const char *nm_config_get_debug (NMConfig *config); gboolean nm_config_get_configure_and_quit (NMConfig *config); +gboolean nm_config_get_is_debug (NMConfig *config); void nm_config_set_values (NMConfig *self, GKeyFile *keyfile_intern_new, -- cgit v1.2.1 From 9020cd1aacf26a03cf1bc46b040d42a791a89935 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 16:53:40 +0200 Subject: logging: remove nm_logging_syslog_closelog() Remove nm_logging_syslog_closelog(). The reasons are: - closelog() is optional according to the manual. - we called nm_logging_syslog_closelog() at the end of the main() function. But we have destructors running afterwards, so we were closing the log before logging the last line. Apparently that had no bad consequences either, so why was closelog() even useful? Also, it's hard to determine when we log the last line and only closelog() afterwards. - closelog() does not revert what openlog() did, this is ugly. --- src/main.c | 2 -- src/nm-iface-helper.c | 2 -- src/nm-logging.c | 6 ------ src/nm-logging.h | 1 - 4 files changed, 11 deletions(-) diff --git a/src/main.c b/src/main.c index ad44471df6..7b1e522467 100644 --- a/src/main.c +++ b/src/main.c @@ -486,8 +486,6 @@ main (int argc, char *argv[]) done: g_clear_object (&manager); - nm_logging_syslog_closelog (); - if (global_opt.pidfile && wrote_pidfile) unlink (global_opt.pidfile); diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index cbff221a85..72b69590b4 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -481,8 +481,6 @@ main (int argc, char *argv[]) g_clear_pointer (&hwaddr, g_byte_array_unref); - nm_logging_syslog_closelog (); - if (pidfile && wrote_pidfile) unlink (pidfile); diff --git a/src/nm-logging.c b/src/nm-logging.c index d8dc4291ac..d4fe998ecf 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -488,9 +488,3 @@ nm_logging_syslog_openlog (gboolean debug) } } -void -nm_logging_syslog_closelog (void) -{ - if (syslog_opened) - closelog (); -} diff --git a/src/nm-logging.h b/src/nm-logging.h index d02e16528f..7ed966f85a 100644 --- a/src/nm-logging.h +++ b/src/nm-logging.h @@ -164,6 +164,5 @@ gboolean nm_logging_setup (const char *level, char **bad_domains, GError **error); void nm_logging_syslog_openlog (gboolean debug); -void nm_logging_syslog_closelog (void); #endif /* __NETWORKMANAGER_LOGGING_H__ */ -- cgit v1.2.1 From d0345ede266fa361e07bbd337be33517ede442c5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 17:01:15 +0200 Subject: logging: allow calling nm_logging_syslog_openlog() only once --- src/nm-logging.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/nm-logging.c b/src/nm-logging.c index d4fe998ecf..f6936e8243 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -473,18 +473,18 @@ nm_log_handler (const gchar *log_domain, void nm_logging_syslog_openlog (gboolean debug) { + if (syslog_opened) + g_return_if_reached (); + syslog_opened = TRUE; + if (debug) openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); else openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON); - 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); - } + g_log_set_handler (G_LOG_DOMAIN, + G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + nm_log_handler, + NULL); } -- cgit v1.2.1 From 831a5e32fb38ec0407b986bee0984142bffbdac8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 17:13:59 +0200 Subject: logging: refactor @syslog_opened variable to @log_backend --- src/nm-logging.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/nm-logging.c b/src/nm-logging.c index f6936e8243..ac418da193 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -48,7 +48,10 @@ static NMLogLevel log_level = LOGL_INFO; static char *log_domains; static NMLogDomain logging[LOGL_MAX]; static gboolean logging_set_up; -static gboolean syslog_opened; +enum { + LOG_BACKEND_GLIB, + LOG_BACKEND_SYSLOG, +} log_backend = LOG_BACKEND_GLIB; static char *logging_domains_to_string; typedef struct { @@ -426,10 +429,13 @@ _nm_log_impl (const char *file, g_assert_not_reached (); } - if (syslog_opened) + switch (log_backend) { + case LOG_BACKEND_SYSLOG: syslog (syslog_level, "%s", fullmsg); - else + break; + default: g_log (G_LOG_DOMAIN, g_log_level, "%s", fullmsg); + } g_free (msg); g_free (fullmsg); @@ -473,9 +479,10 @@ nm_log_handler (const gchar *log_domain, void nm_logging_syslog_openlog (gboolean debug) { - if (syslog_opened) + if (log_backend != LOG_BACKEND_GLIB) g_return_if_reached (); - syslog_opened = TRUE; + + log_backend = LOG_BACKEND_SYSLOG; if (debug) openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); -- cgit v1.2.1 From b1b26e8049c5041bf3a217f68496778bbfcc7dd5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 17:28:22 +0200 Subject: logging: factor our construction of logging message in _nm_log_impl() --- src/nm-logging.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/nm-logging.c b/src/nm-logging.c index ac418da193..ce1c49e18c 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -379,6 +379,8 @@ _nm_log_impl (const char *file, GTimeVal tv; int syslog_level = LOG_INFO; int g_log_level = G_LOG_LEVEL_INFO; + gboolean full_details = FALSE; + const char *level_str = NULL; g_return_if_fail (level < LOGL_MAX); @@ -397,38 +399,44 @@ _nm_log_impl (const char *file, switch (level) { case LOGL_TRACE: - g_get_current_time (&tv); syslog_level = LOG_DEBUG; g_log_level = G_LOG_LEVEL_DEBUG; - fullmsg = g_strdup_printf (" [%ld.%06ld] [%s:%u] %s(): %s", tv.tv_sec, tv.tv_usec, file, line, func, msg); + full_details = TRUE; + level_str = ""; break; case LOGL_DEBUG: - g_get_current_time (&tv); syslog_level = LOG_INFO; g_log_level = G_LOG_LEVEL_DEBUG; - fullmsg = g_strdup_printf (" [%ld.%06ld] [%s:%u] %s(): %s", tv.tv_sec, tv.tv_usec, file, line, func, msg); + full_details = TRUE; + level_str = ""; break; case LOGL_INFO: syslog_level = LOG_INFO; g_log_level = G_LOG_LEVEL_MESSAGE; - fullmsg = g_strconcat (" ", msg, NULL); + level_str = ""; break; case LOGL_WARN: syslog_level = LOG_WARNING; g_log_level = G_LOG_LEVEL_WARNING; - fullmsg = g_strconcat (" ", msg, NULL); + level_str = ""; 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); - fullmsg = g_strdup_printf (" [%ld.%06ld] [%s:%u] %s(): %s", tv.tv_sec, tv.tv_usec, file, line, func, msg); + full_details = TRUE; + level_str = ""; break; default: - g_assert_not_reached (); + g_return_if_reached (); } + if (full_details) { + g_get_current_time (&tv); + fullmsg = g_strdup_printf ("%-7s [%ld.%06ld] [%s:%u] %s(): %s", level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg); + } else + fullmsg = g_strdup_printf ("%-7s %s", level_str, msg); + switch (log_backend) { case LOG_BACKEND_SYSLOG: syslog (syslog_level, "%s", fullmsg); -- cgit v1.2.1 From cd5417ff4f7e15e569f6818ae74605ae55bcfa05 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 16:19:18 +0200 Subject: build: detect systemd-journald support --- configure.ac | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/configure.ac b/configure.ac index c31f27f350..11f6ccdaad 100644 --- a/configure.ac +++ b/configure.ac @@ -376,6 +376,30 @@ elif test "$hostname_persist" = gentoo; then AC_DEFINE(HOSTNAME_PERSIST_GENTOO, 1, [Enable Gentoo hostname persist method]) fi +AC_ARG_WITH(systemd-journal, AS_HELP_STRING([--with-systemd-journal=yes|no], [Use systemd journal for logging])) +have_systemd_journal=no +if test "$with_systemd_journal" != "no"; then + PKG_CHECK_MODULES(SYSTEMD_JOURNAL, + [libsystemd >= 209], + [have_systemd_journal=yes], + [PKG_CHECK_MODULES(SYSTEMD_JOURNAL, + [libsystemd-journal], + [have_systemd_journal=yes], + [have_systemd_journal=no])]) + if test "$have_systemd_journal" != "yes"; then + if test "$with_systemd_journal" = "yes"; then + AC_MSG_ERROR([Missing systemd-journald support]) + fi + fi +fi +if test "$have_systemd_journal" = "yes"; then + AC_SUBST(SYSTEMD_JOURNAL_CFLAGS) + AC_SUBST(SYSTEMD_JOURNAL_LIBS) + AC_DEFINE([SYSTEMD_JOURNAL], 1, [Define to 1 if libsystemd-journald is available]) +else + AC_DEFINE([SYSTEMD_JOURNAL], 0, [Define to 1 if libsystemd-journald is available]) +fi + # Session tracking support AC_ARG_WITH(systemd-logind, AS_HELP_STRING([--with-systemd-logind=yes|no], [Support systemd session tracking])) @@ -1091,6 +1115,7 @@ else fi echo " polkit agent: ${enable_polkit_agent}" echo " selinux: $have_selinux" +echo " systemd-journald: $have_systemd_journal" echo " hostname persist: ${hostname_persist}" echo -- cgit v1.2.1 From 1b808d3b255c0557b90cef49c0624a92e0cf5bf5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 16:21:21 +0200 Subject: logging: add native systemd-journald support to nm-logging --- src/Makefile.am | 3 + src/nm-logging.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 170 insertions(+), 16 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 69ec19b9d3..cc0a0aecd1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -419,6 +419,7 @@ AM_CPPFLAGS += \ $(LIBSOUP_CFLAGS) \ $(SELINUX_CFLAGS) \ $(SYSTEMD_LOGIN_CFLAGS) \ + $(SYSTEMD_JOURNAL_CFLAGS) \ $(SYSTEMD_NM_CFLAGS) \ \ -DBINDIR=\"$(bindir)\" \ @@ -455,6 +456,7 @@ libNetworkManager_la_LIBADD = \ $(GUDEV_LIBS) \ $(LIBNL_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ + $(SYSTEMD_JOURNAL_LIBS) \ $(LIBNDP_LIBS) \ $(LIBDL) \ $(LIBM) @@ -550,6 +552,7 @@ nm_iface_helper_LDADD = \ $(DBUS_LIBS) \ $(GLIB_LIBS) \ $(GUDEV_LIBS) \ + $(SYSTEMD_JOURNAL_LIBS) \ $(LIBNL_LIBS) \ $(LIBNDP_LIBS) \ $(LIBM) diff --git a/src/nm-logging.c b/src/nm-logging.c index ce1c49e18c..49f04220f2 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -34,9 +34,16 @@ #include +#if SYSTEMD_JOURNAL +#define SD_JOURNAL_SUPPRESS_LOCATION +#include +#endif + #include "nm-glib-compat.h" #include "nm-logging.h" #include "nm-errors.h" +#include "gsystem-local-alloc.h" +#include "NetworkManagerUtils.h" static void nm_log_handler (const gchar *log_domain, @@ -51,6 +58,7 @@ static gboolean logging_set_up; enum { LOG_BACKEND_GLIB, LOG_BACKEND_SYSLOG, + LOG_BACKEND_JOURNAL, } log_backend = LOG_BACKEND_GLIB; static char *logging_domains_to_string; @@ -363,6 +371,33 @@ nm_logging_enabled (NMLogLevel level, NMLogDomain domain) return !!(logging[level] & domain); } +#if SYSTEMD_JOURNAL +__attribute__((__format__ (__printf__, 4, 5))) +static void +_iovec_set_format (struct iovec *iov, gboolean *iov_free, int i, const char *format, ...) +{ + va_list ap; + char *str; + + va_start (ap, format); + str = g_strdup_vprintf (format, ap); + va_end (ap); + + iov[i].iov_base = str; + iov[i].iov_len = strlen (str); + iov_free[i] = TRUE; +} + +static void +_iovec_set_string (struct iovec *iov, gboolean *iov_free, int i, const char *str, gsize len) +{ + iov[i].iov_base = (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)) +#endif + void _nm_log_impl (const char *file, guint line, @@ -382,7 +417,8 @@ _nm_log_impl (const char *file, gboolean full_details = FALSE; const char *level_str = NULL; - g_return_if_fail (level < LOGL_MAX); + if ((guint) level >= LOGL_MAX) + g_return_if_reached (); _ensure_initialized (); @@ -431,18 +467,99 @@ _nm_log_impl (const char *file, g_return_if_reached (); } - if (full_details) { - g_get_current_time (&tv); - fullmsg = g_strdup_printf ("%-7s [%ld.%06ld] [%s:%u] %s(): %s", level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg); - } else - fullmsg = g_strdup_printf ("%-7s %s", level_str, msg); - switch (log_backend) { - case LOG_BACKEND_SYSLOG: - syslog (syslog_level, "%s", fullmsg); +#if SYSTEMD_JOURNAL + case LOG_BACKEND_JOURNAL: + { + gint64 now, boottime; +#define _NUM_MAX_FIELDS_SYSLOG_FACILITY 10 +#define _NUM_FIELDS (10 + _NUM_MAX_FIELDS_SYSLOG_FACILITY) + int i_field = 0; + struct iovec iov[_NUM_FIELDS]; + gboolean iov_free[_NUM_FIELDS]; + + now = nm_utils_get_monotonic_timestamp_ns (); + boottime = nm_utils_monotonic_timestamp_as_boottime (now, 1); + + _iovec_set_format (iov, iov_free, i_field++, "PRIORITY=%d", syslog_level); + _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s %s", level_str, 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 ()); + { + const LogDesc *diter; + int i_domain = _NUM_MAX_FIELDS_SYSLOG_FACILITY; + const char *s_domain_1 = NULL; + GString *s_domain_all = NULL; + NMLogDomain dom_all = domain; + NMLogDomain dom = dom_all & logging[level]; + + for (diter = &domain_descs[0]; diter->name; diter++) { + if (!NM_FLAGS_HAS (dom_all, diter->num)) + continue; + + /* construct a list of all domains (not only the enabled ones). + * Note that in by far most cases, there is only one domain present. + * Hence, save the construction of the GString. */ + dom_all &= ~diter->num; + if (!s_domain_1) + s_domain_1 = diter->name; + else { + if (!s_domain_all) + s_domain_all = g_string_new (s_domain_1); + g_string_append_c (s_domain_all, ','); + g_string_append (s_domain_all, diter->name); + } + + if (NM_FLAGS_HAS (dom, diter->num)) { + if (i_domain > 0) { + /* SYSLOG_FACILITY is specified multiple times for each domain that is actually enabled. */ + _iovec_set_format (iov, iov_free, i_field++, "SYSLOG_FACILITY=%s", diter->name); + i_domain--; + } + dom &= ~diter->num; + } + if (!dom && !dom_all) + break; + } + if (s_domain_all) { + _iovec_set_format (iov, iov_free, i_field++, "NM_LOG_DOMAINS=%s", s_domain_all->str); + g_string_free (s_domain_all, TRUE); + } else + _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", level_names[level]); + _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)); + if (error != 0) + _iovec_set_format (iov, iov_free, i_field++, "ERRNO=%d", error); + + nm_assert (i_field <= G_N_ELEMENTS (iov)); + + sd_journal_sendv (iov, i_field); + + for (; i_field > 0; ) { + i_field--; + if (iov_free[i_field]) + g_free (iov[i_field].iov_base); + } + } break; +#endif default: - g_log (G_LOG_DOMAIN, g_log_level, "%s", fullmsg); + if (full_details) { + g_get_current_time (&tv); + fullmsg = g_strdup_printf ("%-7s [%ld.%06ld] [%s:%u] %s(): %s", level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg); + } else + fullmsg = g_strdup_printf ("%-7s %s", level_str, msg); + + if (log_backend == LOG_BACKEND_SYSLOG) + syslog (syslog_level, "%s", fullmsg); + else + g_log (G_LOG_DOMAIN, g_log_level, "%s", fullmsg); + break; } g_free (msg); @@ -457,7 +574,7 @@ nm_log_handler (const gchar *log_domain, const gchar *message, gpointer ignored) { - int syslog_priority; + int syslog_priority; switch (level & G_LOG_LEVEL_MASK) { case G_LOG_LEVEL_ERROR: @@ -481,7 +598,32 @@ nm_log_handler (const gchar *log_domain, break; } - syslog (syslog_priority, "%s", message); + switch (log_backend) { +#if SYSTEMD_JOURNAL + case LOG_BACKEND_JOURNAL: + { + gint64 now, boottime; + + now = nm_utils_get_monotonic_timestamp_ns (); + boottime = nm_utils_monotonic_timestamp_as_boottime (now, 1); + + sd_journal_send ("PRIORITY=%d", syslog_priority, + "MESSAGE=%s", str_if_set (message, ""), + "SYSLOG_IDENTIFIER=%s", G_LOG_DOMAIN, + "SYSLOG_PID=%ld", (long) getpid (), + "SYSLOG_FACILITY=GLIB", + "GLIB_DOMAIN=%s", str_if_set (log_domain, ""), + "GLIB_LEVEL=%d", (int) (level & G_LOG_LEVEL_MASK), + "TIMESTAMP_MONOTONIC=%lld.%06lld", (long long) (now / NM_UTILS_NS_PER_SECOND), (long long) ((now % NM_UTILS_NS_PER_SECOND) / 1000), + "TIMESTAMP_BOOTTIME=%lld.%06lld", (long long) (boottime / NM_UTILS_NS_PER_SECOND), (long long) ((boottime % NM_UTILS_NS_PER_SECOND) / 1000), + NULL); + } + break; +#endif + default: + syslog (syslog_priority, "%s", str_if_set (message, "")); + break; + } } void @@ -490,12 +632,21 @@ nm_logging_syslog_openlog (gboolean debug) if (log_backend != LOG_BACKEND_GLIB) g_return_if_reached (); - log_backend = LOG_BACKEND_SYSLOG; - - if (debug) + if (debug) { + log_backend = LOG_BACKEND_SYSLOG; openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); - else +#if SYSTEMD_JOURNAL + } else if (TRUE) { + 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. */ + nm_utils_get_monotonic_timestamp_ns (); +#endif + } else { + log_backend = LOG_BACKEND_SYSLOG; 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, -- cgit v1.2.1 From 96a7f3a3bafa0cbdced4c5ff57767efa6335adfb Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 19:34:34 +0200 Subject: logging: make use of journal configurable --- man/NetworkManager.conf.xml.in | 12 ++++++++++++ src/devices/nm-device.c | 12 ++++++++++++ src/main.c | 7 ++++++- src/nm-config.h | 1 + src/nm-iface-helper.c | 6 +++++- src/nm-logging.c | 6 +++--- src/nm-logging.h | 2 +- 7 files changed, 40 insertions(+), 6 deletions(-) diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in index bf15c9e8b5..e16932228e 100644 --- a/man/NetworkManager.conf.xml.in +++ b/man/NetworkManager.conf.xml.in @@ -470,6 +470,18 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth + + backend + The logging backend. Supported values + are "debug", "syslog" and + "journal". "debug" uses syslog + and logs to standard error. + If NetworkManager is started in debug mode (--debug) + this option is ignored and we always use "debug". + Otherwise, the default is "journal" if NetworkManager + was compiled with systemd journal support. + + diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 415465ada2..913c48840b 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -8092,6 +8092,7 @@ nm_device_spawn_iface_helper (NMDevice *self) const char *method; GPtrArray *argv; gs_free char *dhcp4_address = NULL; + char *logging_backend; if (priv->state != NM_DEVICE_STATE_ACTIVATED) return; @@ -8110,6 +8111,17 @@ nm_device_spawn_iface_helper (NMDevice *self) g_ptr_array_add (argv, g_strdup ("--uuid")); g_ptr_array_add (argv, g_strdup (nm_connection_get_uuid (connection))); + logging_backend = nm_config_get_is_debug (nm_config_get ()) + ? g_strdup ("debug") + : nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_LOGGING, + NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND, + NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY); + if (logging_backend) { + g_ptr_array_add (argv, g_strdup ("--logging-backend")); + g_ptr_array_add (argv, logging_backend); + } + dhcp4_address = find_dhcp4_address (self); method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); diff --git a/src/main.c b/src/main.c index 7b1e522467..27babf81ec 100644 --- a/src/main.c +++ b/src/main.c @@ -386,7 +386,12 @@ main (int argc, char *argv[]) /* Set up unix signal handling - before creating threads, but after daemonizing! */ nm_main_utils_setup_signals (main_loop); - nm_logging_syslog_openlog (nm_config_get_is_debug (config)); + nm_logging_syslog_openlog (nm_config_get_is_debug (config) + ? "debug" + : nm_config_data_get_value_cached (NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_LOGGING, + NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND, + NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY)); nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting..."); diff --git a/src/nm-config.h b/src/nm-config.h index 113664e79e..870d4e4fe5 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -61,6 +61,7 @@ G_BEGIN_DECLS #define NM_CONFIG_KEYFILE_GROUP_IFUPDOWN "ifupdown" #define NM_CONFIG_KEYFILE_GROUP_IFNET "ifnet" +#define NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND "backend" #define NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS ".was" #define NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH "auto_refresh" #define NM_CONFIG_KEYFILE_KEY_IFNET_MANAGED "managed" diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 72b69590b4..bec6cc8359 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -72,6 +72,7 @@ static struct { char *dhcp4_clientid; char *dhcp4_hostname; char *iid_str; + char *logging_backend; char *opt_log_level; char *opt_log_domains; guint32 priority_v4; @@ -294,6 +295,7 @@ do_early_setup (int *argc, char **argv[]) { "priority4", '\0', 0, G_OPTION_ARG_INT64, &priority64_v4, N_("Route priority for IPv4"), N_("0") }, { "priority6", '\0', 0, G_OPTION_ARG_INT64, &priority64_v6, N_("Route priority for IPv6"), N_("1024") }, { "iid", 'e', 0, G_OPTION_ARG_STRING, &global_opt.iid_str, N_("Hex-encoded Interface Identifier"), "" }, + { "logging-backend", '\0', 0, G_OPTION_ARG_STRING, &global_opt.logging_backend, N_("The logging backend configuration value. See logging.backend in NetworkManager.conf"), NULL }, /* Logging/debugging */ { "version", 'V', 0, G_OPTION_ARG_NONE, &global_opt.show_version, N_("Print NetworkManager version and exit"), NULL }, @@ -405,7 +407,9 @@ main (int argc, char *argv[]) main_loop = g_main_loop_new (NULL, FALSE); setup_signals (); - nm_logging_syslog_openlog (global_opt.debug); + nm_logging_syslog_openlog (global_opt.logging_backend + ? global_opt.logging_backend + : (global_opt.debug ? "debug" : NULL)); nm_log_info (LOGD_CORE, "nm-iface-helper (version " NM_DIST_VERSION ") is starting..."); diff --git a/src/nm-logging.c b/src/nm-logging.c index 49f04220f2..d8a1811197 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -627,16 +627,16 @@ nm_log_handler (const gchar *log_domain, } void -nm_logging_syslog_openlog (gboolean debug) +nm_logging_syslog_openlog (const char *logging_backend) { if (log_backend != LOG_BACKEND_GLIB) g_return_if_reached (); - if (debug) { + if (g_strcmp0 (logging_backend, "debug") == 0) { log_backend = LOG_BACKEND_SYSLOG; openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); #if SYSTEMD_JOURNAL - } else if (TRUE) { + } else if (g_strcmp0 (logging_backend, "syslog") != 0) { log_backend = LOG_BACKEND_JOURNAL; /* ensure we read a monotonic timestamp. Reading the timestamp the first diff --git a/src/nm-logging.h b/src/nm-logging.h index 7ed966f85a..c34ef4559b 100644 --- a/src/nm-logging.h +++ b/src/nm-logging.h @@ -163,6 +163,6 @@ gboolean nm_logging_setup (const char *level, const char *domains, char **bad_domains, GError **error); -void nm_logging_syslog_openlog (gboolean debug); +void nm_logging_syslog_openlog (const char *logging_backend); #endif /* __NETWORKMANAGER_LOGGING_H__ */ -- cgit v1.2.1 From 533a08359e5a9e1fb7da3e3a0d19b44deb65707d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 21:37:35 +0200 Subject: logging: add "journal-syslog-style" logging backend to log the old format This mode logs the same message line as we do for "syslog". --- man/NetworkManager.conf.xml.in | 15 +++++++++------ src/nm-logging.c | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in index e16932228e..3b308253f8 100644 --- a/man/NetworkManager.conf.xml.in +++ b/man/NetworkManager.conf.xml.in @@ -473,13 +473,16 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth backend The logging backend. Supported values - are "debug", "syslog" and - "journal". "debug" uses syslog - and logs to standard error. + are "debug", "syslog", + "journal" and "journal-syslog-style. + "debug" uses syslog and logs to standard error. + "journal-syslog-style" prints the same message to journal + as it would print for "syslog", containing redudant + fields in the text. If NetworkManager is started in debug mode (--debug) - this option is ignored and we always use "debug". - Otherwise, the default is "journal" if NetworkManager - was compiled with systemd journal support. + this option is ignored and "debug" is always used. + Otherwise, the default is "journal-syslog-style" if + NetworkManager was compiled with systemd journal support. diff --git a/src/nm-logging.c b/src/nm-logging.c index d8a1811197..c1a81e0d0c 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -59,6 +59,7 @@ enum { LOG_BACKEND_GLIB, LOG_BACKEND_SYSLOG, LOG_BACKEND_JOURNAL, + LOG_BACKEND_JOURNAL_SYSLOG_STYLE, } log_backend = LOG_BACKEND_GLIB; static char *logging_domains_to_string; @@ -470,6 +471,7 @@ _nm_log_impl (const char *file, switch (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 @@ -482,7 +484,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", syslog_level); - _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s %s", level_str, msg); + if ( log_backend == LOG_BACKEND_JOURNAL_SYSLOG_STYLE + && full_details) { + g_get_current_time (&tv); + _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s [%ld.%06ld] [%s:%u] %s(): %s", level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg); + } else + _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s %s", level_str, 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 ()); { @@ -601,6 +608,7 @@ nm_log_handler (const gchar *log_domain, switch (log_backend) { #if SYSTEMD_JOURNAL case LOG_BACKEND_JOURNAL: + case LOG_BACKEND_JOURNAL_SYSLOG_STYLE: { gint64 now, boottime; @@ -637,7 +645,10 @@ nm_logging_syslog_openlog (const char *logging_backend) openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); #if SYSTEMD_JOURNAL } else if (g_strcmp0 (logging_backend, "syslog") != 0) { - log_backend = LOG_BACKEND_JOURNAL; + if (g_strcmp0 (logging_backend, "journal-syslog-style") != 0) + log_backend = LOG_BACKEND_JOURNAL; + else + log_backend = LOG_BACKEND_JOURNAL_SYSLOG_STYLE; /* 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. */ -- cgit v1.2.1 From f7581bbedcde79bc57617547b279613cd2ac6a35 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Jul 2015 21:44:01 +0200 Subject: logging: add compile time default for logging.backend configuration --- configure.ac | 22 +++++++++++++++++++++- man/NetworkManager.conf.xml.in | 3 +-- src/nm-logging.c | 9 ++++++--- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 11f6ccdaad..9d5ad54719 100644 --- a/configure.ac +++ b/configure.ac @@ -400,6 +400,26 @@ else AC_DEFINE([SYSTEMD_JOURNAL], 0, [Define to 1 if libsystemd-journald is available]) fi +AC_ARG_WITH(config-logging-backend-default, AS_HELP_STRING([--with-logging-backend-default=backend], [Default value for logging.backend]), nm_config_logging_backend_default="$withval", nm_config_logging_backend_default="") +if test "$nm_config_logging_backend_default" != 'debug' \ + -a "$nm_config_logging_backend_default" != 'syslog' \ + -a "$nm_config_logging_backend_default" != 'journal' \ + -a "$nm_config_logging_backend_default" != 'journal-syslog-style'; then + # unknown backend. Reset to default. Silently accept the invalid value to + # be future proof. + nm_config_logging_backend_default='' +fi +if test "$nm_config_logging_backend_default" = ""; then + if test "$have_systemd_journal" = "yes"; then + nm_config_logging_backend_default='journal-syslog-style' + else + nm_config_logging_backend_default='syslog' + fi +fi +AC_DEFINE_UNQUOTED(NM_CONFIG_LOGGING_BACKEND_DEFAULT, "$nm_config_logging_backend_default", [Default configuration option for logging.backend]) +NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT="$nm_config_logging_backend_default" +AC_SUBST(NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT) + # Session tracking support AC_ARG_WITH(systemd-logind, AS_HELP_STRING([--with-systemd-logind=yes|no], [Support systemd session tracking])) @@ -1115,7 +1135,7 @@ else fi echo " polkit agent: ${enable_polkit_agent}" echo " selinux: $have_selinux" -echo " systemd-journald: $have_systemd_journal" +echo " systemd-journald: $have_systemd_journal (logging.backend: ${nm_config_logging_backend_default})" echo " hostname persist: ${hostname_persist}" echo diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in index 3b308253f8..4d4c8a293f 100644 --- a/man/NetworkManager.conf.xml.in +++ b/man/NetworkManager.conf.xml.in @@ -481,8 +481,7 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth fields in the text. If NetworkManager is started in debug mode (--debug) this option is ignored and "debug" is always used. - Otherwise, the default is "journal-syslog-style" if - NetworkManager was compiled with systemd journal support. + Otherwise, the default is "@NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@". diff --git a/src/nm-logging.c b/src/nm-logging.c index c1a81e0d0c..17d820a3fb 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -640,12 +640,15 @@ nm_logging_syslog_openlog (const char *logging_backend) if (log_backend != LOG_BACKEND_GLIB) g_return_if_reached (); - if (g_strcmp0 (logging_backend, "debug") == 0) { + if (!logging_backend) + logging_backend = ""NM_CONFIG_LOGGING_BACKEND_DEFAULT; + + if (strcmp (logging_backend, "debug") == 0) { log_backend = LOG_BACKEND_SYSLOG; openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); #if SYSTEMD_JOURNAL - } else if (g_strcmp0 (logging_backend, "syslog") != 0) { - if (g_strcmp0 (logging_backend, "journal-syslog-style") != 0) + } else if (strcmp (logging_backend, "syslog") != 0) { + if (strcmp (logging_backend, "journal-syslog-style") != 0) log_backend = LOG_BACKEND_JOURNAL; else log_backend = LOG_BACKEND_JOURNAL_SYSLOG_STYLE; -- cgit v1.2.1 From 81f3c36f231c34132a542aaf37c0ffd7ee30baaf Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 9 Jul 2015 13:55:51 +0200 Subject: logging: refactor level conversion from switch() to @level_desc lookup-array --- src/nm-logging.c | 88 +++++++++++++++++++------------------------------------- 1 file changed, 29 insertions(+), 59 deletions(-) diff --git a/src/nm-logging.c b/src/nm-logging.c index 17d820a3fb..eed89dec06 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -68,12 +68,20 @@ typedef struct { const char *name; } LogDesc; -static const char *level_names[LOGL_MAX] = { - [LOGL_TRACE] = "TRACE", - [LOGL_DEBUG] = "DEBUG", - [LOGL_INFO] = "INFO", - [LOGL_WARN] = "WARN", - [LOGL_ERR] = "ERR", +typedef struct { + const char *name; + const char *level_str; + int syslog_level; + GLogLevelFlags g_log_level; + gboolean full_details; +} LogLevelDesc; + +static const LogLevelDesc level_desc[LOGL_MAX] = { + [LOGL_TRACE] = { "TRACE", "", LOG_DEBUG, G_LOG_LEVEL_DEBUG, TRUE }, + [LOGL_DEBUG] = { "DEBUG", "", LOG_INFO, G_LOG_LEVEL_DEBUG, TRUE }, + [LOGL_INFO] = { "INFO", "", LOG_INFO, G_LOG_LEVEL_MESSAGE, FALSE }, + [LOGL_WARN] = { "WARN", "", LOG_WARNING, G_LOG_LEVEL_WARNING, FALSE }, + [LOGL_ERR] = { "ERR", "", LOG_ERR, G_LOG_LEVEL_WARNING, TRUE }, }; static const LogDesc domain_descs[] = { @@ -141,7 +149,7 @@ match_log_level (const char *level, int i; for (i = 0; i < LOGL_MAX; i++) { - if (!g_ascii_strcasecmp (level_names[i], level)) { + if (!g_ascii_strcasecmp (level_desc[i].name, level)) { *out_level = i; return TRUE; } @@ -271,7 +279,7 @@ nm_logging_setup (const char *level, const char * nm_logging_level_to_string (void) { - return level_names[log_level]; + return level_desc[log_level].name; } const char * @@ -286,7 +294,7 @@ nm_logging_all_levels_to_string (void) for (i = 0; i < LOGL_MAX; i++) { if (str->len) g_string_append_c (str, ','); - g_string_append (str, level_names[i]); + g_string_append (str, level_desc[i].name); } } @@ -320,7 +328,7 @@ nm_logging_domains_to_string (void) /* 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]); + g_string_append_printf (str, ":%s", level_desc[i].name); break; } } @@ -328,7 +336,7 @@ nm_logging_domains_to_string (void) 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]); + g_string_append_printf (str, ":%s", level_desc[i].name); break; } } @@ -413,10 +421,6 @@ _nm_log_impl (const char *file, char *msg; char *fullmsg = NULL; GTimeVal tv; - int syslog_level = LOG_INFO; - int g_log_level = G_LOG_LEVEL_INFO; - gboolean full_details = FALSE; - const char *level_str = NULL; if ((guint) level >= LOGL_MAX) g_return_if_reached (); @@ -434,40 +438,6 @@ _nm_log_impl (const char *file, msg = g_strdup_vprintf (fmt, args); va_end (args); - switch (level) { - case LOGL_TRACE: - syslog_level = LOG_DEBUG; - g_log_level = G_LOG_LEVEL_DEBUG; - full_details = TRUE; - level_str = ""; - break; - case LOGL_DEBUG: - syslog_level = LOG_INFO; - g_log_level = G_LOG_LEVEL_DEBUG; - full_details = TRUE; - level_str = ""; - break; - case LOGL_INFO: - syslog_level = LOG_INFO; - g_log_level = G_LOG_LEVEL_MESSAGE; - level_str = ""; - break; - case LOGL_WARN: - syslog_level = LOG_WARNING; - g_log_level = G_LOG_LEVEL_WARNING; - level_str = ""; - 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; - full_details = TRUE; - level_str = ""; - break; - default: - g_return_if_reached (); - } - switch (log_backend) { #if SYSTEMD_JOURNAL case LOG_BACKEND_JOURNAL: @@ -483,13 +453,13 @@ _nm_log_impl (const char *file, now = nm_utils_get_monotonic_timestamp_ns (); boottime = nm_utils_monotonic_timestamp_as_boottime (now, 1); - _iovec_set_format (iov, iov_free, i_field++, "PRIORITY=%d", syslog_level); + _iovec_set_format (iov, iov_free, i_field++, "PRIORITY=%d", level_desc[level].syslog_level); if ( log_backend == LOG_BACKEND_JOURNAL_SYSLOG_STYLE - && full_details) { + && 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", level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg); + _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s [%ld.%06ld] [%s:%u] %s(): %s", 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", level_str, msg); + _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s %s", level_desc[level].level_str, 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 ()); { @@ -534,7 +504,7 @@ _nm_log_impl (const char *file, } else _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", level_names[level]); + _iovec_set_format (iov, iov_free, i_field++, "NM_LOG_LEVEL=%s", 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_LINE=%u", line); @@ -556,16 +526,16 @@ _nm_log_impl (const char *file, break; #endif default: - if (full_details) { + if (level_desc[level].full_details) { g_get_current_time (&tv); - fullmsg = g_strdup_printf ("%-7s [%ld.%06ld] [%s:%u] %s(): %s", level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg); + fullmsg = g_strdup_printf ("%-7s [%ld.%06ld] [%s:%u] %s(): %s", level_desc[level].level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg); } else - fullmsg = g_strdup_printf ("%-7s %s", level_str, msg); + fullmsg = g_strdup_printf ("%-7s %s", level_desc[level].level_str, msg); if (log_backend == LOG_BACKEND_SYSLOG) - syslog (syslog_level, "%s", fullmsg); + syslog (level_desc[level].syslog_level, "%s", fullmsg); else - g_log (G_LOG_DOMAIN, g_log_level, "%s", fullmsg); + g_log (G_LOG_DOMAIN, level_desc[level].g_log_level, "%s", fullmsg); break; } -- cgit v1.2.1