From b29a3c4d11ec1cf778b253e3c3fbbf04b0794f86 Mon Sep 17 00:00:00 2001 From: Duncaen Date: Wed, 1 Mar 2017 19:15:03 +0100 Subject: Add vlogger(8) vlogger(8) is a alternative to logger(1), by default it sends messages from stdin to syslog. The main reason to replace logger(1) is, that logger only connects once to the syslog socket in default mode and puts all messages into the void if syslog is not running at the time. logger(1) has a new `--socket-errors=on` mode which would work, but some void uses don't use syslog at all and in this case the log service would constantly restart. As a bonus vlogger(8) looks for /etc/vlogger and if its executable it just executes it and is replaced by it. This can be used to avoid syslog and just write all logs to files with svlogd(8) as example, without having to edit all log services. --- .gitignore | 1 + Makefile | 2 + vlogger.8 | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vlogger.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 252 insertions(+) create mode 100644 vlogger.8 create mode 100644 vlogger.c diff --git a/.gitignore b/.gitignore index ed231ec..2440471 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ halt pause +vlogger diff --git a/Makefile b/Makefile index a21e5c9..001c17b 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ SCRIPTS= 1 2 3 ctrlaltdel all: $(CC) $(CFLAGS) halt.c -o halt $(LDFLAGS) $(CC) $(CFLAGS) pause.c -o pause $(LDFLAGS) + $(CC) $(CFLAGS) vlogger.c -o vlogger $(LDFLAGS) install: install -d ${DESTDIR}/${PREFIX}/sbin @@ -22,6 +23,7 @@ install: install -m644 shutdown.8 ${DESTDIR}/${PREFIX}/share/man/man8 install -m644 halt.8 ${DESTDIR}/${PREFIX}/share/man/man8 install -m644 modules-load.8 ${DESTDIR}/${PREFIX}/share/man/man8 + install -m644 vlogger.8 ${DESTDIR}/${PREFIX}/share/man/man8 ln -sf halt.8 ${DESTDIR}/${PREFIX}/share/man/man8/poweroff.8 ln -sf halt.8 ${DESTDIR}/${PREFIX}/share/man/man8/reboot.8 install -d ${DESTDIR}/etc/sv diff --git a/vlogger.8 b/vlogger.8 new file mode 100644 index 0000000..2f46fcd --- /dev/null +++ b/vlogger.8 @@ -0,0 +1,138 @@ +.Dd March 1, 2017 +.Dt VLOGGER 8 +.Os Linux +.Sh NAME +.Nm vlogger +.Nd log messages to syslog or an arbitrary executable +.Sh SYNOPSIS +.Nm vlogger +.Op Fl p Ar priority +.Op Fl t Ar tag +.Sh DESCRIPTION +By default, +.Nm +reads lines from +.Dv stdin +and sends them to syslog. +If the file +.Pa /etc/vlogger +exists and is executable it is executed with +.Ar tag +as only argument and replaces +.Nm . +.Pp +If +.Nm +is executed as a log service for runit or another daemontools like +supervision suite it uses the service name as default +.Ar tag . +As example if +.Nm +is linked to +.Dv /var/service/foo/log/run +it uses +.Dv foo +as default +.Ar tag . +.Bl -tag -width indent +.It Fl p Ar priority +The. +.Ar priority +can be +.Pa facility.level +or just +.Pa facility . +See +.Sx FACILITIES , +.Sx LEVELS +or +.Xr syslog 3 . +The default is +.Pa daemon.info . +.It Fl t Ar tag +Defines the +.Xr openlog 3 +.Pa ident +which is used as prefix for each log message or passed as first argument to +.Pa /etc/vlogger . +.El +.Sh FACILITIES +.Bl -tag -width 11n -compact +.It auth +.It authpriv +.It cron +.It daemon +.It ftp +.It kern +can not be used from userspace replaced with +.Pa daemon . +.It lpr +.It mail +.It news +.It syslog +.It user +.It uucp +.It local[0-7] +.It security +deprecated synonym for +.Pa auth. +.El +.Sh LEVELS +.Bl -tag -width 11n -compact +.It emerg +.It alert +.It crit +.It err +.It warning +.It notice +.It info +.It debug +.It panic +deprecated synonym for +.Pa emerg . +.It error +deprecated synonym for +.Ar err . +.It warn +deprecated synonym for +.Pa warning . +.El +.Sh FILES +.Bl -tag -width indent +.It /etc/vlogger +An optional executable file that is used to to handle the messages. +It is executed with +.Ar tag +as first argument and replaces the +.Nm +process. +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +.Pa /etc/vlogger : +.Bd -literal -offset indent +#!/bin/sh +exec svlogd /var/log/$1 +.Ed +.Sh SEE ALSO +.Xr logger 1 , +.Xr syslog 3 , +.Xr svlogd 8 +.Sh HISTORY +This program is a replacement for the +.Nm logger +utility provided by +.Nm util-linux . +.Sh AUTHOR +.An Duncan Overbruck Aq Mt mail@duncano.de +.Sh LICENSE +.Nm +is in the public domain. +.Pp +To the extent possible under law, +the creator of this work +has waived all copyright and related or +neighboring rights to this work. +.Pp +.Lk http://creativecommons.org/publicdomain/zero/1.0/ diff --git a/vlogger.c b/vlogger.c new file mode 100644 index 0000000..981b692 --- /dev/null +++ b/vlogger.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include + +typedef struct _code { + const char *const c_name; + int c_val; +} CODE; + +CODE prioritynames[] = { + { "alert", LOG_ALERT }, + { "crit", LOG_CRIT }, + { "debug", LOG_DEBUG }, + { "emerg", LOG_EMERG }, + { "err", LOG_ERR }, + { "error", LOG_ERR }, + { "info", LOG_INFO }, + { "notice", LOG_NOTICE }, + { "panic", LOG_EMERG }, + { "warn", LOG_WARNING }, + { "warning", LOG_WARNING }, + { 0, -1 } +}; + +CODE facilitynames[] = { + { "auth", LOG_AUTH }, + { "authpriv", LOG_AUTHPRIV }, + { "cron", LOG_CRON }, + { "daemon", LOG_DAEMON }, + { "ftp", LOG_FTP }, + { "kern", LOG_KERN }, + { "lpr", LOG_LPR }, + { "mail", LOG_MAIL }, + { "news", LOG_NEWS }, + { "security", LOG_AUTH }, + { "syslog", LOG_SYSLOG }, + { "user", LOG_USER }, + { "uucp", LOG_UUCP }, + { "local0", LOG_LOCAL0 }, + { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, + { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, + { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, + { "local7", LOG_LOCAL7 }, + { 0, -1 } +}; + +static char *tag; + +static void +strpriority(char *s, int *facility, int *level) +{ + char *p; + CODE *cp; + + if ((p = strchr(s, '.'))) { + *p++ = 0; + for (cp = prioritynames; cp->c_name; cp++) { + if (strcmp(cp->c_name, p) == 0) + *level = cp->c_val; + } + } + if (*s) + for (cp = facilitynames; cp->c_name; cp++) { + if (strcmp(cp->c_name, s) == 0) + *facility = cp->c_val; + } +} + +int +main(int argc, char *argv[]) +{ + char c, *p; + int facility = LOG_DAEMON; + int level = LOG_INFO; + + if (((p = strrchr(*argv, '/')) && !strncmp(p+1, "run", 3)) && + (*p = 0, (p = strrchr(*argv, '/')) && !strncmp(p+1, "log", 3)) && + (*p = 0, (p = strrchr(*argv, '/'))) != 0) { + tag = strdup(p+1); + } + + while ((c = getopt(argc, argv, "p:t:")) != -1) + switch (c) { + case 'p': strpriority(optarg, &facility, &level); break; + case 't': tag = optarg; break; + default: + fprintf(stderr, "usage: vlogger [-p priority] [-t tag]\n"); + exit(1); + } + + if (access("/etc/vlogger", X_OK) != -1) + execl("/etc/vlogger", "/etc/vlogger", tag, (char *)0); + + openlog(tag, 0, facility); + + char *line; + size_t linelen = 0; + ssize_t rd; + while ((rd = getline(&line, &linelen, stdin)) != -1) { + if (line[rd-1] == '\n') + line[rd-1] = 0; + syslog(level|facility, "%s", line); + } + + return 1; +} -- cgit 1.4.1