Merge pull request #1105 from bapt/syslog

Add syslog support
This commit is contained in:
Christian Brauner 2016-07-30 01:23:42 +02:00 committed by GitHub
commit b336ea596b
5 changed files with 163 additions and 2 deletions

View File

@ -1697,6 +1697,19 @@ mknod errno 0
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>lxc.syslog</option>
</term>
<listitem>
<para>
Send logging info to syslog. It respects the log level defined in
<command>lxc.loglevel</command>. The argument should be the syslog
facility to use, valid ones are: daemon, local0, local1, local2,
local3, local4, local5, local5, local7.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>

View 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;
}

View File

@ -33,6 +33,9 @@
#define __USE_GNU /* for *_CLOEXEC */
#include <syslog.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
@ -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;

View 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);

View 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;
}