]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
logger: add support for --prio-prefix when logging stdin
authorDennis H Jensen <dennis.h.jensen@siemens.com>
Wed, 22 May 2013 11:12:08 +0000 (13:12 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 29 May 2013 08:47:16 +0000 (10:47 +0200)
This patch adds a new option to logger that will make it look for a
priority prefix <n> at the beginning of every line. The priority is
a single decimal number formed as explained in syslog(3).

If a prefix is found logger will log the message using the found
facility and level in that prefix, if the prefix doesn't contain a
facility the default facility specified by the -p option will be used.
If no prefix is found, logger will use the priority specified by -p.

[kzak@redhat.com: - add --prio-prefix to usage() output]

Signed-off-by: Dennis H Jensen <dennis.h.jensen@siemens.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
misc-utils/logger.1
misc-utils/logger.c

index 09ecdc4f88a49002150bcf174e408b3765d522a9..f4cadc69705a72b91fe2b519351bf10be554489b 100644 (file)
@@ -109,6 +109,19 @@ Write to the specified
 .I socket
 instead of to the builtin syslog routines.
 .TP
+\fB\-\-prio\-prefix\fR
+Look for a syslog prefix on every line read from standard input, a
+number contained within angle brackets that contain both the facility
+and level. The decimal prefix is constructed by multiplying the
+facility by 8 and then adding the level, thus \fIlocal0.info\fR,
+facility=16 and level=6, becomes \fI<134>\fR.
+
+If the prefix contains no facility, the facility defaults to what is
+specified by \fB\-p\fR option, similarly if no prefix is provided the
+line is logged using the \fB\-p\fR \fIpriority\fR.
+
+This option doesn't affect a command-line message.
+.TP
 \fB\-V\fR, \fB\-\-version\fR
 Display version information and exit.
 .TP
index c83c0b817fb8ceca6dd2c9b8dcca4319c53dddd1..5b4d055f47363d9fca73bc60f684aa2d7af55128 100644 (file)
@@ -64,6 +64,30 @@ enum {
        ALL_TYPES = TYPE_UDP | TYPE_TCP
 };
 
+enum {
+       OPT_PRIO_PREFIX = CHAR_MAX + 1
+};
+
+
+static char* get_prio_prefix(char *msg, int *prio)
+{
+       int p;
+       char *end = NULL;
+       int facility = *prio & LOG_FACMASK;
+
+       errno = 0;
+       p = strtoul(msg + 1, &end, 10);
+
+       if (errno || !end || end == msg + 1 || end[0] != '>')
+               return msg;
+
+       if (p & LOG_FACMASK)
+               facility = p & LOG_FACMASK;
+
+       *prio = facility | (p & LOG_PRIMASK);
+       return end + 1;
+}
+
 static int decode(char *name, CODE *codetab)
 {
        register CODE *c;
@@ -225,6 +249,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out)
                " -P, --port <number>   use this UDP port\n"
                " -p, --priority <prio> mark given message with this priority\n"
                " -s, --stderr          output message to standard error as well\n"), out);
+       fputs(_("     --prio-prefix     look for a prefix on every line read from stdin\n"), out);
        fputs(_(" -t, --tag <tag>       mark every line with this tag\n"
                " -u, --socket <socket> write to this Unix socket\n"
                " -V, --version         output version information and exit\n\n"), out);
@@ -240,7 +265,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out)
  */
 int
 main(int argc, char **argv) {
-       int ch, logflags, pri;
+       int ch, logflags, pri, prio_prefix;
        char *tag, buf[1024];
        char *usock = NULL;
        char *server = NULL;
@@ -260,6 +285,7 @@ main(int argc, char **argv) {
                { "port",       required_argument,  0, 'P' },
                { "version",    no_argument,        0, 'V' },
                { "help",       no_argument,        0, 'h' },
+               { "prio-prefix", no_argument, 0, OPT_PRIO_PREFIX },
                { NULL,         0, 0, 0 }
        };
 
@@ -271,9 +297,10 @@ main(int argc, char **argv) {
        tag = NULL;
        pri = LOG_NOTICE;
        logflags = 0;
+       prio_prefix = 0;
        while ((ch = getopt_long(argc, argv, "f:ip:st:u:dTn:P:Vh",
                                            longopts, NULL)) != -1) {
-               switch((char)ch) {
+               switch (ch) {
                case 'f':               /* file to log */
                        if (freopen(optarg, "r", stdin) == NULL)
                                err(EXIT_FAILURE, _("file %s"),
@@ -311,6 +338,9 @@ main(int argc, char **argv) {
                        exit(EXIT_SUCCESS);
                case 'h':
                        usage(stdout);
+               case OPT_PRIO_PREFIX:
+                       prio_prefix = 1;
+                       break;
                case '?':
                default:
                        usage(stderr);
@@ -360,6 +390,8 @@ main(int argc, char **argv) {
                        mysyslog(LogSock, logflags, pri, tag, buf);
                }
        } else {
+               char *msg;
+               int default_priority = pri;
                while (fgets(buf, sizeof(buf), stdin) != NULL) {
                    /* glibc is buggy and adds an additional newline,
                       so we have to remove it here until glibc is fixed */
@@ -368,10 +400,15 @@ main(int argc, char **argv) {
                    if (len > 0 && buf[len - 1] == '\n')
                            buf[len - 1] = '\0';
 
+                       msg = buf;
+                       pri = default_priority;
+                       if (prio_prefix && msg[0] == '<')
+                               msg = get_prio_prefix(msg, &pri);
+
                    if (!usock && !server)
-                       syslog(pri, "%s", buf);
+                       syslog(pri, "%s", msg);
                    else
-                       mysyslog(LogSock, logflags, pri, tag, buf);
+                       mysyslog(LogSock, logflags, pri, tag, msg);
                }
        }
        if (!usock && !server)