mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-08 02:13:22 +00:00
commit
b336ea596b
@ -1697,6 +1697,19 @@ mknod errno 0
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
</variablelist>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "config.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_rebootsignal(const char *, const char *, struct lxc_conf *);
|
||||||
static int config_stopsignal(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_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_monitor(const char *, const char *, struct lxc_conf *);
|
||||||
static int config_group(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 *);
|
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_uid", config_init_uid },
|
||||||
{ "lxc.init_gid", config_init_gid },
|
{ "lxc.init_gid", config_init_gid },
|
||||||
{ "lxc.ephemeral", config_ephemeral },
|
{ "lxc.ephemeral", config_ephemeral },
|
||||||
|
{ "lxc.syslog", config_syslog },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct signame {
|
struct signame {
|
||||||
@ -270,6 +273,23 @@ static const struct signame signames[] = {
|
|||||||
#endif
|
#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);
|
static const size_t config_size = sizeof(config)/sizeof(struct lxc_config_t);
|
||||||
|
|
||||||
extern struct lxc_config_t *lxc_getconfig(const char *key)
|
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;
|
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;
|
||||||
|
}
|
||||||
|
106
src/lxc/log.c
106
src/lxc/log.c
@ -33,6 +33,9 @@
|
|||||||
|
|
||||||
#define __USE_GNU /* for *_CLOEXEC */
|
#define __USE_GNU /* for *_CLOEXEC */
|
||||||
|
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -43,15 +46,78 @@
|
|||||||
#define LXC_LOG_DATEFOMAT_SIZE 15
|
#define LXC_LOG_DATEFOMAT_SIZE 15
|
||||||
|
|
||||||
int lxc_log_fd = -1;
|
int lxc_log_fd = -1;
|
||||||
|
static int syslog_enable = 0;
|
||||||
int lxc_quiet_specified;
|
int lxc_quiet_specified;
|
||||||
int lxc_log_use_global_fd;
|
int lxc_log_use_global_fd;
|
||||||
static int lxc_loglevel_specified;
|
static int lxc_loglevel_specified;
|
||||||
|
|
||||||
static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc";
|
static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc";
|
||||||
static char *log_fname = NULL;
|
static char *log_fname = NULL;
|
||||||
|
static char *log_vmname = NULL;
|
||||||
|
|
||||||
lxc_log_define(lxc_log, lxc);
|
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,
|
static int log_append_stderr(const struct lxc_log_appender *appender,
|
||||||
struct lxc_log_event *event)
|
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)
|
if (event->priority < LXC_LOG_PRIORITY_ERROR)
|
||||||
return 0;
|
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);
|
fprintf(stderr, "%s: %s: %d ", event->locinfo->file, event->locinfo->func, event->locinfo->line);
|
||||||
vfprintf(stderr, event->fmt, *event->vap);
|
vfprintf(stderr, event->fmt, *event->vap);
|
||||||
fprintf(stderr, "\n");
|
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);
|
strftime(date, sizeof(date), "%Y%m%d%H%M%S", t);
|
||||||
ms = event->timestamp.tv_usec / 1000;
|
ms = event->timestamp.tv_usec / 1000;
|
||||||
n = snprintf(buffer, sizeof(buffer),
|
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_prefix,
|
||||||
|
log_vmname ? " " : "",
|
||||||
|
log_vmname ? log_vmname : "",
|
||||||
date,
|
date,
|
||||||
ms,
|
ms,
|
||||||
lxc_log_priority_to_string(event->priority),
|
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);
|
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 = {
|
static struct lxc_log_appender log_appender_stderr = {
|
||||||
.name = "stderr",
|
.name = "stderr",
|
||||||
.append = log_append_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)
|
extern void lxc_log_close(void)
|
||||||
{
|
{
|
||||||
|
closelog();
|
||||||
|
free(log_vmname);
|
||||||
|
log_vmname = NULL;
|
||||||
if (lxc_log_fd == -1)
|
if (lxc_log_fd == -1)
|
||||||
return;
|
return;
|
||||||
close(lxc_log_fd);
|
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;
|
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:
|
* lxc_log_init:
|
||||||
* Called from lxc front-end programs (like lxc-create, lxc-start) to
|
* 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)
|
if (prefix)
|
||||||
lxc_log_set_prefix(prefix);
|
lxc_log_set_prefix(prefix);
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
log_vmname = strdup(name);
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
if (strcmp(file, "none") == 0)
|
if (strcmp(file, "none") == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -314,6 +314,8 @@ extern int lxc_log_init(const char *name, const char *file,
|
|||||||
const char *lxcpath);
|
const char *lxcpath);
|
||||||
|
|
||||||
extern int lxc_log_set_file(int *fd, const char *fname);
|
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 int lxc_log_set_level(int *dest, int level);
|
||||||
extern void lxc_log_set_prefix(const char *prefix);
|
extern void lxc_log_set_prefix(const char *prefix);
|
||||||
extern const char *lxc_log_get_file(void);
|
extern const char *lxc_log_get_file(void);
|
||||||
|
@ -255,6 +255,13 @@ restart:
|
|||||||
WARN("inherited fd %d", fd);
|
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 */
|
closedir(dir); /* cannot fail */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user