]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Write syslog entries in logfile:
authorRoy Marples <roy@marples.name>
Tue, 11 Apr 2017 17:04:03 +0000 (18:04 +0100)
committerRoy Marples <roy@marples.name>
Tue, 11 Apr 2017 17:04:03 +0000 (18:04 +0100)
  date tag[pid]: message
This does add a few more bytes, but it allows for the same log
analysis tools to be used.
When building SMALL, this code is removed and you just get the
message in the logfile.

BUILDING.md
src/dhcpcd.c
src/logerr.c
src/logerr.h

index a944417a3d1a5539e381ee5cdf54fb517259f3f0..f15742414362ddba593d4d46c6f931e0989165ab 100644 (file)
@@ -11,7 +11,7 @@ To compile small dhcpcd, maybe to be used for installation media where
 size is a concern, you can use the `--small` configure option to enable
 a reduced feature set within dhcpcd.
 Currently this just removes non important options out of
-`dhcpcd-definitions.conf`, the custom logger and
+`dhcpcd-definitions.conf`, the logfile option and
 support for DHCPv6 Prefix Delegation.
 Other features maybe dropped as and when required.
 dhcpcd can also be made smaller by removing the IPv4 or IPv6 stack:
index e7822dde1548deb0bea87053d4d9f28e09ca95b2..e9fbcc502b4b923398c563257bc899fa5b692d6a 100644 (file)
@@ -1461,7 +1461,8 @@ main(int argc, char **argv)
 #ifdef INET
        ctx.udp_fd = -1;
 #endif
-       logopts = LOGERR_WLOG;
+       /* syslog style logging */
+       logopts = LOGERR_LOG|LOGERR_LOG_DATE|LOGERR_LOG_TAG|LOGERR_LOG_PID;
        i = 0;
        while ((opt = getopt_long(argc, argv,
            ctx.options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS,
@@ -1513,7 +1514,7 @@ main(int argc, char **argv)
                        break;
                case 'T':
                        i = 1;
-                       logopts &= ~LOGERR_WLOG;
+                       logopts &= ~LOGERR_LOG;
                        break;
                case 'U':
                        i = 3;
index ee97624a24a4981ffcc4bf7c680c8c8b288f99dd..2ae7ce3773ece145433de793f866b52bfedc8ffd 100644 (file)
 
 #include <sys/time.h>
 #include <errno.h>
+#include <stdbool.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
 #include <time.h>
+#include <unistd.h>
 
 #include "logerr.h"
 
 #ifndef        LOGERR_SYSLOG_FACILITY
 #define        LOGERR_SYSLOG_FACILITY  LOG_DAEMON
 #endif
-#ifndef        LOGERR_SYSLOG_OPTS
-#define        LOGERR_SYSLOG_OPTS      LOG_PID
-#endif
+
+#define UNUSED(a)              (void)(a)
 
 struct logctx {
        unsigned int     log_opts;
+#ifndef SMALL
+       const char      *log_tag;
        FILE            *log_file;
+#endif
 };
 
 static struct logctx _logctx = {
-       .log_opts = LOGERR_WLOG,
-       .log_file = NULL,
+       /* syslog style by default */
+       .log_opts = LOGERR_LOG | LOGERR_LOG_DATE |
+                   LOGERR_LOG_TAG | LOGERR_LOG_PID,
 };
 
-__printflike(2, 0) static void
-vlogprintf(FILE *stream, const char *fmt, va_list args)
+#if !defined(SMALL) && defined(__linux__)
+/* Poor man's getprogname(3). */
+static char *_logprog;
+static const char *
+getprogname(void)
+{
+       const char *p;
+
+       /* Use PATH_MAX + 1 to avoid truncation. */
+       if (_logprog == NULL) {
+               /* readlink(2) does not append a NULL byte,
+                * so zero the buffer. */
+               if ((_logprog = calloc(1, PATH_MAX + 1)) == NULL)
+                       return NULL;
+       }
+       if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1)
+               return NULL;
+       if (_logprog[0] == '[')
+               return NULL;
+       p = strrchr(_logprog, '/');
+       if (p == NULL)
+               return _logprog;
+       return p + 1;
+}
+#endif
+
+__printflike(3, 0) static void
+vlogprintf_r(struct logctx *ctx, FILE *stream, const char *fmt, va_list args)
 {
        va_list a;
+#ifndef SMALL
+       bool log_tag, log_pid;
+
+       log_tag = ((stream == stderr && ctx->log_opts & LOGERR_ERR_TAG) ||
+           (stream != stderr && ctx->log_opts & LOGERR_LOG_TAG));
+       if (log_tag) {
+               if (ctx->log_tag == NULL)
+                       ctx->log_tag = getprogname();
+               fprintf(stream, "%s", ctx->log_tag);
+       }
+
+       log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) ||
+           (stream != stderr && ctx->log_opts & LOGERR_LOG_PID));
+       if (log_pid)
+               fprintf(stream, "[%d]", getpid());
+
+       if (log_tag || log_pid)
+               fprintf(stream, ": ");
+#else
+       UNUSED(ctx);
+#endif
 
        va_copy(a, args);
        vfprintf(stream, fmt, a);
@@ -81,37 +134,45 @@ vlogprintf(FILE *stream, const char *fmt, va_list args)
 __printflike(2, 0) static void
 vlogmessage(int pri, const char *fmt, va_list args)
 {
+#ifndef SMALL
+       struct timeval tv;
+#endif
+       struct logctx *ctx = &_logctx;
 
        if (pri <= LOG_ERR ||
-           (!(_logctx.log_opts & LOGERR_QUIET) && pri <= LOG_INFO) ||
-           (_logctx.log_opts & LOGERR_DEBUG && pri <= LOG_DEBUG))
-               vlogprintf(stderr, fmt, args);
+           (!(ctx->log_opts & LOGERR_QUIET) && pri <= LOG_INFO) ||
+           (ctx->log_opts & LOGERR_DEBUG && pri <= LOG_DEBUG))
+               vlogprintf_r(ctx, stderr, fmt, args);
 
-       if (!(_logctx.log_opts & LOGERR_WLOG))
+       if (!(ctx->log_opts & LOGERR_LOG))
                return;
 
-       if (_logctx.log_file != NULL) {
-               struct timeval tv;
-
-               if (pri == LOG_DEBUG && !(_logctx.log_opts & LOGERR_DEBUG))
-                       return;
+#ifdef SMALL
+       vsyslog(pri, fmt, args);
+#else
+       if (ctx->log_file == NULL) {
+               vsyslog(pri, fmt, args);
+               return;
+       }
 
-               /* Write the time, syslog style. month day time - */
-               if (gettimeofday(&tv, NULL) != -1) {
-                       time_t now;
-                       struct tm tmnow;
-                       char buf[32];
+       if (pri == LOG_DEBUG && !(ctx->log_opts & LOGERR_DEBUG))
+               return;
 
-                       now = tv.tv_sec;
-                       tzset();
-                       localtime_r(&now, &tmnow);
-                       strftime(buf, sizeof(buf), "%b %d %T ", &tmnow);
-                       fprintf(_logctx.log_file, "%s", buf);
-               }
+       /* Write the time, syslog style. month day time - */
+       if (ctx->log_opts & LOGERR_LOG_DATE && gettimeofday(&tv, NULL) != -1) {
+               time_t now;
+               struct tm tmnow;
+               char buf[32];
+
+               now = tv.tv_sec;
+               tzset();
+               localtime_r(&now, &tmnow);
+               strftime(buf, sizeof(buf), "%b %d %T ", &tmnow);
+               fprintf(ctx->log_file, "%s", buf);
+       }
 
-               vlogprintf(_logctx.log_file, fmt, args);
-       } else
-               vsyslog(pri, fmt, args);
+       vlogprintf_r(ctx, ctx->log_file, fmt, args);
+#endif
 }
 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5))
 #pragma GCC diagnostic pop
@@ -200,33 +261,64 @@ logerrx(const char *fmt, ...)
 void
 logsetopts(unsigned int opts)
 {
+       struct logctx *ctx = &_logctx;
 
-       _logctx.log_opts = opts;
+       ctx->log_opts = opts;
        setlogmask(LOG_UPTO(opts & LOGERR_DEBUG ? LOG_DEBUG : LOG_INFO));
 }
 
+void
+logsettag(const char *tag)
+{
+#ifndef SMALL
+       struct logctx *ctx = &_logctx;
+
+       ctx->log_tag = tag;
+#else
+       UNUSED(tag);
+#endif
+}
+
 int
 logopen(const char *path)
 {
+       struct logctx *ctx = &_logctx;
 
        if (path == NULL) {
-               openlog(NULL, LOGERR_SYSLOG_OPTS, LOGERR_SYSLOG_FACILITY);
+               int opts = 0;
+
+               if (ctx->log_opts & LOGERR_LOG_PID)
+                       opts |= LOG_PID;
+               openlog(NULL, opts, LOGERR_SYSLOG_FACILITY);
                return 1;
        }
 
-       if ((_logctx.log_file = fopen(path, "w")) == NULL)
+#ifndef SMALL
+       if ((ctx->log_file = fopen(path, "w")) == NULL)
                return -1;
-       setlinebuf(_logctx.log_file);
-       return fileno(_logctx.log_file);
+       setlinebuf(ctx->log_file);
+       return fileno(ctx->log_file);
+#else
+       errno = ENOTSUP;
+       return -1;
+#endif
 }
 
 void
 logclose(void)
 {
+#ifndef SMALL
+       struct logctx *ctx = &_logctx;
+#endif
 
        closelog();
-       if (_logctx.log_file == NULL)
+#ifndef SMALL
+       if (ctx->log_file == NULL)
                return;
-       fclose(_logctx.log_file);
-       _logctx.log_file = NULL;
+       fclose(ctx->log_file);
+       ctx->log_file = NULL;
+#endif
+#if !defined(SMALL) && defined(__linux__)
+       free(_logprog);
+#endif
 }
index 5b928ffd1bd0ae32048580c978e3b5c23eca6589..b9a8fbc53659f1aac511326e88586f0ca96ec712 100644 (file)
@@ -49,9 +49,15 @@ __printflike(1, 2) void logerr(const char *, ...);
 __printflike(1, 2) void logerrx(const char *, ...);
 
 void logsetopts(unsigned int);
-#define        LOGERR_WLOG     (1U << 1)
-#define        LOGERR_DEBUG    (1U << 2)
-#define        LOGERR_QUIET    (1U << 3)
+#define        LOGERR_LOG      (1U <<  1)
+#define        LOGERR_LOG_TAG  (1U <<  2)
+#define        LOGERR_LOG_PID  (1U <<  3)
+#define        LOGERR_LOG_DATE (1U <<  4)
+#define        LOGERR_ERR_TAG  (1U << 11)
+#define        LOGERR_ERR_PID  (1U << 12)
+#define        LOGERR_DEBUG    (1U << 21)
+#define        LOGERR_QUIET    (1U << 22)
+void logsettag(const char *);
 
 int logopen(const char *);
 void logclose(void);