diff --git a/include/osmocore/Makefile.am b/include/osmocore/Makefile.am index e1ba2c638..1c3a33f33 100644 --- a/include/osmocore/Makefile.am +++ b/include/osmocore/Makefile.am @@ -1,7 +1,7 @@ osmocore_HEADERS = signal.h linuxlist.h timer.h select.h msgb.h \ tlv.h bitvec.h comp128.h statistics.h gsm_utils.h utils.h \ gsmtap.h write_queue.h rsl.h gsm48.h rxlev_stat.h mncc.h \ - gsm48_ie.h debug.h + gsm48_ie.h logging.h if ENABLE_TALLOC osmocore_HEADERS += talloc.h diff --git a/include/osmocore/debug.h b/include/osmocore/debug.h deleted file mode 100644 index 0caec2831..000000000 --- a/include/osmocore/debug.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef _OSMOCORE_DEBUG_H -#define _OSMOCORE_DEBUG_H - -#include -#include -#include - -#define DEBUG_MAX_CATEGORY 32 -#define DEBUG_MAX_CTX 8 -#define DEBUG_MAX_FILTERS 8 - -#define DEBUG - -#ifdef DEBUG -#define DEBUGP(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ## args) -#define DEBUGPC(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ## args) -#else -#define DEBUGP(xss, fmt, args...) -#define DEBUGPC(ss, fmt, args...) -#endif - -#define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1]; - -char *hexdump(const unsigned char *buf, int len); -void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6))); - -/* new logging interface */ -#define LOGP(ss, level, fmt, args...) \ - debugp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args) -#define LOGPC(ss, level, fmt, args...) \ - debugp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args) - -/* different levels */ -#define LOGL_DEBUG 1 /* debugging information */ -#define LOGL_INFO 3 -#define LOGL_NOTICE 5 /* abnormal/unexpected condition */ -#define LOGL_ERROR 7 /* error condition, requires user action */ -#define LOGL_FATAL 8 /* fatal, program aborted */ - -#define DEBUG_FILTER_ALL 0x0001 - -struct debug_category { - uint8_t loglevel; - uint8_t enabled; -}; - -struct debug_info_cat { - const char *name; - const char *color; - const char *description; - uint8_t loglevel; - uint8_t enabled; -}; - -/* debug context information, passed to filter */ -struct debug_context { - void *ctx[DEBUG_MAX_CTX+1]; -}; - -struct debug_target; - -typedef int debug_filter(const struct debug_context *ctx, - struct debug_target *target); - -struct debug_info { - /* filter callback function */ - debug_filter *filter_fn; - - /* per-category information */ - const struct debug_info_cat *cat; - unsigned int num_cat; -}; - -struct debug_target { - struct llist_head entry; - - int filter_map; - void *filter_data[DEBUG_MAX_FILTERS+1]; - - struct debug_category categories[DEBUG_MAX_CATEGORY+1]; - uint8_t loglevel; - int use_color:1; - int print_timestamp:1; - - union { - struct { - FILE *out; - } tgt_stdout; - - struct { - int priority; - } tgt_syslog; - - struct { - void *vty; - } tgt_vty; - }; - - void (*output) (struct debug_target *target, const char *string); -}; - -/* use the above macros */ -void debugp2(unsigned int subsys, unsigned int level, char *file, - int line, int cont, const char *format, ...) - __attribute__ ((format (printf, 6, 7))); -void debug_init(const struct debug_info *cat); - -/* context management */ -void debug_reset_context(void); -int debug_set_context(uint8_t ctx, void *value); - -/* filter on the targets */ -void debug_set_all_filter(struct debug_target *target, int); - -void debug_set_use_color(struct debug_target *target, int); -void debug_set_print_timestamp(struct debug_target *target, int); -void debug_set_log_level(struct debug_target *target, int log_level); -void debug_parse_category_mask(struct debug_target *target, const char* mask); -int debug_parse_level(const char *lvl); -int debug_parse_category(const char *category); -void debug_set_category_filter(struct debug_target *target, int category, - int enable, int level); - -/* management of the targets */ -struct debug_target *debug_target_create(void); -struct debug_target *debug_target_create_stderr(void); -void debug_add_target(struct debug_target *target); -void debug_del_target(struct debug_target *target); - -#endif /* _OSMOCORE_DEBUG_H */ diff --git a/include/osmocore/logging.h b/include/osmocore/logging.h new file mode 100644 index 000000000..93f18a07b --- /dev/null +++ b/include/osmocore/logging.h @@ -0,0 +1,130 @@ +#ifndef _OSMOCORE_LOGGING_H +#define _OSMOCORE_LOGGING_H + +#include +#include +#include + +#define LOG_MAX_CATEGORY 32 +#define LOG_MAX_CTX 8 +#define LOG_MAX_FILTERS 8 + +#define DEBUG + +#ifdef DEBUG +#define DEBUGP(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 0, fmt, ## args) +#define DEBUGPC(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 1, fmt, ## args) +#else +#define DEBUGP(xss, fmt, args...) +#define DEBUGPC(ss, fmt, args...) +#endif + +#define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1]; + +char *hexdump(const unsigned char *buf, int len); +void logp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6))); + +/* new logging interface */ +#define LOGP(ss, level, fmt, args...) \ + logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args) +#define LOGPC(ss, level, fmt, args...) \ + logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args) + +/* different levels */ +#define LOGL_DEBUG 1 /* debugging information */ +#define LOGL_INFO 3 +#define LOGL_NOTICE 5 /* abnormal/unexpected condition */ +#define LOGL_ERROR 7 /* error condition, requires user action */ +#define LOGL_FATAL 8 /* fatal, program aborted */ + +#define LOG_FILTER_ALL 0x0001 + +struct log_category { + uint8_t loglevel; + uint8_t enabled; +}; + +struct log_info_cat { + const char *name; + const char *color; + const char *description; + uint8_t loglevel; + uint8_t enabled; +}; + +/* log context information, passed to filter */ +struct log_context { + void *ctx[LOG_MAX_CTX+1]; +}; + +struct log_target; + +typedef int log_filter(const struct log_context *ctx, + struct log_target *target); + +struct log_info { + /* filter callback function */ + log_filter *filter_fn; + + /* per-category information */ + const struct log_info_cat *cat; + unsigned int num_cat; +}; + +struct log_target { + struct llist_head entry; + + int filter_map; + void *filter_data[LOG_MAX_FILTERS+1]; + + struct log_category categories[LOG_MAX_CATEGORY+1]; + uint8_t loglevel; + int use_color:1; + int print_timestamp:1; + + union { + struct { + FILE *out; + } tgt_stdout; + + struct { + int priority; + } tgt_syslog; + + struct { + void *vty; + } tgt_vty; + }; + + void (*output) (struct log_target *target, const char *string); +}; + +/* use the above macros */ +void logp2(unsigned int subsys, unsigned int level, char *file, + int line, int cont, const char *format, ...) + __attribute__ ((format (printf, 6, 7))); +void log_init(const struct log_info *cat); + +/* context management */ +void log_reset_context(void); +int log_set_context(uint8_t ctx, void *value); + +/* filter on the targets */ +void log_set_all_filter(struct log_target *target, int); + +void log_set_use_color(struct log_target *target, int); +void log_set_print_timestamp(struct log_target *target, int); +void log_set_log_level(struct log_target *target, int log_level); +void log_parse_category_mask(struct log_target *target, const char* mask); +int log_parse_level(const char *lvl); +int log_parse_category(const char *category); +void log_set_category_filter(struct log_target *target, int category, + int enable, int level); + +/* management of the targets */ +struct log_target *log_target_create(void); +struct log_target *log_target_create_stderr(void); +void log_add_target(struct log_target *target); +void log_del_target(struct log_target *target); + +#endif /* _OSMOCORE_LOGGING_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 75a66bf16..16978074a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,7 +10,7 @@ lib_LTLIBRARIES = libosmocore.la libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c rxlev_stat.c \ tlv_parser.c bitvec.c comp128.c gsm_utils.c statistics.c \ write_queue.c utils.c rsl.c gsm48.c gsm48_ie.c \ - debug.c + logging.c if ENABLE_TALLOC libosmocore_la_SOURCES += talloc.c diff --git a/src/debug.c b/src/logging.c similarity index 67% rename from src/debug.c rename to src/logging.c index 19fc30587..508ccfd3e 100644 --- a/src/debug.c +++ b/src/logging.c @@ -30,12 +30,12 @@ #include #include -#include +#include -static const struct debug_info *debug_info; +static const struct log_info *log_info; -static struct debug_context debug_context; -static void *tall_dbg_ctx = NULL; +static struct log_context log_context; +static void *tall_log_ctx = NULL; static LLIST_HEAD(target_list); static const struct value_string loglevel_strs[] = { @@ -48,17 +48,17 @@ static const struct value_string loglevel_strs[] = { { 0, NULL }, }; -int debug_parse_level(const char *lvl) +int log_parse_level(const char *lvl) { return get_string_value(loglevel_strs, lvl); } -int debug_parse_category(const char *category) +int log_parse_category(const char *category) { int i; - for (i = 0; i < debug_info->num_cat; ++i) { - if (!strcasecmp(debug_info->cat[i].name+1, category)) + for (i = 0; i < log_info->num_cat; ++i) { + if (!strcasecmp(log_info->cat[i].name+1, category)) return i; } @@ -70,7 +70,7 @@ int debug_parse_category(const char *category) * The format can be this: category1:category2:category3 * or category1,2:category2,3:... */ -void debug_parse_category_mask(struct debug_target* target, const char *_mask) +void log_parse_category_mask(struct log_target* target, const char *_mask) { int i = 0; char *mask = strdup(_mask); @@ -82,14 +82,14 @@ void debug_parse_category_mask(struct debug_target* target, const char *_mask) category_token = strtok(mask, ":"); do { - for (i = 0; i < debug_info->num_cat; ++i) { + for (i = 0; i < log_info->num_cat; ++i) { char* colon = strstr(category_token, ","); int length = strlen(category_token); if (colon) length = colon - category_token; - if (strncasecmp(debug_info->cat[i].name, category_token, + if (strncasecmp(log_info->cat[i].name, category_token, length) == 0) { int level = 0; @@ -107,13 +107,13 @@ void debug_parse_category_mask(struct debug_target* target, const char *_mask) static const char* color(int subsys) { - if (subsys < debug_info->num_cat) - return debug_info->cat[subsys].color; + if (subsys < log_info->num_cat) + return log_info->cat[subsys].color; return NULL; } -static void _output(struct debug_target *target, unsigned int subsys, +static void _output(struct log_target *target, unsigned int subsys, char *file, int line, int cont, const char *format, va_list ap) { @@ -160,17 +160,17 @@ static void _output(struct debug_target *target, unsigned int subsys, } -static void _debugp(unsigned int subsys, int level, char *file, int line, - int cont, const char *format, va_list ap) +static void _logp(unsigned int subsys, int level, char *file, int line, + int cont, const char *format, va_list ap) { - struct debug_target *tar; + struct log_target *tar; llist_for_each_entry(tar, &target_list, entry) { - struct debug_category *category; + struct log_category *category; int output = 0; category = &tar->categories[subsys]; - /* subsystem is not supposed to be debugged */ + /* subsystem is not supposed to be logged */ if (!category->enabled) continue; @@ -186,10 +186,10 @@ static void _debugp(unsigned int subsys, int level, char *file, int line, /* Apply filters here... if that becomes messy we will * need to put filters in a list and each filter will * say stop, continue, output */ - if ((tar->filter_map & DEBUG_FILTER_ALL) != 0) + if ((tar->filter_map & LOG_FILTER_ALL) != 0) output = 1; - else if (debug_info->filter_fn) - output = debug_info->filter_fn(&debug_context, + else if (log_info->filter_fn) + output = log_info->filter_fn(&log_context, tar); if (output) { @@ -207,22 +207,22 @@ static void _debugp(unsigned int subsys, int level, char *file, int line, } } -void debugp(unsigned int subsys, char *file, int line, int cont, - const char *format, ...) +void logp(unsigned int subsys, char *file, int line, int cont, + const char *format, ...) { va_list ap; va_start(ap, format); - _debugp(subsys, LOGL_DEBUG, file, line, cont, format, ap); + _logp(subsys, LOGL_DEBUG, file, line, cont, format, ap); va_end(ap); } -void debugp2(unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, ...) +void logp2(unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, ...) { va_list ap; va_start(ap, format); - _debugp(subsys, level, file, line, cont, format, ap); + _logp(subsys, level, file, line, cont, format, ap); va_end(ap); } @@ -245,91 +245,91 @@ char *hexdump(const unsigned char *buf, int len) return hexd_buff; } -void debug_add_target(struct debug_target *target) +void log_add_target(struct log_target *target) { llist_add_tail(&target->entry, &target_list); } -void debug_del_target(struct debug_target *target) +void log_del_target(struct log_target *target) { llist_del(&target->entry); } -void debug_reset_context(void) +void log_reset_context(void) { - memset(&debug_context, 0, sizeof(debug_context)); + memset(&log_context, 0, sizeof(log_context)); } -int debug_set_context(uint8_t ctx_nr, void *value) +int log_set_context(uint8_t ctx_nr, void *value) { - if (ctx_nr > DEBUG_MAX_CTX) + if (ctx_nr > LOG_MAX_CTX) return -EINVAL; - debug_context.ctx[ctx_nr] = value; + log_context.ctx[ctx_nr] = value; return 0; } -void debug_set_all_filter(struct debug_target *target, int all) +void log_set_all_filter(struct log_target *target, int all) { if (all) - target->filter_map |= DEBUG_FILTER_ALL; + target->filter_map |= LOG_FILTER_ALL; else - target->filter_map &= ~DEBUG_FILTER_ALL; + target->filter_map &= ~LOG_FILTER_ALL; } -void debug_set_use_color(struct debug_target *target, int use_color) +void log_set_use_color(struct log_target *target, int use_color) { target->use_color = use_color; } -void debug_set_print_timestamp(struct debug_target *target, int print_timestamp) +void log_set_print_timestamp(struct log_target *target, int print_timestamp) { target->print_timestamp = print_timestamp; } -void debug_set_log_level(struct debug_target *target, int log_level) +void log_set_log_level(struct log_target *target, int log_level) { target->loglevel = log_level; } -void debug_set_category_filter(struct debug_target *target, int category, +void log_set_category_filter(struct log_target *target, int category, int enable, int level) { - if (category >= debug_info->num_cat) + if (category >= log_info->num_cat) return; target->categories[category].enabled = !!enable; target->categories[category].loglevel = level; } -static void _stderr_output(struct debug_target *target, const char *log) +static void _stderr_output(struct log_target *target, const char *log) { fprintf(target->tgt_stdout.out, "%s", log); fflush(target->tgt_stdout.out); } -struct debug_target *debug_target_create(void) +struct log_target *log_target_create(void) { - struct debug_target *target; + struct log_target *target; - target = talloc_zero(tall_dbg_ctx, struct debug_target); + target = talloc_zero(tall_log_ctx, struct log_target); if (!target) return NULL; INIT_LLIST_HEAD(&target->entry); - memcpy(target->categories, debug_info->cat, - sizeof(struct debug_category)*debug_info->num_cat); + memcpy(target->categories, log_info->cat, + sizeof(struct log_category)*log_info->num_cat); target->use_color = 1; target->print_timestamp = 0; target->loglevel = 0; return target; } -struct debug_target *debug_target_create_stderr(void) +struct log_target *log_target_create_stderr(void) { - struct debug_target *target; + struct log_target *target; - target = debug_target_create(); + target = log_target_create(); if (!target) return NULL; @@ -338,8 +338,8 @@ struct debug_target *debug_target_create_stderr(void) return target; } -void debug_init(const struct debug_info *cat) +void log_init(const struct log_info *cat) { - tall_dbg_ctx = talloc_named_const(NULL, 1, "debug"); - debug_info = cat; + tall_log_ctx = talloc_named_const(NULL, 1, "logging"); + log_info = cat; }