-
Notifications
You must be signed in to change notification settings - Fork 232
Optional syslog support #1590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Optional syslog support #1590
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
This patch adds an optional syslog backend alternative to the default stdout/stderr logging. The syslog backend is enabled with `--syslog` on the command line. It logs directly to the local syslog daemon, via the POSIX syslog() API, using a default 'daemon' facility. This facility can be changed if an optional argument is given, e.g., `--syslog=local0`. Useful for basic message filtering to a dedicated log file. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,8 @@ | |
#include <locale.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#define SYSLOG_NAMES | ||
#include <syslog.h> | ||
#include <sys/ioctl.h> | ||
#include <unistd.h> | ||
|
||
|
@@ -2646,6 +2648,67 @@ static void create_option_groups(void) | |
g_option_group_add_entries(service_group, entries_service); | ||
} | ||
|
||
static int log_level(GLogLevelFlags level) | ||
{ | ||
if (level & G_LOG_FLAG_FATAL) | ||
return LOG_EMERG; | ||
if (level & G_LOG_FLAG_RECURSION) | ||
return LOG_ALERT; | ||
if (level & G_LOG_LEVEL_CRITICAL) | ||
return LOG_CRIT; | ||
if (level & G_LOG_LEVEL_ERROR) | ||
return LOG_ERR; | ||
if (level & G_LOG_LEVEL_WARNING) | ||
return LOG_WARNING; | ||
if (level & G_LOG_LEVEL_MESSAGE) | ||
return LOG_NOTICE; | ||
if (level & G_LOG_LEVEL_INFO) | ||
return LOG_INFO; | ||
if (level & G_LOG_LEVEL_DEBUG) | ||
return LOG_DEBUG; | ||
|
||
return LOG_INFO; /* Fallback to INFO for unknown levels */ | ||
} | ||
|
||
static void syslog_handler(const gchar *domain, GLogLevelFlags level, const gchar *message, gpointer arg) | ||
{ | ||
int prio = log_level(level); | ||
|
||
if (g_strcmp0(domain, G_LOG_DOMAIN)) | ||
syslog(prio, "%s: %s", domain, message); | ||
else | ||
syslog(prio, "%s", message); | ||
} | ||
|
||
static gboolean syslog_option_cb(const gchar *option_name, const gchar *value, | ||
gpointer data, GError **error) | ||
{ | ||
int facility = LOG_DAEMON; | ||
|
||
if (value) { | ||
gboolean found = FALSE; | ||
|
||
for (const CODE *f = facilitynames; f->c_name != NULL; f++) { | ||
if (g_ascii_strcasecmp(value, f->c_name) == 0) { | ||
facility = f->c_val; | ||
found = TRUE; | ||
break; | ||
} | ||
} | ||
|
||
if (!found) { | ||
g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, | ||
"Invalid syslog facility: %s", value); | ||
return FALSE; | ||
} | ||
} | ||
|
||
openlog(G_LOG_DOMAIN, LOG_PID | LOG_NOWAIT, facility); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, it depends a bit on the backend. I maintain sysklogd, which today supplies an RFC5424 compliant There's no overhead to supporting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the effect of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Internally it will connect immediately to the |
||
g_log_set_default_handler(syslog_handler, NULL); | ||
|
||
return TRUE; | ||
} | ||
|
||
static void cmdline_handler(int argc, char **argv) | ||
{ | ||
gboolean help = FALSE, debug = FALSE, version = FALSE; | ||
|
@@ -2661,6 +2724,7 @@ static void cmdline_handler(int argc, char **argv) | |
{"intermediate", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &intermediate, "intermediate CA file or PKCS#11 URL", "PEMFILE|PKCS11-URL"}, | ||
{"mount", '\0', 0, G_OPTION_ARG_FILENAME, &mount, "mount prefix", "PATH"}, | ||
{"debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "enable debug output", NULL}, | ||
{"syslog", 's', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, syslog_option_cb, "enable syslog output, optional facility, default: daemon", "[facility]"}, | ||
{"version", '\0', 0, G_OPTION_ARG_NONE, &version, "display version", NULL}, | ||
{"help", 'h', 0, G_OPTION_ARG_NONE, &help, "display help and exit", NULL}, | ||
{0} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really needed? https://sourceware.org/bugzilla/show_bug.cgi?id=16355 sounds like we should avoid this define.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The define opens up the use of
facilitynames[]
. It has been a long standing practice, but we can replace that with a local array of the same names if you want.