mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-05 07:40:28 +01:00
logging: merge branch 'th/logging-sd-journal-bgo752136'
https://bugzilla.gnome.org/show_bug.cgi?id=752136
This commit is contained in:
commit
59ca132b3a
12 changed files with 337 additions and 83 deletions
45
configure.ac
45
configure.ac
|
|
@ -376,6 +376,50 @@ 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
|
||||
|
||||
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]))
|
||||
|
|
@ -1091,6 +1135,7 @@ else
|
|||
fi
|
||||
echo " polkit agent: ${enable_polkit_agent}"
|
||||
echo " selinux: $have_selinux"
|
||||
echo " systemd-journald: $have_systemd_journal (logging.backend: ${nm_config_logging_backend_default})"
|
||||
echo " hostname persist: ${hostname_persist}"
|
||||
echo
|
||||
|
||||
|
|
|
|||
|
|
@ -470,6 +470,20 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth
|
|||
</simplelist>
|
||||
</para>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>backend</varname></term>
|
||||
<listitem><para>The logging backend. Supported values
|
||||
are "<literal>debug</literal>", "<literal>syslog</literal>",
|
||||
"<literal>journal</literal>" and "<literal>journal-syslog-style</literal>.
|
||||
"<literal>debug</literal>" uses syslog and logs to standard error.
|
||||
"<literal>journal-syslog-style</literal>" prints the same message to journal
|
||||
as it would print for "<literal>syslog</literal>", containing redudant
|
||||
fields in the text.
|
||||
If NetworkManager is started in debug mode (<literal>--debug</literal>)
|
||||
this option is ignored and "<literal>debug</literal>" is always used.
|
||||
Otherwise, the default is "<literal>@NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@</literal>".
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
13
src/main.c
13
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,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 (global_opt.debug);
|
||||
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...");
|
||||
|
||||
|
|
@ -488,8 +491,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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -102,6 +103,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,
|
||||
|
|
|
|||
|
|
@ -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...");
|
||||
|
||||
|
|
@ -481,8 +485,6 @@ main (int argc, char *argv[])
|
|||
|
||||
g_clear_pointer (&hwaddr, g_byte_array_unref);
|
||||
|
||||
nm_logging_syslog_closelog ();
|
||||
|
||||
if (pidfile && wrote_pidfile)
|
||||
unlink (pidfile);
|
||||
|
||||
|
|
|
|||
288
src/nm-logging.c
288
src/nm-logging.c
|
|
@ -34,9 +34,16 @@
|
|||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#if SYSTEMD_JOURNAL
|
||||
#define SD_JOURNAL_SUPPRESS_LOCATION
|
||||
#include <systemd/sd-journal.h>
|
||||
#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,
|
||||
|
|
@ -48,7 +55,12 @@ 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_JOURNAL,
|
||||
LOG_BACKEND_JOURNAL_SYSLOG_STYLE,
|
||||
} log_backend = LOG_BACKEND_GLIB;
|
||||
static char *logging_domains_to_string;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -56,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", "<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 },
|
||||
};
|
||||
|
||||
static const LogDesc domain_descs[] = {
|
||||
|
|
@ -129,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;
|
||||
}
|
||||
|
|
@ -259,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 *
|
||||
|
|
@ -274,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -308,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -316,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -360,6 +380,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,
|
||||
|
|
@ -374,10 +421,9 @@ _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;
|
||||
|
||||
g_return_if_fail (level < LOGL_MAX);
|
||||
if ((guint) level >= LOGL_MAX)
|
||||
g_return_if_reached ();
|
||||
|
||||
_ensure_initialized ();
|
||||
|
||||
|
|
@ -392,44 +438,106 @@ _nm_log_impl (const char *file,
|
|||
msg = g_strdup_vprintf (fmt, args);
|
||||
va_end (args);
|
||||
|
||||
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 ("<trace> [%ld.%06ld] [%s:%u] %s(): %s", tv.tv_sec, tv.tv_usec, file, line, func, msg);
|
||||
break;
|
||||
case LOGL_DEBUG:
|
||||
g_get_current_time (&tv);
|
||||
syslog_level = LOG_INFO;
|
||||
g_log_level = G_LOG_LEVEL_DEBUG;
|
||||
fullmsg = g_strdup_printf ("<debug> [%ld.%06ld] [%s:%u] %s(): %s", tv.tv_sec, tv.tv_usec, file, line, 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);
|
||||
fullmsg = g_strdup_printf ("<error> [%ld.%06ld] [%s:%u] %s(): %s", tv.tv_sec, tv.tv_usec, file, line, func, msg);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
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
|
||||
#define _NUM_FIELDS (10 + _NUM_MAX_FIELDS_SYSLOG_FACILITY)
|
||||
int i_field = 0;
|
||||
struct iovec iov[_NUM_FIELDS];
|
||||
gboolean iov_free[_NUM_FIELDS];
|
||||
|
||||
if (syslog_opened)
|
||||
syslog (syslog_level, "%s", fullmsg);
|
||||
else
|
||||
g_log (G_LOG_DOMAIN, g_log_level, "%s", fullmsg);
|
||||
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", level_desc[level].syslog_level);
|
||||
if ( log_backend == LOG_BACKEND_JOURNAL_SYSLOG_STYLE
|
||||
&& 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_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_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 ());
|
||||
{
|
||||
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_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);
|
||||
_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:
|
||||
if (level_desc[level].full_details) {
|
||||
g_get_current_time (&tv);
|
||||
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_desc[level].level_str, msg);
|
||||
|
||||
if (log_backend == LOG_BACKEND_SYSLOG)
|
||||
syslog (level_desc[level].syslog_level, "%s", fullmsg);
|
||||
else
|
||||
g_log (G_LOG_DOMAIN, level_desc[level].g_log_level, "%s", fullmsg);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (msg);
|
||||
g_free (fullmsg);
|
||||
|
|
@ -443,7 +551,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:
|
||||
|
|
@ -467,30 +575,66 @@ nm_log_handler (const gchar *log_domain,
|
|||
break;
|
||||
}
|
||||
|
||||
syslog (syslog_priority, "%s", message);
|
||||
}
|
||||
switch (log_backend) {
|
||||
#if SYSTEMD_JOURNAL
|
||||
case LOG_BACKEND_JOURNAL:
|
||||
case LOG_BACKEND_JOURNAL_SYSLOG_STYLE:
|
||||
{
|
||||
gint64 now, boottime;
|
||||
|
||||
void
|
||||
nm_logging_syslog_openlog (gboolean debug)
|
||||
{
|
||||
if (debug)
|
||||
openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER);
|
||||
else
|
||||
openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON);
|
||||
now = nm_utils_get_monotonic_timestamp_ns ();
|
||||
boottime = nm_utils_monotonic_timestamp_as_boottime (now, 1);
|
||||
|
||||
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);
|
||||
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
|
||||
nm_logging_syslog_closelog (void)
|
||||
nm_logging_syslog_openlog (const char *logging_backend)
|
||||
{
|
||||
if (syslog_opened)
|
||||
closelog ();
|
||||
if (log_backend != LOG_BACKEND_GLIB)
|
||||
g_return_if_reached ();
|
||||
|
||||
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 (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;
|
||||
|
||||
/* 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,
|
||||
nm_log_handler,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +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_closelog (void);
|
||||
void nm_logging_syslog_openlog (const char *logging_backend);
|
||||
|
||||
#endif /* __NETWORKMANAGER_LOGGING_H__ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue