]> git.proxmox.com Git - mirror_lxc.git/commitdiff
Add a new logger: syslog and Print the VM name in the logs
authorBaptiste Daroussin <bapt@gandi.net>
Fri, 8 Jul 2016 09:35:11 +0000 (11:35 +0200)
committerBaptiste Daroussin <bapt@gandi.net>
Fri, 29 Jul 2016 21:31:48 +0000 (23:31 +0200)
To activate it specify lxc.syslog = <afacility>
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 <fatih.acar@gandi.net>
Signed-off-by: Ahmed Amamou <ahmed@gandi.net>
Signed-off-by: Baptiste Daroussin <bapt@gandi.net>
Signed-off-by: William Dauchy <william@gandi.net>
src/lxc/confile.c
src/lxc/log.c
src/lxc/log.h
src/lxc/start.c

index 14a76b2ec13004b582ec7f5797b6890bddad273f..645cac02d3112cf884ad88d10a884f5df797b81d 100644 (file)
@@ -38,6 +38,7 @@
 #include <net/if.h>
 #include <time.h>
 #include <dirent.h>
+#include <syslog.h>
 
 #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;
+}
index 11d4bbfb5dd30f6ba429960ee5a448840d91ba71..d7db033a2070bbca9abcee55a74b697c46a92c89 100644 (file)
@@ -33,6 +33,9 @@
 
 #define __USE_GNU /* for *_CLOEXEC */
 
+#include <syslog.h>
+#include <stdio.h>
+
 #include <fcntl.h>
 #include <stdlib.h>
 
 #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;
index eb330d0b18ff1b5cdda16f694d76787802152489..8906c234d5ff8f1d01a9aaeb77605d4404bd3c9c 100644 (file)
@@ -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);
index b3f75b8e1c24235220318bbbb636606a4e86310c..1ba0f9bd785856696b21aa4a1e393a7f1bdbbd56 100644 (file)
@@ -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;
 }