[sheepdog] [PATCH] lib: implement a mechanism for logging with standard syslog

Hitoshi Mitake mitake.hitoshi at gmail.com
Tue Aug 13 11:24:11 CEST 2013


Some users want sheepdog processes to write log to standard syslog
(e.g. /var/log/syslog), mainly for utilizing standard log rotation
policy of their systems.

For this purpose, this patch implements a mechanism for using the
standard syslog in logger and adds a new option "-s" to sheep and
shepherd for using it.

Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
 include/logger.h    |  9 ++++++++-
 lib/logger.c        | 35 ++++++++++++++++++++++-------------
 sheep/sheep.c       | 12 +++++++++---
 shepherd/shepherd.c |  9 ++++++++-
 4 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/include/logger.h b/include/logger.h
index 5bb3a65..e34793a 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -30,9 +30,16 @@ struct logger_user_info {
 
 extern int sd_log_level;
 
+enum log_out_dest {
+	TO_STDOUT,
+	TO_FILE,
+	TO_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_out_dest dest, 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 b7dbd2f..8daaa79 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -38,6 +38,7 @@
 #include "util.h"
 
 static bool colorize;
+static bool timestamp = true;
 static const char * const log_color[] = {
 	[SDOG_EMERG] = TEXT_BOLD_RED,
 	[SDOG_ALERT] = TEXT_BOLD_RED,
@@ -212,9 +213,11 @@ static int server_log_formatter(char *buff, size_t size,
 	struct tm tm;
 	int worker_name_len = strlen(msg->worker_name);
 
-	localtime_r(&msg->tv.tv_sec, &tm);
-	strftime(p, size, "%b %2d %H:%M:%S ", (const struct tm *)&tm);
-	p += strlen(p);
+	if (timestamp) {
+		localtime_r(&msg->tv.tv_sec, &tm);
+		strftime(p, size, "%b %2d %H:%M:%S ", (const struct tm *)&tm);
+		p += strlen(p);
+	}
 
 	if (colorize) {
 		pstrcpy(p, size - strlen(buff), TEXT_YELLOW);
@@ -514,17 +517,20 @@ static void crash_handler(int signo)
 	reraise_crash_signal(signo, 1);
 }
 
-static void logger(char *log_dir, char *outfile)
+static void logger(char *log_dir, bool use_syslog, char *outfile)
 {
 	int fd;
 
 	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 (!use_syslog) {
+		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;
 
 	fd = open("/dev/null", O_RDWR);
@@ -558,7 +564,7 @@ static void logger(char *log_dir, char *outfile)
 	while (la->active) {
 		log_flush();
 
-		if (max_logsize) {
+		if (max_logsize && 0 <= log_fd) {
 			off_t offset;
 
 			pthread_mutex_lock(&logsize_lock);
@@ -604,8 +610,8 @@ 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,
-		     char *outfile)
+int log_init(const char *program_name, enum log_out_dest dest, int level,
+	     char *outfile)
 {
 	char log_dir[PATH_MAX], tmp[PATH_MAX];
 	int size = level == SDOG_DEBUG ? LOG_SPACE_DEBUG_SIZE : LOG_SPACE_SIZE;
@@ -619,10 +625,13 @@ int log_init(const char *program_name, bool to_stdout, int level,
 
 	semkey = random();
 
-	if (to_stdout) {
+	if (dest == TO_STDOUT) {
 		if (is_stdout_console())
 			colorize = true;
 	} else {
+		if (dest == TO_SYSLOG)
+			timestamp = false;
+
 		if (logarea_init(size)) {
 			syslog(LOG_ERR, "failed to initialize the logger\n");
 			return 1;
@@ -644,7 +653,7 @@ int log_init(const char *program_name, bool to_stdout, int level,
 		if (logger_pid)
 			syslog(LOG_WARNING, "logger pid %d starting\n", logger_pid);
 		else
-			logger(log_dir, outfile);
+			logger(log_dir, dest != TO_FILE, outfile);
 	}
 
 	return 0;
diff --git a/sheep/sheep.c b/sheep/sheep.c
index 461a729..6b9489a 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -119,6 +119,8 @@ static struct sd_option sheep_options[] = {
 	 "(default: 7000)"},
 	{'P', "pidfile", true, "create a pid file"},
 	{'r', "http", true, "enable http service", http_help},
+	{'s', "syslog", false, "log to standard syslog instead of a dedicated "
+	 "file (sheep.log)"},
 	{'u', "upgrade", false, "upgrade to the latest data layout"},
 	{'v', "version", false, "show the version"},
 	{'w', "cache", true, "enable object cache", cache_help},
@@ -577,12 +579,13 @@ int main(int argc, char **argv)
 	const char *dirp = DEFAULT_OBJECT_DIR, *short_options;
 	char *dir, *p, *pid_file = NULL, *bindaddr = NULL, 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 *log_format = "server", *http_address = NULL;
 	static struct logger_user_info sheep_info;
+	enum log_out_dest log_dest = TO_FILE;
 
 	install_crash_handler(crash_handler);
 	signal(SIGPIPE, SIG_IGN);
@@ -640,7 +643,7 @@ int main(int argc, char **argv)
 			nr_vnodes = 0;
 			break;
 		case 'o':
-			to_stdout = true;
+			log_dest = TO_STDOUT;
 			break;
 		case 'z':
 			zone = strtol(optarg, &p, 10);
@@ -711,6 +714,9 @@ int main(int argc, char **argv)
 		case 'F':
 			log_format = optarg;
 			break;
+		case 's':
+			log_dest = TO_SYSLOG;
+			break;
 		default:
 			usage(1);
 			break;
@@ -747,7 +753,7 @@ int main(int argc, char **argv)
 	if (lock_and_daemon(is_daemon, dir))
 		exit(1);
 
-	ret = log_init(program_name, to_stdout, log_level, path);
+	ret = log_init(program_name, log_dest, log_level, path);
 	if (ret)
 		exit(1);
 
diff --git a/shepherd/shepherd.c b/shepherd/shepherd.c
index 77c09fb..b4bd1b6 100644
--- a/shepherd/shepherd.c
+++ b/shepherd/shepherd.c
@@ -611,6 +611,8 @@ static struct sd_option shepherd_options[] = {
 	{ 'l', "log-file", true,
 	  "specify a log file for writing logs of shepherd" },
 	{ 'p', "port", true, "specify TCP port on which to listen" },
+	{ 's', "syslog", false, "log to standard syslog instead of a dedicated "
+	  "file (/var/log/shepherd.log)" },
 	{ 0, NULL, false, NULL },
 };
 
@@ -662,6 +664,7 @@ int main(int argc, char **argv)
 	const char *log_file = "/var/log/shepherd.log";
 	const char *log_format = "server";
 	struct logger_user_info shepherd_info;
+	enum log_out_dest log_dest = TO_FILE;
 
 	int port = SHEPHERD_PORT;
 	const char *bindaddr = NULL;
@@ -690,6 +693,7 @@ int main(int argc, char **argv)
 			break;
 		case 'f':
 			daemonize = false;
+			log_dest = TO_STDOUT;
 			break;
 		case 'F':
 			log_format = optarg;
@@ -708,6 +712,9 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 			break;
+		case 's':
+			log_dest = TO_SYSLOG;
+			break;
 		default:
 			sd_err("unknown option: %c", ch);
 			usage();
@@ -728,7 +735,7 @@ int main(int argc, char **argv)
 	shepherd_info.port = port;
 	early_log_init(log_format, &shepherd_info);
 
-	ret = log_init(progname, !daemonize, log_level, (char *)log_file);
+	ret = log_init(progname, log_dest, log_level, (char *)log_file);
 	if (ret)
 		panic("initialize logger failed: %m");
 
-- 
1.8.1.2




More information about the sheepdog mailing list