[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