[Sheepdog] [PATCH] add log level support

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Sun Mar 14 16:59:51 CET 2010


Supports the following eight log levels:

SDOG_EMERG    0
SDOG_ALERT    1
SDOG_CRIT     2
SDOG_ERR      3
SDOG_WARNING  4
SDOG_NOTICE   5
SDOG_INFO     6
SDOG_DEBUG    7

Note that they correspond to syslog message levels.

A new logging function, vprintf supports the above. vprintf works like
printk in linux kernel:

vprintf(SDOG_NOTICE "Sheepdog daemon (version %s) started\n", SD_VERSION);

like printk, you can use vprintf without SDOG_ level (used SDOG_INFO
by default), however, it's a good idea to specify the level at all
times.

By default, collie prints messages that are more important than
INFO. You can change the default log level with "loglevel" boot
option.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
---
 collie/collie.c  |   16 ++++++++---
 include/logger.h |   34 ++++++++++++++++--------
 lib/logger.c     |   75 ++++++++++++++++++++++++++++++-----------------------
 3 files changed, 75 insertions(+), 50 deletions(-)

diff --git a/collie/collie.c b/collie/collie.c
index e1d160f..669e894 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/syslog.h>
 
 #include "collie.h"
 
@@ -23,12 +24,13 @@ static char program_name[] = "collie";
 static struct option const long_options[] = {
 	{"port", required_argument, 0, 'p'},
 	{"foreground", no_argument, 0, 'f'},
+	{"loglevel", required_argument, 0, 'l'},
 	{"debug", no_argument, 0, 'd'},
 	{"help", no_argument, 0, 'h'},
 	{0, 0, 0, 0},
 };
 
-static char *short_options = "p:fdh";
+static char *short_options = "p:fl:dh";
 
 static void usage(int status)
 {
@@ -41,6 +43,7 @@ static void usage(int status)
 Sheepdog Daemon, version %s\n\
   -p, --port              specify the listen port number\n\
   -f, --foreground        make the program run in the foreground\n\
+  -l, --loglevel          specify the message level printed by default\n\
   -d, --debug             print debug messages\n\
   -h, --help              display this help and exit\n\
 ", SD_VERSION);
@@ -56,7 +59,7 @@ int main(int argc, char **argv)
 	int ret, port = SD_LISTEN_PORT;
 	char *dir = DEFAULT_OBJECT_DIR;
 	int is_daemon = 1;
-	int is_debug = 0;
+	int log_level = LOG_INFO;
 
 	while ((ch = getopt_long(argc, argv, short_options, long_options,
 				 &longindex)) >= 0) {
@@ -67,8 +70,11 @@ int main(int argc, char **argv)
 		case 'f':
 			is_daemon = 0;
 			break;
+		case 'l':
+			log_level = atoi(optarg);
 		case 'd':
-			is_debug = 1;
+			/* removed soon. use loglevel instead */
+			log_level = LOG_DEBUG;
 			break;
 		case 'h':
 			usage(0);
@@ -82,7 +88,7 @@ int main(int argc, char **argv)
 	if (optind != argc)
 		dir = argv[optind];
 
-	ret = log_init(program_name, LOG_SPACE_SIZE, is_daemon, is_debug);
+	ret = log_init(program_name, LOG_SPACE_SIZE, is_daemon, log_level);
 	if (ret)
 		exit(1);
 
@@ -111,7 +117,7 @@ int main(int argc, char **argv)
 		exit(1);
 	}
 
-	dprintf("Sheepdog daemon (version %s) started\n", SD_VERSION);
+	vprintf(SDOG_NOTICE "Sheepdog daemon (version %s) started\n", SD_VERSION);
 
 	event_loop(-1);
 
diff --git a/include/logger.h b/include/logger.h
index 21494a7..7fa4cf1 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -27,6 +27,7 @@
 #define LOGGER_H
 
 #include <sys/sem.h>
+#include <sys/syslog.h>
 
 union semun {
 	int val;
@@ -38,9 +39,6 @@ union semun {
 #define LOG_SPACE_SIZE 16384
 #define MAX_MSG_SIZE 256
 
-extern int log_daemon;
-extern int log_level;
-
 struct logmsg {
 	short int prio;
 	void *next;
@@ -59,24 +57,36 @@ struct logarea {
 	union semun semarg;
 };
 
-extern int log_init (char * progname, int size, int daemon, int debug);
+extern int log_init(char * progname, int size, int daemon, int level);
 extern void log_close (void);
 extern void dump_logmsg (void *);
-extern void log_warning(const char *fmt, ...)
-	__attribute__ ((format (printf, 1, 2)));
-extern void log_error(const char *fmt, ...)
-	__attribute__ ((format (printf, 1, 2)));
-extern void log_debug(const char *fmt, ...)
-	__attribute__ ((format (printf, 1, 2)));
+extern void log_write(int prio, const char *func, int line, const char *fmt, ...)
+	__attribute__ ((format (printf, 4, 5)));
+
+#define	SDOG_EMERG	"<0>"
+#define	SDOG_ALERT	"<1>"
+#define	SDOG_CRIT	"<2>"
+#define	SDOG_ERR	"<3>"
+#define	SDOG_WARNING	"<4>"
+#define	SDOG_NOTICE	"<5>"
+#define	SDOG_INFO	"<6>"
+#define	SDOG_DEBUG	"<7>"
+
+#define vprintf(fmt, args...)						\
+do {									\
+	log_write(LOG_INFO, __func__, __LINE__, fmt, ##args);		\
+} while (0)
+
+/* don't use the following obsolete functions. use vprintf instead. */
 
 #define eprintf(fmt, args...)						\
 do {									\
-	log_error("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args);	\
+	log_write(LOG_ERR, __func__, __LINE__, fmt, ##args);		\
 } while (0)
 
 #define dprintf(fmt, args...)						\
 do {									\
-	log_debug("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args);	\
+	log_write(LOG_DEBUG, __func__, __LINE__, fmt, ##args);		\
 } while (0)
 
 #endif	/* LOG_H */
diff --git a/lib/logger.c b/lib/logger.c
index 5be8819..817fd0e 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -45,7 +45,7 @@
 
 static struct logarea *la;
 static char *log_name;
-static int is_debug;
+static int log_level;
 static pid_t pid;
 
 static int logarea_init (int size)
@@ -159,12 +159,13 @@ static void dump_logarea (void)
 }
 #endif
 
-static int log_enqueue(int prio, const char *fmt, va_list ap)
+static int log_enqueue(int prio, const char *func, int line, const char *fmt,
+		       va_list ap)
 {
 	int len, fwd;
-	char buff[MAX_MSG_SIZE];
-	struct logmsg * msg;
-	struct logmsg * lastmsg;
+	char *p, buff[MAX_MSG_SIZE];
+	struct logmsg *msg;
+	struct logmsg *lastmsg;
 
 	lastmsg = (struct logmsg *)la->tail;
 
@@ -173,7 +174,19 @@ static int log_enqueue(int prio, const char *fmt, va_list ap)
 		      strlen((char *)&lastmsg->str) * sizeof(char) + 1;
 		la->tail += fwd;
 	}
-	vsnprintf(buff, MAX_MSG_SIZE, fmt, ap);
+
+	p = buff;
+	snprintf(p, MAX_MSG_SIZE, "%s(%d) ", func, line);
+
+	p += strlen(p);
+
+	vsnprintf(p, MAX_MSG_SIZE - strlen(p), fmt, ap);
+
+	if (p[0] == '<' && p[2] == '>') {
+		prio = atoi(p + 1);
+		memmove(p, p + 3, strlen(p) - 3 + 1);
+	}
+
 	len = strlen(buff) * sizeof(char) + 1;
 
 	/* not enough space on tail : rewind */
@@ -250,7 +263,7 @@ static void log_syslog (void * buff)
 	syslog(msg->prio, "%s", (char *)&msg->str);
 }
 
-static void dolog(int prio, const char *fmt, va_list ap)
+static void dolog(int prio, const char *func, int line, const char *fmt, va_list ap)
 {
 	struct timespec ts;
 	struct sembuf ops;
@@ -267,7 +280,7 @@ static void dolog(int prio, const char *fmt, va_list ap)
 			return;
 		}
 
-		log_enqueue(prio, fmt, ap);
+		log_enqueue(prio, func, line, fmt, ap);
 
 		ops.sem_op = 1;
 		if (semop(la->semid, &ops, 1) < 0) {
@@ -275,37 +288,33 @@ static void dolog(int prio, const char *fmt, va_list ap)
 			return;
 		}
 	} else {
+		char *p, q[MAX_MSG_SIZE];
+
+		p = q;
+		vsnprintf(p, MAX_MSG_SIZE, fmt, ap);
+
+		if (p[0] == '<' && p[2] == '>') {
+			prio = atoi(p + 1);
+			p += 3;
+		}
+
+		if (prio > log_level)
+			return;
+
 		if (log_name)
-			fprintf(stderr, "%s: ", log_name);
-		vfprintf(stderr, fmt, ap);
+			fprintf(stderr, "%s: %s(%d) %s", log_name, func, line, p);
+		else
+			fprintf(stderr, "%s(%d) %s", func, line, p);
+
 		fflush(stderr);
 	}
 }
 
-void log_warning(const char *fmt, ...)
+void log_write(int prio, const char *func, int line, const char *fmt, ...)
 {
 	va_list ap;
 	va_start(ap, fmt);
-	dolog(LOG_WARNING, fmt, ap);
-	va_end(ap);
-}
-
-void log_error(const char *fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-	dolog(LOG_ERR, fmt, ap);
-	va_end(ap);
-}
-
-void log_debug(const char *fmt, ...)
-{
-	if (!is_debug)
-		return;
-
-	va_list ap;
-	va_start(ap, fmt);
-	dolog(LOG_DEBUG, fmt, ap);
+	dolog(prio, func, line, fmt, ap);
 	va_end(ap);
 }
 
@@ -333,9 +342,9 @@ static void log_flush(void)
 	}
 }
 
-int log_init(char *program_name, int size, int daemon, int debug)
+int log_init(char *program_name, int size, int daemon, int level)
 {
-	is_debug = debug;
+	log_level = level;
 
 	logdbg(stderr,"enter log_init\n");
 	log_name = program_name;
-- 
1.6.5




More information about the sheepdog mailing list