From: Roy Marples Date: Tue, 11 Apr 2017 17:04:03 +0000 (+0100) Subject: Write syslog entries in logfile: X-Git-Tag: v7.0.0-beta3~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=12cc2d99466df9f11602983009ee43ee3414304d;p=thirdparty%2Fdhcpcd.git Write syslog entries in logfile: 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. --- diff --git a/BUILDING.md b/BUILDING.md index a944417a..f1574241 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -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: diff --git a/src/dhcpcd.c b/src/dhcpcd.c index e7822dde..e9fbcc50 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -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; diff --git a/src/logerr.c b/src/logerr.c index ee97624a..2ae7ce37 100644 --- a/src/logerr.c +++ b/src/logerr.c @@ -27,35 +27,88 @@ #include #include +#include #include #include +#include #include #include #include +#include #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 } diff --git a/src/logerr.h b/src/logerr.h index 5b928ffd..b9a8fbc5 100644 --- a/src/logerr.h +++ b/src/logerr.h @@ -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);