logging: add basic logging capabilities

This commit is contained in:
Dan Williams
2010-04-06 15:23:08 -07:00
parent 043ce2c655
commit 32128b04ca
3 changed files with 230 additions and 41 deletions

View File

@@ -442,6 +442,7 @@ main (int argc, char *argv[])
gboolean g_fatal_warnings = FALSE; gboolean g_fatal_warnings = FALSE;
char *pidfile = NULL, *state_file = NULL, *dhcp = NULL; char *pidfile = NULL, *state_file = NULL, *dhcp = NULL;
char *config = NULL, *plugins = NULL, *conf_plugins = NULL; char *config = NULL, *plugins = NULL, *conf_plugins = NULL;
char *log_level = NULL, *log_domains = NULL;
gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE; gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE;
gboolean success; gboolean success;
NMPolicy *policy = NULL; NMPolicy *policy = NULL;
@@ -460,6 +461,10 @@ main (int argc, char *argv[])
{ "state-file", 0, 0, G_OPTION_ARG_FILENAME, &state_file, "State file location", "/path/to/state.file" }, { "state-file", 0, 0, G_OPTION_ARG_FILENAME, &state_file, "State file location", "/path/to/state.file" },
{ "config", 0, 0, G_OPTION_ARG_FILENAME, &config, "Config file location", "/path/to/config.file" }, { "config", 0, 0, G_OPTION_ARG_FILENAME, &config, "Config file location", "/path/to/config.file" },
{ "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ,", "plugin1,plugin2" }, { "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ,", "plugin1,plugin2" },
{ "log-level", 0, 0, G_OPTION_ARG_STRING, &log_level, "Log level: one of [ERR, WARN, INFO, DEBUG]", "INFO" },
{ "log-domain", 0, 0, G_OPTION_ARG_STRING, &log_domains,
"Log domains separated by ,: any combination of [HW,RKILL,ETHER,WIFI,BT,MB,DHCP4,DHCP6,PPP,WIFI_SCAN,IP4,IP6,AUTOIP4,DNS,VPN,SHARING,SUPPLICANT,USER_SET,SYS_SET,SUSPEND,CORE]",
"HW,RFKILL,WIFI" },
{NULL} {NULL}
}; };
@@ -495,6 +500,14 @@ main (int argc, char *argv[])
exit (1); exit (1);
} }
/* Logging setup */
if (!nm_logging_setup (log_level, log_domains, &error)) {
fprintf (stderr,
_("%s. Please use --help to see a list of valid options.\n"),
error->message);
exit (1);
}
pidfile = pidfile ? pidfile : g_strdup (NM_DEFAULT_PID_FILE); pidfile = pidfile ? pidfile : g_strdup (NM_DEFAULT_PID_FILE);
state_file = state_file ? state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE); state_file = state_file ? state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE);
@@ -600,7 +613,7 @@ main (int argc, char *argv[])
setup_signals (); setup_signals ();
nm_logging_setup (become_daemon); nm_logging_start (become_daemon);
nm_info ("starting..."); nm_info ("starting...");
success = FALSE; success = FALSE;

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright (C) 2006 - 2008 Red Hat, Inc. * Copyright (C) 2006 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc. * Copyright (C) 2006 - 2008 Novell, Inc.
*/ */
@@ -30,10 +30,150 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <execinfo.h> #include <execinfo.h>
#include <strings.h>
#include <string.h>
#include <glib/gi18n.h>
#include "nm-logging.h" #include "nm-logging.h"
#include "nm-utils.h" #include "nm-utils.h"
static guint32 log_level = LOGL_ERR;
static guint32 log_domains = LOGD_CORE & LOGD_HW;
typedef struct {
guint32 num;
const char *name;
} LogDesc;
static const LogDesc level_descs[] = {
{ LOGL_ERR, "ERR" },
{ LOGL_WARN, "WARN" },
{ LOGL_INFO, "INFO" },
{ LOGL_DEBUG, "DEBUG" },
{ 0, NULL }
};
static const LogDesc domain_descs[] = {
{ LOGD_HW, "HW" },
{ LOGD_RFKILL, "RFKILL" },
{ LOGD_ETHER, "ETHER" },
{ LOGD_WIFI, "WIFI" },
{ LOGD_BT, "BT" },
{ LOGD_MB, "MB" },
{ LOGD_DHCP4, "DHCP4" },
{ LOGD_DHCP6, "DHCP6" },
{ LOGD_PPP, "PPP" },
{ LOGD_WIFI_SCAN, "WIFI_SCAN" },
{ LOGD_IP4, "IP4" },
{ LOGD_IP6, "IP6" },
{ LOGD_AUTOIP4, "AUTOIP4" },
{ LOGD_DNS, "DNS" },
{ LOGD_VPN, "VPN" },
{ LOGD_SHARING, "SHARING" },
{ LOGD_SUPPLICANT,"SUPPLICANT" },
{ LOGD_USER_SET, "USER_SET" },
{ LOGD_SYS_SET, "SYS_SET" },
{ LOGD_SUSPEND, "SUSPEND" },
{ LOGD_CORE, "CORE" },
{ 0, NULL }
};
/************************************************************************/
gboolean
nm_logging_setup (const char *level, const char *domains, GError **error)
{
char **tmp, **iter;
guint32 new_level = 0;
guint32 new_domains = 0;
/* levels */
if (level && strlen (level)) {
tmp = g_strsplit (level, ",", 0);
for (iter = tmp; iter && *iter; iter++) {
const LogDesc *diter;
gboolean found = FALSE;
for (diter = &level_descs[0]; diter->name; diter++) {
if (!strcasecmp (diter->name, *iter)) {
new_level &= diter->num;
found = TRUE;
break;
}
}
if (!found) {
g_set_error (error, 0, 0, _("Unknown log level '%s'"), *iter);
return FALSE;
}
}
g_strfreev (tmp);
log_level = new_level;
}
/* domains */
if (domains && strlen (domains)) {
tmp = g_strsplit (domains, ",", 0);
for (iter = tmp; iter && *iter; iter++) {
const LogDesc *diter;
gboolean found = FALSE;
for (diter = &domain_descs[0]; diter->name; diter++) {
if (!strcasecmp (diter->name, *iter)) {
new_domains &= diter->num;
found = TRUE;
break;
}
}
if (!found) {
g_set_error (error, 0, 0, _("Unknown log domain '%s'"), *iter);
return FALSE;
}
}
g_strfreev (tmp);
log_domains = new_domains;
}
return TRUE;
}
void _nm_log (const char *loc,
const char *func,
guint32 domain,
guint32 level,
const char *fmt,
...)
{
va_list args;
char *msg;
GTimeVal tv;
if (!(log_level & level) || !(log_domains & domain))
return;
va_start (args, fmt);
msg = g_strdup_vprintf (fmt, args);
va_end (args);
if (log_level & LOGL_DEBUG) {
g_get_current_time (&tv);
syslog (LOG_DEBUG, "<debug> [%zu.%zu] [%s] %s(): %s\n", tv.tv_sec, tv.tv_usec, loc, func, msg);
} else if (log_level & LOGL_INFO)
syslog (LOG_INFO, "<info> [%s] %s(): %s\n", loc, func, msg);
else if (log_level & LOGL_WARN)
syslog (LOG_WARNING, "<warn> [%s] %s(): %s\n", loc, func, msg);
else if (log_level & LOGL_ERR) {
g_get_current_time (&tv);
syslog (LOG_ERR, "<error> [%zu.%zu] [%s] %s(): %s\n", tv.tv_sec, tv.tv_usec, loc, func, msg);
}
g_free (msg);
}
/************************************************************************/
static void static void
fallback_get_backtrace (void) fallback_get_backtrace (void)
{ {
@@ -115,47 +255,40 @@ nm_logging_backtrace (void)
static void static void
nm_log_handler (const gchar * log_domain, nm_log_handler (const gchar *log_domain,
GLogLevelFlags log_level, GLogLevelFlags level,
const gchar * message, const gchar *message,
gpointer ignored) gpointer ignored)
{ {
int syslog_priority; int syslog_priority;
switch (log_level) switch (level) {
{ case G_LOG_LEVEL_ERROR:
case G_LOG_LEVEL_ERROR: syslog_priority = LOG_CRIT;
syslog_priority = LOG_CRIT; break;
break; case G_LOG_LEVEL_CRITICAL:
syslog_priority = LOG_ERR;
case G_LOG_LEVEL_CRITICAL: break;
syslog_priority = LOG_ERR; case G_LOG_LEVEL_WARNING:
break; syslog_priority = LOG_WARNING;
break;
case G_LOG_LEVEL_WARNING: case G_LOG_LEVEL_MESSAGE:
syslog_priority = LOG_WARNING; syslog_priority = LOG_NOTICE;
break; break;
case G_LOG_LEVEL_DEBUG:
case G_LOG_LEVEL_MESSAGE: syslog_priority = LOG_DEBUG;
syslog_priority = LOG_NOTICE; break;
break; case G_LOG_LEVEL_INFO:
default:
case G_LOG_LEVEL_DEBUG: syslog_priority = LOG_INFO;
syslog_priority = LOG_DEBUG; break;
break;
case G_LOG_LEVEL_INFO:
default:
syslog_priority = LOG_INFO;
break;
} }
syslog (syslog_priority, "%s", message); syslog (syslog_priority, "%s", message);
} }
void void
nm_logging_setup (gboolean become_daemon) nm_logging_start (gboolean become_daemon)
{ {
if (become_daemon) if (become_daemon)
openlog (G_LOG_DOMAIN, 0, LOG_DAEMON); openlog (G_LOG_DOMAIN, 0, LOG_DAEMON);
@@ -163,9 +296,9 @@ nm_logging_setup (gboolean become_daemon)
openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR, LOG_USER); openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR, LOG_USER);
g_log_set_handler (G_LOG_DOMAIN, g_log_set_handler (G_LOG_DOMAIN,
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
nm_log_handler, nm_log_handler,
NULL); NULL);
} }
void void

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright (C) 2006 - 2008 Red Hat, Inc. * Copyright (C) 2006 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc. * Copyright (C) 2006 - 2008 Novell, Inc.
*/ */
@@ -24,8 +24,51 @@
#include <glib.h> #include <glib.h>
void nm_logging_setup (gboolean become_daemon); /* Log domains */
void nm_logging_backtrace (void); enum {
void nm_logging_shutdown (void); LOGD_NONE = 0x00000000,
LOGD_HW = 0x00000001,
LOGD_RFKILL = 0x00000002,
LOGD_ETHER = 0x00000004,
LOGD_WIFI = 0x00000008,
LOGD_BT = 0x00000010,
LOGD_MB = 0x00000020, /* mobile broadband */
LOGD_DHCP4 = 0x00000040,
LOGD_DHCP6 = 0x00000080,
LOGD_PPP = 0x00000100,
LOGD_WIFI_SCAN = 0x00000200,
LOGD_IP4 = 0x00000400,
LOGD_IP6 = 0x00000800,
LOGD_AUTOIP4 = 0x00001000,
LOGD_DNS = 0x00002000,
LOGD_VPN = 0x00004000,
LOGD_SHARING = 0x00008000,
LOGD_SUPPLICANT = 0x00010000,
LOGD_USER_SET = 0x00020000,
LOGD_SYS_SET = 0x00040000,
LOGD_SUSPEND = 0x00080000,
LOGD_CORE = 0x00100000, /* Core daemon and policy stuff */
};
/* Log levels */
enum {
LOGL_ERR = 0x00000000,
LOGL_WARN = 0x00000001,
LOGL_INFO = 0x00000002,
LOGL_DEBUG = 0x00000004
};
#define nm_log(domain, level, fmt, args...) \
{ _nm_log (G_STRFUNC, G_STRLOC, domain, level, fmt, ##args); }
void _nm_log (const char *func, const char *loc,
guint32 domain, guint32 level,
const char *fmt, ...);
gboolean nm_logging_setup (const char *level, const char *domains, GError **error);
void nm_logging_start (gboolean become_daemon);
void nm_logging_backtrace (void);
void nm_logging_shutdown (void);
#endif /* NM_LOGGING_H */ #endif /* NM_LOGGING_H */