[sheepdog] [PATCH 2/2] logger: add a unified log destination option and syslog support
Hitoshi Mitake
mitake.hitoshi at lab.ntt.co.jp
Fri Jan 17 00:35:59 CET 2014
This patch adds a new parameter "dst=" to the "-l" option for
specifying logging destination. Possible parameters are below:
- default: a dedicated file under sheep's directory
- syslog: standard syslog
- stdout: standard output
In addition, this patch removes "-o" option, previous option for
logging with stdout. Now it is replaced with "-l dst=stdout".
Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
CHANGELOG.md | 6 ++++++
include/logger.h | 9 ++++++++-
lib/logger.c | 59 ++++++++++++++++++++++++++++++++++++------------------
sheep/sheep.c | 38 +++++++++++++++++++++++++++--------
4 files changed, 84 insertions(+), 28 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 568c795..1775fa2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,3 +16,9 @@ SHEEP COMMAND INTERFACE:
- improvements of help messages
- change format of the size format in -j (journaling) and -w (object cache) options. The new format is: n[TtGgMmKkb]. e.g. "-j size=1024M".
- rotate log when sheep process catches SIGHUP signal
+ - remove "-o" option for choosing stdout as an output of log
+ - unified "-l" option
+ - "-l format=..." for log format
+ - "-l level=..." for log level
+ - "-l dst=..." for log destination
+
diff --git a/include/logger.h b/include/logger.h
index bebe043..51525d5 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -30,9 +30,16 @@ struct logger_user_info {
extern int sd_log_level;
+enum log_dst_type {
+ LOG_DST_DEFAULT,
+ LOG_DST_STDOUT,
+ LOG_DST_SYSLOG,
+};
+
void early_log_init(const char *format_name,
struct logger_user_info *user_info);
-int log_init(const char *progname, bool to_stdout, int level, char *outfile);
+int log_init(const char *progname, enum log_dst_type type, int level,
+ char *outfile);
void log_close(void);
void dump_logmsg(void *);
void log_write(int prio, const char *func, int line, const char *fmt, ...)
diff --git a/lib/logger.c b/lib/logger.c
index 3b5607b..8d78077 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -95,7 +95,7 @@ struct logmsg {
char str[0];
};
-typedef int (*formatter_fn)(char *, size_t, const struct logmsg *);
+typedef int (*formatter_fn)(char *, size_t, const struct logmsg *, bool);
struct log_format {
const char *name;
@@ -120,6 +120,8 @@ static char *log_buff;
static int64_t max_logsize = 500 * 1024 * 1024; /*500MB*/
+static enum log_dst_type dst_type = LOG_DST_STDOUT;
+
/*
* block_sighup()
*
@@ -165,17 +167,20 @@ static const char *format_thread_name(char *str, size_t size, const char *name,
}
static int server_log_formatter(char *buff, size_t size,
- const struct logmsg *msg)
+ const struct logmsg *msg, bool print_time)
{
char *p = buff;
struct tm tm;
size_t len;
char thread_name[MAX_THREAD_NAME_LEN];
- localtime_r(&msg->tv.tv_sec, &tm);
- len = strftime(p, size, "%b %2d %H:%M:%S ", (const struct tm *)&tm);
- p += len;
- size -= len;
+ if (print_time) {
+ localtime_r(&msg->tv.tv_sec, &tm);
+ len = strftime(p, size, "%b %2d %H:%M:%S ",
+ (const struct tm *)&tm);
+ p += len;
+ size -= len;
+ }
len = snprintf(p, size, "%s%6s %s[%s] %s(%d) %s%s%s",
colorize ? log_color[msg->prio] : "",
@@ -194,7 +199,7 @@ static int server_log_formatter(char *buff, size_t size,
}
static int default_log_formatter(char *buff, size_t size,
- const struct logmsg *msg)
+ const struct logmsg *msg, bool print_time)
{
size_t len = min(size, msg->str_len);
@@ -204,7 +209,7 @@ static int default_log_formatter(char *buff, size_t size,
}
static int json_log_formatter(char *buff, size_t size,
- const struct logmsg *msg)
+ const struct logmsg *msg, bool print_time)
{
char *p = buff;
size_t len;
@@ -357,8 +362,11 @@ static void log_syslog(const struct logmsg *msg)
char str[MAX_MSG_SIZE];
int len;
- len = format->formatter(str, sizeof(str) - 1, msg);
- str[len++] = '\n';
+ len = format->formatter(str, sizeof(str) - 1, msg, log_fd >= 0);
+ if (dst_type == LOG_DST_DEFAULT)
+ str[len++] = '\n';
+ else /* LOG_DST_SYSLOG */
+ str[len++] = '\0';
block_sighup();
@@ -434,7 +442,8 @@ static void dolog(int prio, const char *func, int line,
char str_final[MAX_MSG_SIZE];
init_logmsg(msg, &tv, prio, func, line);
- len = format->formatter(str_final, sizeof(str_final) - 1, msg);
+ len = format->formatter(str_final, sizeof(str_final) - 1, msg,
+ true);
str_final[len++] = '\n';
xwrite(fileno(stderr), str_final, len);
fflush(stderr);
@@ -565,10 +574,12 @@ static void logger(char *log_dir, char *outfile)
log_buff = xzalloc(la->end - la->start);
- log_fd = open(outfile, O_CREAT | O_RDWR | O_APPEND, 0644);
- if (log_fd < 0) {
- syslog(LOG_ERR, "failed to open %s\n", outfile);
- exit(1);
+ if (dst_type == LOG_DST_DEFAULT) {
+ log_fd = open(outfile, O_CREAT | O_RDWR | O_APPEND, 0644);
+ if (log_fd < 0) {
+ syslog(LOG_ERR, "failed to open %s\n", outfile);
+ exit(1);
+ }
}
la->active = true;
@@ -605,7 +616,7 @@ static void logger(char *log_dir, char *outfile)
block_sighup();
- if (max_logsize) {
+ if (dst_type == LOG_DST_DEFAULT && max_logsize) {
off_t offset;
offset = lseek(log_fd, 0, SEEK_END);
@@ -651,7 +662,7 @@ void early_log_init(const char *format_name, struct logger_user_info *user_info)
exit(1);
}
-int log_init(const char *program_name, bool to_stdout, int level,
+int log_init(const char *program_name, enum log_dst_type type, int level,
char *outfile)
{
char log_dir[PATH_MAX], tmp[PATH_MAX];
@@ -666,10 +677,15 @@ int log_init(const char *program_name, bool to_stdout, int level,
semkey = random();
- if (to_stdout) {
+ switch (type) {
+ case LOG_DST_STDOUT:
if (is_stdout_console())
colorize = true;
- } else {
+ break;
+ case LOG_DST_SYSLOG:
+ openlog(program_name, LOG_PID, LOG_DAEMON);
+ /* fall through */
+ case LOG_DST_DEFAULT:
if (logarea_init(size)) {
syslog(LOG_ERR, "failed to initialize the logger\n");
return 1;
@@ -692,8 +708,13 @@ int log_init(const char *program_name, bool to_stdout, int level,
syslog(LOG_WARNING, "logger pid %d starting\n", logger_pid);
else
logger(log_dir, outfile);
+ break;
+ default:
+ sd_err("unknown type of log destination type: %d", type);
+ return -1;
}
+ dst_type = type;
return 0;
}
diff --git a/sheep/sheep.c b/sheep/sheep.c
index 09434c3..74c8a32 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -90,6 +90,7 @@ static const char log_help[] =
"\tdir=: path to the location of sheep.log\n"
"\tlevel=: log level of sheep.log\n"
"\tformat=: log format type\n\n"
+"\tdst=: log destination type\n\n"
"if dir is not specified, use metastore directory\n\n"
"Available log levels:\n"
" Level Description\n"
@@ -106,8 +107,12 @@ static const char log_help[] =
" FormatType Description\n"
" default raw format\n"
" server raw format with timestamp\n"
-" json json format\n"
-"default log format is server\n";
+" json json format\n\n"
+"Available log destination:\n"
+" DestinationType Description\n"
+" default dedicated file in a directory used by sheep\n"
+" syslog syslog of the system\n"
+" stdout standard output\n";
static struct sd_option sheep_options[] = {
{'b', "bindaddr", true, "specify IP address of interface to listen on",
@@ -127,7 +132,6 @@ static struct sd_option sheep_options[] = {
"specify the log level, the log directory and the log format"
"(log level default: 6 [SDOG_INFO])", log_help},
{'n', "nosync", false, "drop O_SYNC for write of backend"},
- {'o', "stdout", false, "log to stdout instead of shared logger"},
{'p', "port", true, "specify the TCP port on which to listen "
"(default: 7000)"},
{'P', "pidfile", true, "create a pid file"},
@@ -348,10 +352,19 @@ static int log_format_parser(const char *s)
return 0;
}
+static const char *log_dst = "default"; /* default: dedicated file */
+
+static int log_dst_parser(const char *s)
+{
+ log_dst = s;
+ return 0;
+}
+
static struct option_parser log_parsers[] = {
{ "level=", log_level_parser },
{ "dir=", log_dir_parser },
{ "format=", log_format_parser },
+ { "dst=", log_dst_parser },
{ NULL, NULL },
};
@@ -600,13 +613,14 @@ int main(int argc, char **argv)
const char *dirp = DEFAULT_OBJECT_DIR, *short_options;
char *dir, *p, *pid_file = NULL, *bindaddr = NULL, log_path[PATH_MAX],
*argp = NULL;
- bool is_daemon = true, to_stdout = false, explicit_addr = false;
+ bool is_daemon = true, explicit_addr = false;
int64_t zone = -1;
struct cluster_driver *cdrv;
struct option *long_options;
const char *http_options = NULL;
static struct logger_user_info sheep_info;
struct stat logdir_st;
+ enum log_dst_type log_dst_type;
install_crash_handler(crash_handler);
signal(SIGPIPE, SIG_IGN);
@@ -656,9 +670,6 @@ int main(int argc, char **argv)
/* same as '-v 0' */
nr_vnodes = 0;
break;
- case 'o':
- to_stdout = true;
- break;
case 'z':
zone = strtol(optarg, &p, 10);
if (optarg == p || zone < 0 || UINT32_MAX < zone
@@ -785,12 +796,23 @@ int main(int argc, char **argv)
free(logdir);
+ if (!strcmp(log_dst, "default"))
+ log_dst_type = LOG_DST_DEFAULT;
+ else if (!strcmp(log_dst, "stdout"))
+ log_dst_type = LOG_DST_STDOUT;
+ else if (!strcmp(log_dst, "syslog"))
+ log_dst_type = LOG_DST_SYSLOG;
+ else {
+ sd_err("invalid type of log destination: %s", log_dst);
+ exit(1);
+ }
+
srandom(port);
if (lock_and_daemon(is_daemon, dir))
exit(1);
- ret = log_init(program_name, to_stdout, log_level, log_path);
+ ret = log_init(program_name, log_dst_type, log_level, log_path);
if (ret)
exit(1);
--
1.7.10.4
More information about the sheepdog
mailing list