From dceda380abb90707b4c42ee05ec5363c869c03fb Mon Sep 17 00:00:00 2001 From: LiuHao Date: Thu, 19 Mar 2020 16:26:24 +0800 Subject: [PATCH] Support syslog for console log Signed-off-by: LiuHao --- src/lxc/confile.c | 108 +++++++++++++++++++++++++++++++++++++++++++++ src/lxc/terminal.c | 44 +++++++++++++++++- src/lxc/terminal.h | 9 ++++ 3 files changed, 160 insertions(+), 1 deletion(-) diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 747ccec7..a14d0756 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -93,6 +93,9 @@ lxc_config_define(console_logfile); lxc_config_define(console_path); lxc_config_define(console_rotate); lxc_config_define(console_size); +lxc_config_define(console_log_driver); +lxc_config_define(console_syslog_tag); +lxc_config_define(console_syslog_facility); lxc_config_define(environment); lxc_config_define(ephemeral); lxc_config_define(execute_cmd); @@ -176,6 +179,9 @@ static struct lxc_config_t config_jump_table[] = { { "lxc.console.path", set_config_console_path, get_config_console_path, clr_config_console_path, }, { "lxc.console.rotate", set_config_console_rotate, get_config_console_rotate, clr_config_console_rotate, }, { "lxc.console.size", set_config_console_size, get_config_console_size, clr_config_console_size, }, + { "lxc.console.logdriver", set_config_console_log_driver, get_config_console_log_driver, clr_config_console_log_driver, }, + { "lxc.console.syslog_tag", set_config_console_syslog_tag, get_config_console_syslog_tag, clr_config_console_syslog_tag, }, + { "lxc.console.syslog_facility", set_config_console_syslog_facility, get_config_console_syslog_facility, clr_config_console_syslog_facility, }, { "lxc.environment", set_config_environment, get_config_environment, clr_config_environment, }, { "lxc.ephemeral", set_config_ephemeral, get_config_ephemeral, clr_config_ephemeral, }, { "lxc.execute.cmd", set_config_execute_cmd, get_config_execute_cmd, clr_config_execute_cmd, }, @@ -1932,6 +1938,68 @@ static int set_config_console_size(const char *key, const char *value, return 0; } +static int set_config_console_log_driver(const char *key, const char *value, + struct lxc_conf *lxc_conf, void *data) +{ + return set_config_string_item(&lxc_conf->console.log_driver, value); +} + +static int set_config_console_syslog_tag(const char *key, const char *value, + struct lxc_conf *lxc_conf, void *data) +{ + char buf[16] = { 0 }; + + if (value == NULL) { + return -1; + } + (void)strlcpy(buf, value, 16); + return set_config_string_item(&lxc_conf->console.log_syslog_tag, buf); +} + +static int parse_facility(const char *facility) +{ +#define FACILITIES_LEN 20 + const char *facility_keys[FACILITIES_LEN] = { + "kern", "user", "mail", "daemon", "auth", + "syslog", "lpr", "news", "uucp", "cron", "authpriv", "ftp", + "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7" + }; + const int facilities[FACILITIES_LEN] = { + LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_SYSLOG, + LOG_LPR, LOG_NEWS, LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_FTP, + LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, + LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 + }; + int i = 0; + + if (facility == NULL) { + return -1; + } + + for (; i < FACILITIES_LEN; i++) { + if (strcmp(facility, facility_keys[i]) == 0) { + return facilities[i]; + } + } + + return -1; +} + +static int set_config_console_syslog_facility(const char *key, const char *value, + struct lxc_conf *lxc_conf, void *data) +{ + int facility; + + facility = parse_facility(value); + if (facility < 0) { + NOTICE("Invalid facility: %s", value); + facility = LOG_DAEMON; + } + + lxc_conf->console.log_syslog_facility = facility; + return 0; +} + int append_unexp_config_line(const char *line, struct lxc_conf *conf) { size_t linelen; @@ -3713,6 +3781,23 @@ static int get_config_console_size(const char *key, char *retv, int inlen, return lxc_get_conf_uint64(c, retv, inlen, c->console.log_size); } +static int get_config_console_log_driver(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) +{ + return lxc_get_conf_str(retv, inlen, c->console.log_driver); +} + +static int get_config_console_syslog_tag(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) +{ + return lxc_get_conf_str(retv, inlen, c->console.log_syslog_tag); +} + +static int get_config_console_syslog_facility(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) +{ + return lxc_get_conf_int(c, retv, inlen, c->console.log_syslog_facility); +} static int get_config_seccomp_profile(const char *key, char *retv, int inlen, struct lxc_conf *c, void *data) @@ -4368,6 +4453,29 @@ static inline int clr_config_console_size(const char *key, struct lxc_conf *c, return 0; } +static inline int clr_config_console_log_driver(const char *key, + struct lxc_conf *c, void *data) +{ + free(c->console.log_driver); + c->console.log_driver = NULL; + return 0; +} + +static inline int clr_config_console_syslog_tag(const char *key, + struct lxc_conf *c, void *data) +{ + free(c->console.log_syslog_tag); + c->console.log_syslog_tag= NULL; + return 0; +} + +static inline int clr_config_console_syslog_facility(const char *key, + struct lxc_conf *c, void *data) +{ + c->console.log_syslog_facility = LOG_DAEMON; + return 0; +} + static inline int clr_config_seccomp_profile(const char *key, struct lxc_conf *c, void *data) { diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c index 535f3746..8c8edac4 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c @@ -49,6 +49,7 @@ #include "terminal.h" #include "logger_json_file.h" #include "utils.h" +#include "include/strlcpy.h" #if HAVE_PTY_H #include @@ -477,7 +478,7 @@ static bool get_now_time_buffer(char *timebuffer, size_t maxsize) return get_time_buffer(&ts, timebuffer, maxsize); } -static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *type, const char *buf, +static ssize_t lxc_logger_json_write(struct lxc_terminal *terminal, const char *type, const char *buf, int bytes_read) { logger_json_file *msg = NULL; @@ -521,6 +522,31 @@ cleanup: return ret; } +static ssize_t lxc_logger_syslog_write(struct lxc_terminal *terminal, const char *buf) +{ + syslog(LOG_INFO, "%s", buf); + return 0; +} + +static inline bool is_syslog(const char *driver) +{ + if (driver == NULL) { + return false; + } + + return (strcmp("syslog", driver) == 0); +} + +static inline ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *type, const char *buf, + int bytes_read) +{ + if (is_syslog(terminal->log_driver)) { + return lxc_logger_syslog_write(terminal, buf); + } + + return lxc_logger_json_write(terminal, type, buf, bytes_read); +} + static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, const char *type, char *buf, int bytes_read) { @@ -1210,6 +1236,11 @@ void lxc_terminal_delete(struct lxc_terminal *terminal) close(terminal->log_fd); terminal->log_fd = -1; + if (is_syslog(terminal->log_driver)) { + closelog(); + free(terminal->log_driver); + } + /* isulad: close all pipes */ if (terminal->pipes[0][0] >= 0) close(terminal->pipes[0][0]); @@ -1504,6 +1535,17 @@ int lxc_terminal_setup(struct lxc_conf *conf) if (ret < 0) return -1; + if (is_syslog(terminal->log_driver)) { + if (terminal->log_syslog_tag == NULL) { + terminal->log_syslog_tag = malloc(16 * sizeof(char)); + (void)strlcpy(terminal->log_syslog_tag, conf->name, 16); + } + if (terminal->log_syslog_facility <= 0) { + terminal->log_syslog_facility = LOG_DAEMON; + } + openlog(terminal->log_syslog_tag, LOG_PID, terminal->log_syslog_facility); + } + ret = lxc_terminal_create_log_file(terminal); if (ret < 0) goto err; diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h index 4b5c70e8..197b44b9 100644 --- a/src/lxc/terminal.h +++ b/src/lxc/terminal.h @@ -106,6 +106,15 @@ struct lxc_terminal { /* whether the log file will be rotated */ unsigned int log_rotate; + + /* driver of log, support file and syslog */ + char *log_driver; + + /* syslog tag for every log */ + char *log_syslog_tag; + + /* syslog facility */ + int log_syslog_facility; }; struct /* lxc_terminal_ringbuf */ { -- 2.25.1