From 64c57ea1579b1832f65ffa41923ae146bb97a213 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 8 Jul 2016 11:35:11 +0200 Subject: [PATCH] Add a new logger: syslog and Print the VM name in the logs To activate it specify lxc.syslog = For now the available facilities are: daemon, local[0-7] others will be rejected syslog got only activated after the function that checks for inheritance of fd is passed in order to make sure the syslog fd is not inherited and prevent the creation of the fd is any log have been issued during the checks (which would end up in an infinite loop) Signed-off-by: Fatih ACAR Signed-off-by: Ahmed Amamou Signed-off-by: Baptiste Daroussin Signed-off-by: William Dauchy --- src/lxc/confile.c | 37 ++++++++++++++++ src/lxc/log.c | 106 +++++++++++++++++++++++++++++++++++++++++++++- src/lxc/log.h | 2 + src/lxc/start.c | 7 +++ 4 files changed, 150 insertions(+), 2 deletions(-) diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 14a76b2ec..645cac02d 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "parse.h" #include "config.h" @@ -105,6 +106,7 @@ static int config_haltsignal(const char *, const char *, struct lxc_conf *); static int config_rebootsignal(const char *, const char *, struct lxc_conf *); static int config_stopsignal(const char *, const char *, struct lxc_conf *); static int config_start(const char *, const char *, struct lxc_conf *); +static int config_syslog(const char *, const char *, struct lxc_conf *); static int config_monitor(const char *, const char *, struct lxc_conf *); static int config_group(const char *, const char *, struct lxc_conf *); static int config_environment(const char *, const char *, struct lxc_conf *); @@ -184,6 +186,7 @@ static struct lxc_config_t config[] = { { "lxc.init_uid", config_init_uid }, { "lxc.init_gid", config_init_gid }, { "lxc.ephemeral", config_ephemeral }, + { "lxc.syslog", config_syslog }, }; struct signame { @@ -270,6 +273,23 @@ static const struct signame signames[] = { #endif }; +struct syslog_facility { + const char *name; + int facility; +}; + +static const struct syslog_facility syslog_facilities[] = { + { "daemon", LOG_DAEMON }, + { "local0", LOG_LOCAL0 }, + { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, + { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, + { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, + { "local7", LOG_LOCAL7 }, +}; + static const size_t config_size = sizeof(config)/sizeof(struct lxc_config_t); extern struct lxc_config_t *lxc_getconfig(const char *key) @@ -2919,3 +2939,20 @@ static int config_ephemeral(const char *key, const char *value, return 0; } +static int config_syslog(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + int n; + int facility = -1; + + for (n = 0; n < sizeof(syslog_facilities) / sizeof((syslog_facilities)[0]); n++) { + if (strcasecmp(syslog_facilities[n].name, value) == 0) { + facility = syslog_facilities[n].facility; + lxc_log_syslog(facility); + return 0; + } + } + + ERROR("Wrong value for lxc.syslog"); + return -1; +} diff --git a/src/lxc/log.c b/src/lxc/log.c index 11d4bbfb5..d7db033a2 100644 --- a/src/lxc/log.c +++ b/src/lxc/log.c @@ -33,6 +33,9 @@ #define __USE_GNU /* for *_CLOEXEC */ +#include +#include + #include #include @@ -43,15 +46,78 @@ #define LXC_LOG_DATEFOMAT_SIZE 15 int lxc_log_fd = -1; +static int syslog_enable = 0; int lxc_quiet_specified; int lxc_log_use_global_fd; static int lxc_loglevel_specified; static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc"; static char *log_fname = NULL; +static char *log_vmname = NULL; lxc_log_define(lxc_log, lxc); +static int lxc_log_priority_to_syslog(int priority) +{ + switch (priority) { + case LXC_LOG_PRIORITY_FATAL: + return LOG_EMERG; + case LXC_LOG_PRIORITY_ALERT: + return LOG_ALERT; + case LXC_LOG_PRIORITY_CRIT: + return LOG_CRIT; + case LXC_LOG_PRIORITY_ERROR: + return LOG_ERR; + case LXC_LOG_PRIORITY_WARN: + return LOG_WARNING; + case LXC_LOG_PRIORITY_NOTICE: + case LXC_LOG_PRIORITY_NOTSET: + return LOG_NOTICE; + case LXC_LOG_PRIORITY_INFO: + return LOG_INFO; + case LXC_LOG_PRIORITY_TRACE: + case LXC_LOG_PRIORITY_DEBUG: + return LOG_DEBUG; + } + + /* Not reached */ + return LOG_NOTICE; +} + +/*---------------------------------------------------------------------------*/ +static int log_append_syslog(const struct lxc_log_appender *appender, + struct lxc_log_event *event) +{ + char *msg; + int rc, len; + va_list args; + + if (!syslog_enable) + return 0; + + va_copy(args, *event->vap); + len = vsnprintf(NULL, 0, event->fmt, args) + 1; + va_end(args); + msg = malloc(len * sizeof(char)); + if (msg == NULL) + return 0; + rc = vsnprintf(msg, len, event->fmt, *event->vap); + if (rc == -1 || rc >= len) { + free(msg); + return 0; + } + + syslog(lxc_log_priority_to_syslog(event->priority), + "%s %s - %s:%s:%d - %s" , + log_vmname ? log_vmname : "", + event->category, + event->locinfo->file, event->locinfo->func, + event->locinfo->line, + msg); + free(msg); + return 0; +} + /*---------------------------------------------------------------------------*/ static int log_append_stderr(const struct lxc_log_appender *appender, struct lxc_log_event *event) @@ -59,7 +125,7 @@ static int log_append_stderr(const struct lxc_log_appender *appender, if (event->priority < LXC_LOG_PRIORITY_ERROR) return 0; - fprintf(stderr, "%s: ", log_prefix); + fprintf(stderr, "%s: %s", log_prefix, log_vmname ? log_vmname : ""); fprintf(stderr, "%s: %s: %d ", event->locinfo->file, event->locinfo->func, event->locinfo->line); vfprintf(stderr, event->fmt, *event->vap); fprintf(stderr, "\n"); @@ -92,8 +158,10 @@ static int log_append_logfile(const struct lxc_log_appender *appender, strftime(date, sizeof(date), "%Y%m%d%H%M%S", t); ms = event->timestamp.tv_usec / 1000; n = snprintf(buffer, sizeof(buffer), - "%15s %10s.%03d %-8s %s - %s:%s:%d - ", + "%15s%s%s %10s.%03d %-8s %s - %s:%s:%d - ", log_prefix, + log_vmname ? " " : "", + log_vmname ? log_vmname : "", date, ms, lxc_log_priority_to_string(event->priority), @@ -115,6 +183,12 @@ static int log_append_logfile(const struct lxc_log_appender *appender, return write(fd_to_use, buffer, n + 1); } +static struct lxc_log_appender log_appender_syslog = { + .name = "syslog", + .append = log_append_syslog, + .next = NULL, +}; + static struct lxc_log_appender log_appender_stderr = { .name = "stderr", .append = log_append_stderr, @@ -253,6 +327,9 @@ static char *build_log_path(const char *name, const char *lxcpath) extern void lxc_log_close(void) { + closelog(); + free(log_vmname); + log_vmname = NULL; if (lxc_log_fd == -1) return; close(lxc_log_fd); @@ -317,6 +394,28 @@ static int _lxc_log_set_file(const char *name, const char *lxcpath, int create_d return ret; } +extern int lxc_log_syslog(int facility) +{ + struct lxc_log_appender *appender; + + openlog(log_prefix, LOG_PID, facility); + if (!lxc_log_category_lxc.appender) { + lxc_log_category_lxc.appender = &log_appender_syslog; + return 0; + } + appender = lxc_log_category_lxc.appender; + while (appender->next != NULL) + appender = appender->next; + appender->next = &log_appender_syslog; + + return 0; +} + +extern void lxc_log_enable_syslog(void) +{ + syslog_enable = 1; +} + /* * lxc_log_init: * Called from lxc front-end programs (like lxc-create, lxc-start) to @@ -350,6 +449,9 @@ extern int lxc_log_init(const char *name, const char *file, if (prefix) lxc_log_set_prefix(prefix); + if (name) + log_vmname = strdup(name); + if (file) { if (strcmp(file, "none") == 0) return 0; diff --git a/src/lxc/log.h b/src/lxc/log.h index eb330d0b1..8906c234d 100644 --- a/src/lxc/log.h +++ b/src/lxc/log.h @@ -314,6 +314,8 @@ extern int lxc_log_init(const char *name, const char *file, const char *lxcpath); extern int lxc_log_set_file(int *fd, const char *fname); +extern int lxc_log_syslog(int facility); +extern void lxc_log_enable_syslog(void); extern int lxc_log_set_level(int *dest, int level); extern void lxc_log_set_prefix(const char *prefix); extern const char *lxc_log_get_file(void); diff --git a/src/lxc/start.c b/src/lxc/start.c index b3f75b8e1..1ba0f9bd7 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -255,6 +255,13 @@ restart: WARN("inherited fd %d", fd); } + /* + * only enable syslog at this point to avoid the above logging function + * to open a new fd and make the check_inherited function enter an + * infinite loop. + */ + lxc_log_enable_syslog(); + closedir(dir); /* cannot fail */ return 0; } -- 2.39.5