Skip to content

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
src/main: add optional syslog support
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
troglobit committed Jan 8, 2025
commit ccd2af807af6a583c82e62dbae769e65e2a1e125
13 changes: 7 additions & 6 deletions docs/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1288,12 +1288,13 @@ Command Line Tool
rauc [OPTION?] <COMMAND>

Options:
-c, --conf=FILENAME config file
--keyring=PEMFILE keyring file
--mount=PATH mount prefix
-d, --debug enable debug output
--version display version
-h, --help display help and exit
-c, --conf=FILENAME config file
--keyring=PEMFILE keyring file
--mount=PATH mount prefix
-d, --debug enable debug output
-s, --syslog=[facility] enable syslog output, optional facility, default: daemon
--version display version
-h, --help display help and exit

Command-specific help:
rauc <COMMAND> --help
Expand Down
64 changes: 64 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <locale.h>
#include <stdio.h>
#include <string.h>
#define SYSLOG_NAMES
Copy link
Member

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.

Copy link
Contributor Author

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.

#include <syslog.h>
#include <sys/ioctl.h>
#include <unistd.h>

Expand Down Expand Up @@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syslog(3) mentions that LOG_NOWAIT has no effect on Linux, so it could be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 syslogp(), as well as replacement syslog() API, this is one implementation that can replace the stanard C-library APIs for syslog.

There's no overhead to supporting LOG_NOWAIT, but if you only want to support GLIBC or standard C-library, that is fine and I can remove it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the effect of LOG_NOWAIT with sysklogd?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internally it will connect immediately to the /dev/log socket instead of postponing it until the first syslogd() call.

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;
Expand All @@ -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}
Expand Down
Loading