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 |