logging: merge branch 'th/logging-sd-journal-bgo752136'

https://bugzilla.gnome.org/show_bug.cgi?id=752136
This commit is contained in:
Thomas Haller 2015-07-14 15:59:13 +02:00
commit 59ca132b3a
12 changed files with 337 additions and 83 deletions

View file

@ -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

View file

@ -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>

View file

@ -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)

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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" },

View file

@ -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,

View file

@ -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);

View file

@ -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);
}

View file

@ -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__ */