|
Packit Service |
87a54e |
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
Packit |
5756e2 |
/*
|
|
Packit |
5756e2 |
* Copyright (C) 2006 - 2012 Red Hat, Inc.
|
|
Packit |
5756e2 |
* Copyright (C) 2006 - 2008 Novell, Inc.
|
|
Packit |
5756e2 |
*/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-default.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-logging.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include <dlfcn.h>
|
|
Packit |
5756e2 |
#include <syslog.h>
|
|
Packit |
5756e2 |
#include <stdio.h>
|
|
Packit |
5756e2 |
#include <stdlib.h>
|
|
Packit |
5756e2 |
#include <unistd.h>
|
|
Packit |
5756e2 |
#include <sys/wait.h>
|
|
Packit |
5756e2 |
#include <sys/stat.h>
|
|
Packit |
5756e2 |
#include <strings.h>
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#if SYSTEMD_JOURNAL
|
|
Packit Service |
a1bd4f |
#define SD_JOURNAL_SUPPRESS_LOCATION
|
|
Packit Service |
a1bd4f |
#include <systemd/sd-journal.h>
|
|
Packit |
5756e2 |
#endif
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-glib-aux/nm-logging-base.h"
|
|
Packit |
5756e2 |
#include "nm-glib-aux/nm-time-utils.h"
|
|
Packit |
5756e2 |
#include "nm-errors.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/* Notes about thread-safety:
|
|
Packit |
5756e2 |
*
|
|
Packit |
5756e2 |
* NetworkManager generally is single-threaded and uses a (GLib) mainloop.
|
|
Packit |
5756e2 |
* However, nm-logging is in parts thread-safe. That means:
|
|
Packit |
5756e2 |
*
|
|
Packit |
5756e2 |
* - functions that configure logging (nm_logging_init(), nm_logging_setup()) and
|
|
Packit |
5756e2 |
* most other functions MUST be called only from the main-thread. These functions
|
|
Packit |
5756e2 |
* are expected to be called infrequently, so they may or may not use a mutex
|
|
Packit |
5756e2 |
* (but the overhead is negligible here).
|
|
Packit |
5756e2 |
*
|
|
Packit |
5756e2 |
* - functions that do the actual logging logging (nm_log(), nm_logging_enabled()) are
|
|
Packit |
5756e2 |
* thread-safe and may be used from multiple threads.
|
|
Packit |
5756e2 |
* - When called from the not-main-thread, @mt_require_locking must be set to %TRUE.
|
|
Packit |
5756e2 |
* In this case, a Mutex will be used for accessing the global state.
|
|
Packit |
5756e2 |
* - When called from the main-thread, they may optionally pass @mt_require_locking %FALSE.
|
|
Packit |
5756e2 |
* This avoids extra locking and is in particular interesting for nm_logging_enabled(),
|
|
Packit |
5756e2 |
* which is expected to be called frequently and from the main-thread.
|
|
Packit |
5756e2 |
*
|
|
Packit |
5756e2 |
* Note that the logging macros honor %NM_THREAD_SAFE_ON_MAIN_THREAD define, to automatically
|
|
Packit |
5756e2 |
* set @mt_require_locking. That means, by default %NM_THREAD_SAFE_ON_MAIN_THREAD is "1",
|
|
Packit |
5756e2 |
* and code that only runs on the main-thread (which is the majority), can get away
|
|
Packit |
5756e2 |
* without locking.
|
|
Packit |
5756e2 |
*/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(LOG_EMERG == 0);
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(LOG_ALERT == 1);
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(LOG_CRIT == 2);
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(LOG_ERR == 3);
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(LOG_WARNING == 4);
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(LOG_NOTICE == 5);
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(LOG_INFO == 6);
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(LOG_DEBUG == 7);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/* We have more then 32 logging domains. Assert that it compiles to a 64 bit sized enum */
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(sizeof(NMLogDomain) >= sizeof(guint64));
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/* Combined domains */
|
|
Packit |
5756e2 |
#define LOGD_ALL_STRING "ALL"
|
|
Packit |
5756e2 |
#define LOGD_DEFAULT_STRING "DEFAULT"
|
|
Packit |
5756e2 |
#define LOGD_DHCP_STRING "DHCP"
|
|
Packit |
5756e2 |
#define LOGD_IP_STRING "IP"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef enum {
|
|
Packit Service |
a1bd4f |
LOG_BACKEND_GLIB,
|
|
Packit Service |
a1bd4f |
LOG_BACKEND_SYSLOG,
|
|
Packit Service |
a1bd4f |
LOG_BACKEND_JOURNAL,
|
|
Packit |
5756e2 |
} LogBackend;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct {
|
|
Packit Service |
a1bd4f |
NMLogDomain num;
|
|
Packit Service |
a1bd4f |
const char *name;
|
|
Packit |
5756e2 |
} LogDesc;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct {
|
|
Packit Service |
a1bd4f |
char *logging_domains_to_string;
|
|
Packit |
5756e2 |
} GlobalMain;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct {
|
|
Packit Service |
a1bd4f |
NMLogLevel log_level;
|
|
Packit Service |
a1bd4f |
bool uses_syslog : 1;
|
|
Packit Service |
a1bd4f |
bool init_pre_done : 1;
|
|
Packit Service |
a1bd4f |
bool init_done : 1;
|
|
Packit Service |
a1bd4f |
bool debug_stderr : 1;
|
|
Packit Service |
a1bd4f |
const char *prefix;
|
|
Packit Service |
a1bd4f |
const char *syslog_identifier;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* before we setup syslog (during start), the backend defaults to GLIB, meaning:
|
|
Packit Service |
a1bd4f |
* we use g_log() for all logging. At that point, the application is not yet supposed
|
|
Packit Service |
a1bd4f |
* to do any logging and doing so indicates a bug.
|
|
Packit Service |
a1bd4f |
*
|
|
Packit Service |
a1bd4f |
* Afterwards, the backend is either SYSLOG or JOURNAL. From that point, also
|
|
Packit Service |
a1bd4f |
* g_log() is redirected to this backend via a logging handler. */
|
|
Packit Service |
a1bd4f |
LogBackend log_backend;
|
|
Packit |
5756e2 |
} Global;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_LOCK_DEFINE_STATIC(log);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/* This data must only be accessed from the main-thread (and as
|
|
Packit |
5756e2 |
* such does not need any lock). */
|
|
Packit Service |
a1bd4f |
static GlobalMain gl_main = {};
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static union {
|
|
Packit Service |
a1bd4f |
/* a union with an immutable and a mutable alias for the Global.
|
|
Packit Service |
a1bd4f |
* Since nm-logging must be thread-safe, we must take care at which
|
|
Packit Service |
a1bd4f |
* places we only read value ("imm") and where we modify them ("mut"). */
|
|
Packit Service |
a1bd4f |
Global mut;
|
|
Packit Service |
a1bd4f |
const Global imm;
|
|
Packit |
5756e2 |
} gl = {
|
|
Packit Service |
a1bd4f |
.imm =
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
/* nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL); */
|
|
Packit Service |
a1bd4f |
.log_level = LOGL_INFO,
|
|
Packit Service |
a1bd4f |
.log_backend = LOG_BACKEND_GLIB,
|
|
Packit Service |
a1bd4f |
.syslog_identifier = "SYSLOG_IDENTIFIER=" G_LOG_DOMAIN,
|
|
Packit Service |
a1bd4f |
.prefix = "",
|
|
Packit Service |
a1bd4f |
},
|
|
Packit |
5756e2 |
};
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
NMLogDomain _nm_logging_enabled_state[_LOGL_N_REAL] = {
|
|
Packit Service |
a1bd4f |
/* nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL);
|
|
Packit Service |
a1bd4f |
*
|
|
Packit Service |
a1bd4f |
* Note: LOGD_VPN_PLUGIN is special and must be disabled for
|
|
Packit Service |
a1bd4f |
* DEBUG and TRACE levels. */
|
|
Packit Service |
a1bd4f |
[LOGL_INFO] = LOGD_DEFAULT,
|
|
Packit Service |
a1bd4f |
[LOGL_WARN] = LOGD_DEFAULT,
|
|
Packit Service |
a1bd4f |
[LOGL_ERR] = LOGD_DEFAULT,
|
|
Packit |
5756e2 |
};
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static const LogDesc domain_desc[] = {
|
|
Packit Service |
a1bd4f |
{LOGD_PLATFORM, "PLATFORM"},
|
|
Packit Service |
a1bd4f |
{LOGD_RFKILL, "RFKILL"},
|
|
Packit Service |
a1bd4f |
{LOGD_ETHER, "ETHER"},
|
|
Packit Service |
a1bd4f |
{LOGD_WIFI, "WIFI"},
|
|
Packit Service |
a1bd4f |
{LOGD_BT, "BT"},
|
|
Packit Service |
a1bd4f |
{LOGD_MB, "MB"},
|
|
Packit Service |
a1bd4f |
{LOGD_DHCP4, "DHCP4"},
|
|
Packit Service |
a1bd4f |
{LOGD_DHCP6, "DHCP6"},
|
|
Packit Service |
a1bd4f |
{LOGD_PPP, "PPP"},
|
|
Packit Service |
a1bd4f |
{LOGD_WIFI_SCAN, "WIFI_SCAN"},
|
|
Packit Service |
a1bd4f |
{LOGD_IP4, "IP4"},
|
|
Packit Service |
a1bd4f |
{LOGD_IP6, "IP6"},
|
|
Packit Service |
a1bd4f |
{LOGD_AUTOIP4, "AUTOIP4"},
|
|
Packit Service |
a1bd4f |
{LOGD_DNS, "DNS"},
|
|
Packit Service |
a1bd4f |
{LOGD_VPN, "VPN"},
|
|
Packit Service |
a1bd4f |
{LOGD_SHARING, "SHARING"},
|
|
Packit Service |
a1bd4f |
{LOGD_SUPPLICANT, "SUPPLICANT"},
|
|
Packit Service |
a1bd4f |
{LOGD_AGENTS, "AGENTS"},
|
|
Packit Service |
a1bd4f |
{LOGD_SETTINGS, "SETTINGS"},
|
|
Packit Service |
a1bd4f |
{LOGD_SUSPEND, "SUSPEND"},
|
|
Packit Service |
a1bd4f |
{LOGD_CORE, "CORE"},
|
|
Packit Service |
a1bd4f |
{LOGD_DEVICE, "DEVICE"},
|
|
Packit Service |
a1bd4f |
{LOGD_OLPC, "OLPC"},
|
|
Packit Service |
a1bd4f |
{LOGD_INFINIBAND, "INFINIBAND"},
|
|
Packit Service |
a1bd4f |
{LOGD_FIREWALL, "FIREWALL"},
|
|
Packit Service |
a1bd4f |
{LOGD_ADSL, "ADSL"},
|
|
Packit Service |
a1bd4f |
{LOGD_BOND, "BOND"},
|
|
Packit Service |
a1bd4f |
{LOGD_VLAN, "VLAN"},
|
|
Packit Service |
a1bd4f |
{LOGD_BRIDGE, "BRIDGE"},
|
|
Packit Service |
a1bd4f |
{LOGD_DBUS_PROPS, "DBUS_PROPS"},
|
|
Packit Service |
a1bd4f |
{LOGD_TEAM, "TEAM"},
|
|
Packit Service |
a1bd4f |
{LOGD_CONCHECK, "CONCHECK"},
|
|
Packit Service |
a1bd4f |
{LOGD_DCB, "DCB"},
|
|
Packit Service |
a1bd4f |
{LOGD_DISPATCH, "DISPATCH"},
|
|
Packit Service |
a1bd4f |
{LOGD_AUDIT, "AUDIT"},
|
|
Packit Service |
a1bd4f |
{LOGD_SYSTEMD, "SYSTEMD"},
|
|
Packit Service |
a1bd4f |
{LOGD_VPN_PLUGIN, "VPN_PLUGIN"},
|
|
Packit Service |
a1bd4f |
{LOGD_PROXY, "PROXY"},
|
|
Packit Service |
a1bd4f |
{0},
|
|
Packit |
5756e2 |
};
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static char *_domains_to_string(gboolean include_level_override,
|
|
Packit Service |
a1bd4f |
NMLogLevel log_level,
|
|
Packit Service |
a1bd4f |
const NMLogDomain log_state[static _LOGL_N_REAL]);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit Service |
a1bd4f |
_syslog_identifier_valid_domain(const char *domain)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
char c;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!domain || !domain[0])
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* we pass the syslog identifier as format string. No funny stuff. */
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (; (c = domain[0]); domain++) {
|
|
Packit Service |
a1bd4f |
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
|
|
Packit Service |
a1bd4f |
|| NM_IN_SET(c, '-', '_'))
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
return TRUE;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit Service |
a1bd4f |
_syslog_identifier_assert(const char *syslog_identifier)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
g_assert(syslog_identifier);
|
|
Packit Service |
a1bd4f |
g_assert(g_str_has_prefix(syslog_identifier, "SYSLOG_IDENTIFIER="));
|
|
Packit Service |
a1bd4f |
g_assert(_syslog_identifier_valid_domain(&syslog_identifier[NM_STRLEN("SYSLOG_IDENTIFIER=")]));
|
|
Packit Service |
a1bd4f |
return TRUE;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static const char *
|
|
Packit Service |
a1bd4f |
syslog_identifier_domain(const char *syslog_identifier)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
nm_assert(_syslog_identifier_assert(syslog_identifier));
|
|
Packit Service |
a1bd4f |
return &syslog_identifier[NM_STRLEN("SYSLOG_IDENTIFIER=")];
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#if SYSTEMD_JOURNAL
|
|
Packit |
5756e2 |
static const char *
|
|
Packit Service |
a1bd4f |
syslog_identifier_full(const char *syslog_identifier)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
nm_assert(_syslog_identifier_assert(syslog_identifier));
|
|
Packit Service |
a1bd4f |
return &syslog_identifier[0];
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
#endif
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit Service |
a1bd4f |
match_log_level(const char *level, NMLogLevel *out_level, GError **error)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
if (_nm_log_parse_level(level, out_level))
|
|
Packit Service |
a1bd4f |
return TRUE;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_set_error(error,
|
|
Packit Service |
a1bd4f |
NM_MANAGER_ERROR,
|
|
Packit Service |
a1bd4f |
NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL,
|
|
Packit Service |
a1bd4f |
_("Unknown log level '%s'"),
|
|
Packit Service |
a1bd4f |
level);
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
gboolean
|
|
Packit Service |
a1bd4f |
nm_logging_setup(const char *level, const char *domains, char **bad_domains, GError **error)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
GString * unrecognized = NULL;
|
|
Packit Service |
a1bd4f |
NMLogDomain cur_log_state[_LOGL_N_REAL];
|
|
Packit Service |
a1bd4f |
NMLogDomain new_log_state[_LOGL_N_REAL];
|
|
Packit Service |
a1bd4f |
NMLogLevel cur_log_level;
|
|
Packit Service |
a1bd4f |
NMLogLevel new_log_level;
|
|
Packit Service |
a1bd4f |
gs_free const char **domains_v = NULL;
|
|
Packit Service |
a1bd4f |
gsize i_d;
|
|
Packit Service |
a1bd4f |
int i;
|
|
Packit Service |
a1bd4f |
gboolean had_platform_debug;
|
|
Packit Service |
a1bd4f |
gs_free char * domains_free = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
NM_ASSERT_ON_MAIN_THREAD();
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_return_val_if_fail(!bad_domains || !*bad_domains, FALSE);
|
|
Packit Service |
a1bd4f |
g_return_val_if_fail(!error || !*error, FALSE);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
cur_log_level = gl.imm.log_level;
|
|
Packit Service |
a1bd4f |
memcpy(cur_log_state, _nm_logging_enabled_state, sizeof(cur_log_state));
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
new_log_level = cur_log_level;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!domains || !*domains) {
|
|
Packit Service |
a1bd4f |
domains_free = _domains_to_string(FALSE, cur_log_level, cur_log_state);
|
|
Packit Service |
a1bd4f |
domains = domains_free;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (i = 0; i < G_N_ELEMENTS(new_log_state); i++)
|
|
Packit Service |
a1bd4f |
new_log_state[i] = 0;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (level && *level) {
|
|
Packit Service |
a1bd4f |
if (!match_log_level(level, &new_log_level, error))
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit Service |
a1bd4f |
if (new_log_level == _LOGL_KEEP) {
|
|
Packit Service |
a1bd4f |
new_log_level = cur_log_level;
|
|
Packit Service |
a1bd4f |
for (i = 0; i < G_N_ELEMENTS(new_log_state); i++)
|
|
Packit Service |
a1bd4f |
new_log_state[i] = cur_log_state[i];
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
domains_v = nm_utils_strsplit_set(domains, ", ");
|
|
Packit Service |
a1bd4f |
for (i_d = 0; domains_v && domains_v[i_d]; i_d++) {
|
|
Packit Service |
a1bd4f |
const char * s = domains_v[i_d];
|
|
Packit Service |
a1bd4f |
const char * p;
|
|
Packit Service |
a1bd4f |
const LogDesc *diter;
|
|
Packit Service |
a1bd4f |
NMLogLevel domain_log_level;
|
|
Packit Service |
a1bd4f |
NMLogDomain bits;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* LOGD_VPN_PLUGIN is protected, that is, when setting ALL or DEFAULT,
|
|
Packit Service |
a1bd4f |
* it does not enable the verbose levels DEBUG and TRACE, because that
|
|
Packit Service |
a1bd4f |
* may expose sensitive data. */
|
|
Packit Service |
a1bd4f |
NMLogDomain protect = LOGD_NONE;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
p = strchr(s, ':');
|
|
Packit Service |
a1bd4f |
if (p) {
|
|
Packit Service |
a1bd4f |
*((char *) p) = '\0';
|
|
Packit Service |
a1bd4f |
if (!match_log_level(p + 1, &domain_log_level, error))
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit Service |
a1bd4f |
} else
|
|
Packit Service |
a1bd4f |
domain_log_level = new_log_level;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
bits = 0;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (domains_free) {
|
|
Packit Service |
a1bd4f |
/* The caller didn't provide any domains to set (`nmcli general logging level DEBUG`).
|
|
Packit Service |
a1bd4f |
* We reset all domains that were previously set, but we still want to protect
|
|
Packit Service |
a1bd4f |
* VPN_PLUGIN domain. */
|
|
Packit Service |
a1bd4f |
protect = LOGD_VPN_PLUGIN;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Check for combined domains */
|
|
Packit Service |
a1bd4f |
if (!g_ascii_strcasecmp(s, LOGD_ALL_STRING)) {
|
|
Packit Service |
a1bd4f |
bits = LOGD_ALL;
|
|
Packit Service |
a1bd4f |
protect = LOGD_VPN_PLUGIN;
|
|
Packit Service |
a1bd4f |
} else if (!g_ascii_strcasecmp(s, LOGD_DEFAULT_STRING)) {
|
|
Packit Service |
a1bd4f |
bits = LOGD_DEFAULT;
|
|
Packit Service |
a1bd4f |
protect = LOGD_VPN_PLUGIN;
|
|
Packit Service |
a1bd4f |
} else if (!g_ascii_strcasecmp(s, LOGD_DHCP_STRING))
|
|
Packit Service |
a1bd4f |
bits = LOGD_DHCP;
|
|
Packit Service |
a1bd4f |
else if (!g_ascii_strcasecmp(s, LOGD_IP_STRING))
|
|
Packit Service |
a1bd4f |
bits = LOGD_IP;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Check for compatibility domains */
|
|
Packit Service |
a1bd4f |
else if (!g_ascii_strcasecmp(s, "HW"))
|
|
Packit Service |
a1bd4f |
bits = LOGD_PLATFORM;
|
|
Packit Service |
a1bd4f |
else if (!g_ascii_strcasecmp(s, "WIMAX"))
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
else {
|
|
Packit Service |
a1bd4f |
for (diter = &domain_desc[0]; diter->name; diter++) {
|
|
Packit Service |
a1bd4f |
if (!g_ascii_strcasecmp(diter->name, s)) {
|
|
Packit Service |
a1bd4f |
bits = diter->num;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!bits) {
|
|
Packit Service |
a1bd4f |
if (!bad_domains) {
|
|
Packit Service |
a1bd4f |
g_set_error(error,
|
|
Packit Service |
a1bd4f |
NM_MANAGER_ERROR,
|
|
Packit Service |
a1bd4f |
NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN,
|
|
Packit Service |
a1bd4f |
_("Unknown log domain '%s'"),
|
|
Packit Service |
a1bd4f |
s);
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (unrecognized)
|
|
Packit Service |
a1bd4f |
g_string_append(unrecognized, ", ");
|
|
Packit Service |
a1bd4f |
else
|
|
Packit Service |
a1bd4f |
unrecognized = g_string_new(NULL);
|
|
Packit Service |
a1bd4f |
g_string_append(unrecognized, s);
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (domain_log_level == _LOGL_KEEP) {
|
|
Packit Service |
a1bd4f |
for (i = 0; i < G_N_ELEMENTS(new_log_state); i++)
|
|
Packit Service |
a1bd4f |
new_log_state[i] = (new_log_state[i] & ~bits) | (cur_log_state[i] & bits);
|
|
Packit Service |
a1bd4f |
} else {
|
|
Packit Service |
a1bd4f |
for (i = 0; i < G_N_ELEMENTS(new_log_state); i++) {
|
|
Packit Service |
a1bd4f |
if (i < domain_log_level)
|
|
Packit Service |
a1bd4f |
new_log_state[i] &= ~bits;
|
|
Packit Service |
a1bd4f |
else {
|
|
Packit Service |
a1bd4f |
new_log_state[i] |= bits;
|
|
Packit Service |
a1bd4f |
if ((protect & bits) && i < LOGL_INFO)
|
|
Packit Service |
a1bd4f |
new_log_state[i] &= ~protect;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_clear_g_free(&gl_main.logging_domains_to_string);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
had_platform_debug = _nm_logging_enabled_lockfree(LOGL_DEBUG, LOGD_PLATFORM);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
G_LOCK(log);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
gl.mut.log_level = new_log_level;
|
|
Packit Service |
a1bd4f |
for (i = 0; i < G_N_ELEMENTS(new_log_state); i++)
|
|
Packit Service |
a1bd4f |
_nm_logging_enabled_state[i] = new_log_state[i];
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
G_UNLOCK(log);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (had_platform_debug && !_nm_logging_enabled_lockfree(LOGL_DEBUG, LOGD_PLATFORM)) {
|
|
Packit Service |
a1bd4f |
/* when debug logging is enabled, platform will cache all access to
|
|
Packit Service |
a1bd4f |
* sysctl. When the user disables debug-logging, we want to clear that
|
|
Packit Service |
a1bd4f |
* cache right away. */
|
|
Packit Service |
a1bd4f |
_nm_logging_clear_platform_logging_cache();
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (unrecognized)
|
|
Packit Service |
a1bd4f |
*bad_domains = g_string_free(unrecognized, FALSE);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return TRUE;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const char *
|
|
Packit Service |
a1bd4f |
nm_logging_level_to_string(void)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NM_ASSERT_ON_MAIN_THREAD();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return level_desc[gl.imm.log_level].name;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const char *
|
|
Packit Service |
a1bd4f |
nm_logging_all_levels_to_string(void)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
static GString *str;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (G_UNLIKELY(!str)) {
|
|
Packit Service |
a1bd4f |
int i;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
str = g_string_new(NULL);
|
|
Packit Service |
a1bd4f |
for (i = 0; i < G_N_ELEMENTS(level_desc); i++) {
|
|
Packit Service |
a1bd4f |
if (str->len)
|
|
Packit Service |
a1bd4f |
g_string_append_c(str, ',');
|
|
Packit Service |
a1bd4f |
g_string_append(str, level_desc[i].name);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return str->str;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const char *
|
|
Packit Service |
a1bd4f |
nm_logging_domains_to_string(void)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NM_ASSERT_ON_MAIN_THREAD();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (G_UNLIKELY(!gl_main.logging_domains_to_string)) {
|
|
Packit Service |
a1bd4f |
gl_main.logging_domains_to_string =
|
|
Packit Service |
a1bd4f |
_domains_to_string(TRUE, gl.imm.log_level, _nm_logging_enabled_state);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return gl_main.logging_domains_to_string;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static char *
|
|
Packit Service |
a1bd4f |
_domains_to_string(gboolean include_level_override,
|
|
Packit Service |
a1bd4f |
NMLogLevel log_level,
|
|
Packit Service |
a1bd4f |
const NMLogDomain log_state[static _LOGL_N_REAL])
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
const LogDesc *diter;
|
|
Packit Service |
a1bd4f |
GString * str;
|
|
Packit Service |
a1bd4f |
int i;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* We don't just return g_strdup() the logging domains that were set during
|
|
Packit Service |
a1bd4f |
* nm_logging_setup(), because we want to expand "DEFAULT" and "ALL".
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
str = g_string_sized_new(75);
|
|
Packit Service |
a1bd4f |
for (diter = &domain_desc[0]; diter->name; diter++) {
|
|
Packit Service |
a1bd4f |
/* If it's set for any lower level, it will also be set for LOGL_ERR */
|
|
Packit Service |
a1bd4f |
if (!(diter->num & log_state[LOGL_ERR]))
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (str->len)
|
|
Packit Service |
a1bd4f |
g_string_append_c(str, ',');
|
|
Packit Service |
a1bd4f |
g_string_append(str, diter->name);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!include_level_override)
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Check if it's logging at a lower level than the default. */
|
|
Packit Service |
a1bd4f |
for (i = 0; i < log_level; i++) {
|
|
Packit Service |
a1bd4f |
if (diter->num & log_state[i]) {
|
|
Packit Service |
a1bd4f |
g_string_append_printf(str, ":%s", level_desc[i].name);
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
/* Check if it's logging at a higher level than the default. */
|
|
Packit Service |
a1bd4f |
if (!(diter->num & log_state[log_level])) {
|
|
Packit Service |
a1bd4f |
for (i = log_level + 1; i < _LOGL_N_REAL; i++) {
|
|
Packit Service |
a1bd4f |
if (diter->num & log_state[i]) {
|
|
Packit Service |
a1bd4f |
g_string_append_printf(str, ":%s", level_desc[i].name);
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
return g_string_free(str, FALSE);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static char _all_logging_domains_to_str[273];
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
const char *
|
|
Packit Service |
a1bd4f |
nm_logging_all_domains_to_string(void)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
static const char *volatile str = NULL;
|
|
Packit Service |
a1bd4f |
const char *s;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
again:
|
|
Packit Service |
a1bd4f |
s = g_atomic_pointer_get(&str);
|
|
Packit Service |
a1bd4f |
if (G_UNLIKELY(!s)) {
|
|
Packit Service |
a1bd4f |
static gsize once = 0;
|
|
Packit Service |
a1bd4f |
const LogDesc *diter;
|
|
Packit Service |
a1bd4f |
gsize buf_l;
|
|
Packit Service |
a1bd4f |
char * buf_p;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!g_once_init_enter(&once))
|
|
Packit Service |
a1bd4f |
goto again;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
buf_p = _all_logging_domains_to_str;
|
|
Packit Service |
a1bd4f |
buf_l = sizeof(_all_logging_domains_to_str);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_utils_strbuf_append_str(&buf_p, &buf_l, LOGD_DEFAULT_STRING);
|
|
Packit Service |
a1bd4f |
for (diter = &domain_desc[0]; diter->name; diter++) {
|
|
Packit Service |
a1bd4f |
nm_utils_strbuf_append_c(&buf_p, &buf_l, ',');
|
|
Packit Service |
a1bd4f |
nm_utils_strbuf_append_str(&buf_p, &buf_l, diter->name);
|
|
Packit Service |
a1bd4f |
if (diter->num == LOGD_DHCP6)
|
|
Packit Service |
a1bd4f |
nm_utils_strbuf_append_str(&buf_p, &buf_l, "," LOGD_DHCP_STRING);
|
|
Packit Service |
a1bd4f |
else if (diter->num == LOGD_IP6)
|
|
Packit Service |
a1bd4f |
nm_utils_strbuf_append_str(&buf_p, &buf_l, "," LOGD_IP_STRING);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
nm_utils_strbuf_append_str(&buf_p, &buf_l, LOGD_ALL_STRING);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Did you modify the logging domains (or their names)? Adjust the size of
|
|
Packit Service |
a1bd4f |
* _all_logging_domains_to_str buffer above to have the exact size. */
|
|
Packit Service |
a1bd4f |
nm_assert(strlen(_all_logging_domains_to_str) == sizeof(_all_logging_domains_to_str) - 1);
|
|
Packit Service |
a1bd4f |
nm_assert(buf_l == 1);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
s = _all_logging_domains_to_str;
|
|
Packit Service |
a1bd4f |
g_atomic_pointer_set(&str, s);
|
|
Packit Service |
a1bd4f |
g_once_init_leave(&once, 1);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return s;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/**
|
|
Packit |
5756e2 |
* nm_logging_get_level:
|
|
Packit |
5756e2 |
* @domain: find the lowest enabled logging level for the
|
|
Packit |
5756e2 |
* given domain. If this is a set of multiple
|
|
Packit |
5756e2 |
* domains, the most verbose level will be returned.
|
|
Packit |
5756e2 |
*
|
|
Packit |
5756e2 |
* Returns: the lowest (most verbose) logging level for the
|
|
Packit |
5756e2 |
* give @domain, or %_LOGL_OFF if it is disabled.
|
|
Packit |
5756e2 |
**/
|
|
Packit |
5756e2 |
NMLogLevel
|
|
Packit Service |
a1bd4f |
nm_logging_get_level(NMLogDomain domain)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMLogLevel sl = _LOGL_OFF;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT(LOGL_TRACE == 0);
|
|
Packit Service |
a1bd4f |
while (sl > LOGL_TRACE && _nm_logging_enabled_lockfree(sl - 1, domain))
|
|
Packit Service |
a1bd4f |
sl--;
|
|
Packit Service |
a1bd4f |
return sl;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
gboolean
|
|
Packit Service |
a1bd4f |
_nm_logging_enabled_locking(NMLogLevel level, NMLogDomain domain)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
gboolean v;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_LOCK(log);
|
|
Packit Service |
a1bd4f |
v = _nm_logging_enabled_lockfree(level, domain);
|
|
Packit Service |
a1bd4f |
G_UNLOCK(log);
|
|
Packit Service |
a1bd4f |
return v;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
gboolean
|
|
Packit Service |
a1bd4f |
_nm_log_enabled_impl(gboolean mt_require_locking, NMLogLevel level, NMLogDomain domain)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
return nm_logging_enabled_mt(mt_require_locking, level, domain);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#if SYSTEMD_JOURNAL
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
_iovec_set(struct iovec *iov, const void *str, gsize len)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
iov->iov_base = (void *) str;
|
|
Packit Service |
a1bd4f |
iov->iov_len = len;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
_iovec_set_string(struct iovec *iov, const char *str)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
_iovec_set(iov, str, strlen(str));
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
#define _iovec_set_string_literal(iov, str) _iovec_set((iov), "" str "", NM_STRLEN(str))
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
_nm_printf(3, 4) static void _iovec_set_format(struct iovec *iov,
|
|
Packit Service |
a1bd4f |
char ** iov_free,
|
|
Packit Service |
a1bd4f |
const char * format,
|
|
Packit Service |
a1bd4f |
...)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
va_list ap;
|
|
Packit Service |
a1bd4f |
char * str;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
va_start(ap, format);
|
|
Packit Service |
a1bd4f |
str = g_strdup_vprintf(format, ap);
|
|
Packit Service |
a1bd4f |
va_end(ap);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
_iovec_set_string(iov, str);
|
|
Packit Service |
a1bd4f |
*iov_free = str;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
#define _iovec_set_format_a(iov, reserve_extra, format, ...) \
|
|
Packit Service |
a1bd4f |
G_STMT_START \
|
|
Packit Service |
a1bd4f |
{ \
|
|
Packit Service |
a1bd4f |
const gsize _size = (reserve_extra) + (NM_STRLEN(format) + 3); \
|
|
Packit Service |
a1bd4f |
char *const _buf = g_alloca(_size); \
|
|
Packit Service |
a1bd4f |
int _len; \
|
|
Packit Service |
a1bd4f |
\
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT_EXPR((reserve_extra) + (NM_STRLEN(format) + 3) <= 96); \
|
|
Packit Service |
a1bd4f |
\
|
|
Packit Service |
a1bd4f |
_len = g_snprintf(_buf, _size, "" format "", ##__VA_ARGS__); \
|
|
Packit Service |
a1bd4f |
\
|
|
Packit Service |
a1bd4f |
nm_assert(_len >= 0); \
|
|
Packit Service |
a1bd4f |
nm_assert(_len < _size); \
|
|
Packit Service |
a1bd4f |
nm_assert(_len == strlen(_buf)); \
|
|
Packit Service |
a1bd4f |
\
|
|
Packit Service |
a1bd4f |
_iovec_set((iov), _buf, _len); \
|
|
Packit Service |
a1bd4f |
} \
|
|
Packit Service |
a1bd4f |
G_STMT_END
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
#define _iovec_set_format_str_a(iov, max_str_len, format, str_arg) \
|
|
Packit Service |
a1bd4f |
G_STMT_START \
|
|
Packit Service |
a1bd4f |
{ \
|
|
Packit Service |
a1bd4f |
const char *_str_arg = (str_arg); \
|
|
Packit Service |
a1bd4f |
\
|
|
Packit Service |
a1bd4f |
nm_assert(_str_arg &&strlen(_str_arg) < (max_str_len)); \
|
|
Packit Service |
a1bd4f |
_iovec_set_format_a((iov), (max_str_len), format, str_arg); \
|
|
Packit Service |
a1bd4f |
} \
|
|
Packit Service |
a1bd4f |
G_STMT_END
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#endif
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
void
|
|
Packit Service |
a1bd4f |
_nm_log_impl(const char *file,
|
|
Packit Service |
a1bd4f |
guint line,
|
|
Packit Service |
a1bd4f |
const char *func,
|
|
Packit Service |
a1bd4f |
gboolean mt_require_locking,
|
|
Packit Service |
a1bd4f |
NMLogLevel level,
|
|
Packit Service |
a1bd4f |
NMLogDomain domain,
|
|
Packit Service |
a1bd4f |
int error,
|
|
Packit Service |
a1bd4f |
const char *ifname,
|
|
Packit Service |
a1bd4f |
const char *conn_uuid,
|
|
Packit Service |
a1bd4f |
const char *fmt,
|
|
Packit Service |
a1bd4f |
...)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
va_list args;
|
|
Packit Service |
a1bd4f |
char * msg;
|
|
Packit Service |
a1bd4f |
GTimeVal tv;
|
|
Packit Service |
a1bd4f |
int errsv;
|
|
Packit Service |
a1bd4f |
const NMLogDomain *cur_log_state;
|
|
Packit Service |
a1bd4f |
NMLogDomain cur_log_state_copy[_LOGL_N_REAL];
|
|
Packit Service |
a1bd4f |
Global g_copy;
|
|
Packit Service |
a1bd4f |
const Global * g;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (G_UNLIKELY(mt_require_locking)) {
|
|
Packit Service |
a1bd4f |
G_LOCK(log);
|
|
Packit Service |
a1bd4f |
/* we evaluate logging-enabled under lock. There is still a race that
|
|
Packit Service |
a1bd4f |
* we might log the message below *after* logging was disabled. That means,
|
|
Packit Service |
a1bd4f |
* when disabling logging, we might still log messages. */
|
|
Packit Service |
a1bd4f |
if (!_nm_logging_enabled_lockfree(level, domain)) {
|
|
Packit Service |
a1bd4f |
G_UNLOCK(log);
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
g_copy = gl.imm;
|
|
Packit Service |
a1bd4f |
memcpy(cur_log_state_copy, _nm_logging_enabled_state, sizeof(cur_log_state_copy));
|
|
Packit Service |
a1bd4f |
G_UNLOCK(log);
|
|
Packit Service |
a1bd4f |
g = &g_copy;
|
|
Packit Service |
a1bd4f |
cur_log_state = cur_log_state_copy;
|
|
Packit Service |
a1bd4f |
} else {
|
|
Packit Service |
a1bd4f |
NM_ASSERT_ON_MAIN_THREAD();
|
|
Packit Service |
a1bd4f |
if (!_nm_logging_enabled_lockfree(level, domain))
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
g = &gl.imm;
|
|
Packit Service |
a1bd4f |
cur_log_state = _nm_logging_enabled_state;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
(void) cur_log_state;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
errsv = errno;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Make sure that %m maps to the specified error */
|
|
Packit Service |
a1bd4f |
if (error != 0) {
|
|
Packit Service |
a1bd4f |
if (error < 0)
|
|
Packit Service |
a1bd4f |
error = -error;
|
|
Packit Service |
a1bd4f |
errno = error;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
va_start(args, fmt);
|
|
Packit Service |
a1bd4f |
msg = g_strdup_vprintf(fmt, args);
|
|
Packit Service |
a1bd4f |
va_end(args);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#define MESSAGE_FMT "%s%-7s [%ld.%04ld] %s"
|
|
Packit |
5756e2 |
#define MESSAGE_ARG(prefix, tv, msg) \
|
|
Packit Service |
a1bd4f |
prefix, level_desc[level].level_str, (tv).tv_sec, ((tv).tv_usec / 100), (msg)
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_get_current_time(&tv;;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (g->debug_stderr)
|
|
Packit Service |
a1bd4f |
g_printerr(MESSAGE_FMT "\n", MESSAGE_ARG(g->prefix, tv, msg));
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
switch (g->log_backend) {
|
|
Packit |
5756e2 |
#if SYSTEMD_JOURNAL
|
|
Packit Service |
a1bd4f |
case LOG_BACKEND_JOURNAL:
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
gint64 now, boottime;
|
|
Packit Service |
a1bd4f |
struct iovec iov_data[15];
|
|
Packit Service |
a1bd4f |
struct iovec * iov = iov_data;
|
|
Packit Service |
a1bd4f |
char * iov_free_data[5];
|
|
Packit Service |
a1bd4f |
char ** iov_free = iov_free_data;
|
|
Packit Service |
a1bd4f |
const LogDesc *diter;
|
|
Packit Service |
a1bd4f |
NMLogDomain dom_all;
|
|
Packit Service |
a1bd4f |
char s_log_domains_buf[NM_STRLEN("NM_LOG_DOMAINS=") + sizeof(_all_logging_domains_to_str)];
|
|
Packit Service |
a1bd4f |
char *s_log_domains;
|
|
Packit Service |
a1bd4f |
gsize l_log_domains;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
now = nm_utils_get_monotonic_timestamp_nsec();
|
|
Packit Service |
a1bd4f |
boottime = nm_utils_monotonic_timestamp_as_boottime(now, 1);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
_iovec_set_format_a(iov++, 30, "PRIORITY=%d", level_desc[level].syslog_level);
|
|
Packit Service |
a1bd4f |
_iovec_set_format(iov++,
|
|
Packit Service |
a1bd4f |
iov_free++,
|
|
Packit Service |
a1bd4f |
"MESSAGE=" MESSAGE_FMT,
|
|
Packit Service |
a1bd4f |
MESSAGE_ARG(g->prefix, tv, msg));
|
|
Packit Service |
a1bd4f |
_iovec_set_string(iov++, syslog_identifier_full(g->syslog_identifier));
|
|
Packit Service |
a1bd4f |
_iovec_set_format_a(iov++, 30, "SYSLOG_PID=%ld", (long) getpid());
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
dom_all = domain;
|
|
Packit Service |
a1bd4f |
s_log_domains = s_log_domains_buf;
|
|
Packit Service |
a1bd4f |
l_log_domains = sizeof(s_log_domains_buf);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_utils_strbuf_append_str(&s_log_domains, &l_log_domains, "NM_LOG_DOMAINS=");
|
|
Packit Service |
a1bd4f |
for (diter = &domain_desc[0]; dom_all != 0 && diter->name; diter++) {
|
|
Packit Service |
a1bd4f |
if (!NM_FLAGS_ANY(dom_all, diter->num))
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
if (dom_all != domain)
|
|
Packit Service |
a1bd4f |
nm_utils_strbuf_append_c(&s_log_domains, &l_log_domains, ',');
|
|
Packit Service |
a1bd4f |
nm_utils_strbuf_append_str(&s_log_domains, &l_log_domains, diter->name);
|
|
Packit Service |
a1bd4f |
dom_all &= ~diter->num;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
nm_assert(l_log_domains > 0);
|
|
Packit Service |
a1bd4f |
_iovec_set(iov++, s_log_domains_buf, s_log_domains - s_log_domains_buf);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
G_STATIC_ASSERT_EXPR(LOG_FAC(LOG_DAEMON) == 3);
|
|
Packit Service |
a1bd4f |
_iovec_set_string_literal(iov++, "SYSLOG_FACILITY=3");
|
|
Packit Service |
a1bd4f |
_iovec_set_format_str_a(iov++, 15, "NM_LOG_LEVEL=%s", level_desc[level].name);
|
|
Packit Service |
a1bd4f |
if (func)
|
|
Packit Service |
a1bd4f |
_iovec_set_format(iov++, iov_free++, "CODE_FUNC=%s", func);
|
|
Packit Service |
a1bd4f |
_iovec_set_format(iov++, iov_free++, "CODE_FILE=%s", file ?: "");
|
|
Packit Service |
a1bd4f |
_iovec_set_format_a(iov++, 20, "CODE_LINE=%u", line);
|
|
Packit Service |
a1bd4f |
_iovec_set_format_a(iov++,
|
|
Packit Service |
a1bd4f |
60,
|
|
Packit Service |
a1bd4f |
"TIMESTAMP_MONOTONIC=%lld.%06lld",
|
|
Packit Service |
a1bd4f |
(long long) (now / NM_UTILS_NSEC_PER_SEC),
|
|
Packit Service |
a1bd4f |
(long long) ((now % NM_UTILS_NSEC_PER_SEC) / 1000));
|
|
Packit Service |
a1bd4f |
_iovec_set_format_a(iov++,
|
|
Packit Service |
a1bd4f |
60,
|
|
Packit Service |
a1bd4f |
"TIMESTAMP_BOOTTIME=%lld.%06lld",
|
|
Packit Service |
a1bd4f |
(long long) (boottime / NM_UTILS_NSEC_PER_SEC),
|
|
Packit Service |
a1bd4f |
(long long) ((boottime % NM_UTILS_NSEC_PER_SEC) / 1000));
|
|
Packit Service |
a1bd4f |
if (error != 0)
|
|
Packit Service |
a1bd4f |
_iovec_set_format_a(iov++, 30, "ERRNO=%d", error);
|
|
Packit Service |
a1bd4f |
if (ifname)
|
|
Packit Service |
a1bd4f |
_iovec_set_format(iov++, iov_free++, "NM_DEVICE=%s", ifname);
|
|
Packit Service |
a1bd4f |
if (conn_uuid)
|
|
Packit Service |
a1bd4f |
_iovec_set_format(iov++, iov_free++, "NM_CONNECTION=%s", conn_uuid);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_assert(iov <= &iov_data[G_N_ELEMENTS(iov_data)]);
|
|
Packit Service |
a1bd4f |
nm_assert(iov_free <= &iov_free_data[G_N_ELEMENTS(iov_free_data)]);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
sd_journal_sendv(iov_data, iov - iov_data);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (; --iov_free >= iov_free_data;)
|
|
Packit Service |
a1bd4f |
g_free(*iov_free);
|
|
Packit Service |
a1bd4f |
} break;
|
|
Packit |
5756e2 |
#endif
|
|
Packit Service |
a1bd4f |
case LOG_BACKEND_SYSLOG:
|
|
Packit Service |
a1bd4f |
syslog(level_desc[level].syslog_level, MESSAGE_FMT, MESSAGE_ARG(g->prefix, tv, msg));
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
default:
|
|
Packit Service |
a1bd4f |
g_log(syslog_identifier_domain(g->syslog_identifier),
|
|
Packit Service |
a1bd4f |
level_desc[level].g_log_level,
|
|
Packit Service |
a1bd4f |
MESSAGE_FMT,
|
|
Packit Service |
a1bd4f |
MESSAGE_ARG(g->prefix, tv, msg));
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_free(msg);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
errno = errsv;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
void
|
|
Packit Service |
a1bd4f |
_nm_utils_monotonic_timestamp_initialized(const struct timespec *tp,
|
|
Packit Service |
a1bd4f |
gint64 offset_sec,
|
|
Packit Service |
a1bd4f |
gboolean is_boottime)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NM_ASSERT_ON_MAIN_THREAD();
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (_nm_logging_enabled_lockfree(LOGL_DEBUG, LOGD_CORE)) {
|
|
Packit Service |
a1bd4f |
time_t now = time(NULL);
|
|
Packit Service |
a1bd4f |
struct tm tm;
|
|
Packit Service |
a1bd4f |
char s[255];
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime_r(&now, &tm));
|
|
Packit Service |
a1bd4f |
nm_log_dbg(LOGD_CORE,
|
|
Packit Service |
a1bd4f |
"monotonic timestamp started counting 1.%09ld seconds ago with "
|
|
Packit Service |
a1bd4f |
"an offset of %lld.0 seconds to %s (local time is %s)",
|
|
Packit Service |
a1bd4f |
tp->tv_nsec,
|
|
Packit Service |
a1bd4f |
(long long) -offset_sec,
|
|
Packit Service |
a1bd4f |
is_boottime ? "CLOCK_BOOTTIME" : "CLOCK_MONOTONIC",
|
|
Packit Service |
a1bd4f |
s);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
nm_log_handler(const char *log_domain, GLogLevelFlags level, const char *message, gpointer ignored)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
int syslog_priority;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
switch (level & G_LOG_LEVEL_MASK) {
|
|
Packit Service |
a1bd4f |
case G_LOG_LEVEL_ERROR:
|
|
Packit Service |
a1bd4f |
syslog_priority = LOG_CRIT;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case G_LOG_LEVEL_CRITICAL:
|
|
Packit Service |
a1bd4f |
syslog_priority = LOG_ERR;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case G_LOG_LEVEL_WARNING:
|
|
Packit Service |
a1bd4f |
syslog_priority = LOG_WARNING;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case G_LOG_LEVEL_MESSAGE:
|
|
Packit Service |
a1bd4f |
syslog_priority = LOG_NOTICE;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case G_LOG_LEVEL_DEBUG:
|
|
Packit Service |
a1bd4f |
syslog_priority = LOG_DEBUG;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case G_LOG_LEVEL_INFO:
|
|
Packit Service |
a1bd4f |
default:
|
|
Packit Service |
a1bd4f |
syslog_priority = LOG_INFO;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* we don't need any locking here. The glib log handler gets only registered
|
|
Packit Service |
a1bd4f |
* once during nm_logging_init() and the global data is not modified afterwards. */
|
|
Packit Service |
a1bd4f |
nm_assert(gl.imm.init_done);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (gl.imm.debug_stderr)
|
|
Packit Service |
a1bd4f |
g_printerr("%s%s\n", gl.imm.prefix, message ?: "");
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
switch (gl.imm.log_backend) {
|
|
Packit |
5756e2 |
#if SYSTEMD_JOURNAL
|
|
Packit Service |
a1bd4f |
case LOG_BACKEND_JOURNAL:
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
gint64 now, boottime;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
now = nm_utils_get_monotonic_timestamp_nsec();
|
|
Packit Service |
a1bd4f |
boottime = nm_utils_monotonic_timestamp_as_boottime(now, 1);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
sd_journal_send("PRIORITY=%d",
|
|
Packit Service |
a1bd4f |
syslog_priority,
|
|
Packit Service |
a1bd4f |
"MESSAGE=%s%s",
|
|
Packit Service |
a1bd4f |
gl.imm.prefix,
|
|
Packit Service |
a1bd4f |
message ?: "",
|
|
Packit Service |
a1bd4f |
syslog_identifier_full(gl.imm.syslog_identifier),
|
|
Packit Service |
a1bd4f |
"SYSLOG_PID=%ld",
|
|
Packit Service |
a1bd4f |
(long) getpid(),
|
|
Packit Service |
a1bd4f |
"SYSLOG_FACILITY=3",
|
|
Packit Service |
a1bd4f |
"GLIB_DOMAIN=%s",
|
|
Packit Service |
a1bd4f |
log_domain ?: "",
|
|
Packit Service |
a1bd4f |
"GLIB_LEVEL=%d",
|
|
Packit Service |
a1bd4f |
(int) (level & G_LOG_LEVEL_MASK),
|
|
Packit Service |
a1bd4f |
"TIMESTAMP_MONOTONIC=%lld.%06lld",
|
|
Packit Service |
a1bd4f |
(long long) (now / NM_UTILS_NSEC_PER_SEC),
|
|
Packit Service |
a1bd4f |
(long long) ((now % NM_UTILS_NSEC_PER_SEC) / 1000),
|
|
Packit Service |
a1bd4f |
"TIMESTAMP_BOOTTIME=%lld.%06lld",
|
|
Packit Service |
a1bd4f |
(long long) (boottime / NM_UTILS_NSEC_PER_SEC),
|
|
Packit Service |
a1bd4f |
(long long) ((boottime % NM_UTILS_NSEC_PER_SEC) / 1000),
|
|
Packit Service |
a1bd4f |
NULL);
|
|
Packit Service |
a1bd4f |
} break;
|
|
Packit |
5756e2 |
#endif
|
|
Packit Service |
a1bd4f |
default:
|
|
Packit Service |
a1bd4f |
syslog(syslog_priority, "%s%s", gl.imm.prefix, message ?: "");
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
gboolean
|
|
Packit Service |
a1bd4f |
nm_logging_syslog_enabled(void)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NM_ASSERT_ON_MAIN_THREAD();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return gl.imm.uses_syslog;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
void
|
|
Packit Service |
a1bd4f |
nm_logging_init_pre(const char *syslog_identifier, char *prefix_take)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
/* this function may be called zero or one times, and only
|
|
Packit Service |
a1bd4f |
* - on the main thread
|
|
Packit Service |
a1bd4f |
* - not after nm_logging_init(). */
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
NM_ASSERT_ON_MAIN_THREAD();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (gl.imm.init_pre_done)
|
|
Packit Service |
a1bd4f |
g_return_if_reached();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (gl.imm.init_done)
|
|
Packit Service |
a1bd4f |
g_return_if_reached();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!_syslog_identifier_valid_domain(syslog_identifier))
|
|
Packit Service |
a1bd4f |
g_return_if_reached();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!prefix_take || !prefix_take[0])
|
|
Packit Service |
a1bd4f |
g_return_if_reached();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_LOCK(log);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
gl.mut.init_pre_done = TRUE;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
gl.mut.syslog_identifier = g_strdup_printf("SYSLOG_IDENTIFIER=%s", syslog_identifier);
|
|
Packit Service |
a1bd4f |
nm_assert(_syslog_identifier_assert(gl.imm.syslog_identifier));
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
/* we pass the allocated string on and never free it. */
|
|
Packit Service |
a1bd4f |
gl.mut.prefix = prefix_take;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_UNLOCK(log);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
void
|
|
Packit Service |
a1bd4f |
nm_logging_init(const char *logging_backend, gboolean debug)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
gboolean fetch_monotonic_timestamp = FALSE;
|
|
Packit Service |
a1bd4f |
gboolean obsolete_debug_backend = FALSE;
|
|
Packit Service |
a1bd4f |
LogBackend x_log_backend;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
/* this function may be called zero or one times, and only on the
|
|
Packit Service |
a1bd4f |
* main thread. */
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
NM_ASSERT_ON_MAIN_THREAD();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nm_assert(NM_IN_STRSET("" NM_CONFIG_DEFAULT_LOGGING_BACKEND,
|
|
Packit Service |
a1bd4f |
NM_LOG_CONFIG_BACKEND_JOURNAL,
|
|
Packit Service |
a1bd4f |
NM_LOG_CONFIG_BACKEND_SYSLOG));
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (gl.imm.init_done)
|
|
Packit Service |
a1bd4f |
g_return_if_reached();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!logging_backend)
|
|
Packit Service |
a1bd4f |
logging_backend = "" NM_CONFIG_DEFAULT_LOGGING_BACKEND;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (nm_streq(logging_backend, NM_LOG_CONFIG_BACKEND_DEBUG)) {
|
|
Packit Service |
a1bd4f |
/* "debug" was wrongly documented as a valid logging backend. It makes no sense however,
|
|
Packit Service |
a1bd4f |
* because printing to stderr only makes sense when not demonizing. Whether to daemonize
|
|
Packit Service |
a1bd4f |
* is only controlled via command line arguments (--no-daemon, --debug) and not via the
|
|
Packit Service |
a1bd4f |
* logging backend from configuration.
|
|
Packit Service |
a1bd4f |
*
|
|
Packit Service |
a1bd4f |
* Fall back to the default. */
|
|
Packit Service |
a1bd4f |
logging_backend = "" NM_CONFIG_DEFAULT_LOGGING_BACKEND;
|
|
Packit Service |
a1bd4f |
obsolete_debug_backend = TRUE;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_LOCK(log);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#if SYSTEMD_JOURNAL
|
|
Packit Service |
a1bd4f |
if (!nm_streq(logging_backend, NM_LOG_CONFIG_BACKEND_SYSLOG)) {
|
|
Packit Service |
a1bd4f |
x_log_backend = LOG_BACKEND_JOURNAL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
/* We only log the monotonic-timestamp with structured logging (journal).
|
|
Packit Service |
a1bd4f |
* Only in this case, fetch the timestamp. */
|
|
Packit Service |
a1bd4f |
fetch_monotonic_timestamp = TRUE;
|
|
Packit Service |
a1bd4f |
} else
|
|
Packit |
5756e2 |
#endif
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
x_log_backend = LOG_BACKEND_SYSLOG;
|
|
Packit Service |
a1bd4f |
openlog(syslog_identifier_domain(gl.imm.syslog_identifier), LOG_PID, LOG_DAEMON);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
gl.mut.init_done = TRUE;
|
|
Packit Service |
a1bd4f |
gl.mut.log_backend = x_log_backend;
|
|
Packit Service |
a1bd4f |
gl.mut.uses_syslog = TRUE;
|
|
Packit Service |
a1bd4f |
gl.mut.debug_stderr = debug;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_log_set_handler(syslog_identifier_domain(gl.imm.syslog_identifier),
|
|
Packit Service |
a1bd4f |
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
|
Packit Service |
a1bd4f |
nm_log_handler,
|
|
Packit Service |
a1bd4f |
NULL);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
G_UNLOCK(log);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (fetch_monotonic_timestamp) {
|
|
Packit Service |
a1bd4f |
/* ensure we read a monotonic timestamp. Reading the timestamp the first
|
|
Packit Service |
a1bd4f |
* time causes a logging message. We don't want to do that during _nm_log_impl. */
|
|
Packit Service |
a1bd4f |
nm_utils_get_monotonic_timestamp_nsec();
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (obsolete_debug_backend)
|
|
Packit Service |
a1bd4f |
nm_log_dbg(LOGD_CORE,
|
|
Packit Service |
a1bd4f |
"config: ignore deprecated logging backend 'debug', fallback to '%s'",
|
|
Packit Service |
a1bd4f |
logging_backend);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_streq(logging_backend, NM_LOG_CONFIG_BACKEND_SYSLOG)) {
|
|
Packit Service |
a1bd4f |
/* good */
|
|
Packit Service |
a1bd4f |
} else if (nm_streq(logging_backend, NM_LOG_CONFIG_BACKEND_JOURNAL)) {
|
|
Packit |
5756e2 |
#if !SYSTEMD_JOURNAL
|
|
Packit Service |
a1bd4f |
nm_log_warn(LOGD_CORE,
|
|
Packit Service |
a1bd4f |
"config: logging backend 'journal' is not available, fallback to 'syslog'");
|
|
Packit |
5756e2 |
#endif
|
|
Packit Service |
a1bd4f |
} else {
|
|
Packit Service |
a1bd4f |
nm_log_warn(LOGD_CORE,
|
|
Packit Service |
a1bd4f |
"config: invalid logging backend '%s', fallback to '%s'",
|
|
Packit Service |
a1bd4f |
logging_backend,
|
|
Packit |
5756e2 |
#if SYSTEMD_JOURNAL
|
|
Packit Service |
a1bd4f |
NM_LOG_CONFIG_BACKEND_JOURNAL
|
|
Packit |
5756e2 |
#else
|
|
Packit Service |
a1bd4f |
NM_LOG_CONFIG_BACKEND_SYSLOG
|
|
Packit |
5756e2 |
#endif
|
|
Packit Service |
a1bd4f |
);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
}
|