about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDuncaen <mail@duncano.de>2017-03-01 19:15:03 +0100
committerDuncaen <mail@duncano.de>2018-06-20 18:02:46 +0200
commitb29a3c4d11ec1cf778b253e3c3fbbf04b0794f86 (patch)
treef81345c482f77b0d31b2ca73d98fa6752013a23f
parent8fe7df917d20e4bdad51fabcc3675e66fa50e330 (diff)
downloadrunit-void-b29a3c4d11ec1cf778b253e3c3fbbf04b0794f86.tar.gz
runit-void-b29a3c4d11ec1cf778b253e3c3fbbf04b0794f86.tar.xz
runit-void-b29a3c4d11ec1cf778b253e3c3fbbf04b0794f86.zip
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.
-rw-r--r--.gitignore1
-rw-r--r--Makefile2
-rw-r--r--vlogger.8138
-rw-r--r--vlogger.c111
4 files changed, 252 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+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;
+}