mirror of https://github.com/nirenjan/pinelog.git
Update logging library to include module and string buffer
This commit adds the following changes to pinelog: - Optional buffer to write the message to prior to writing to the output stream. This reduces the likelihood of log messages from multiple threads interleaving due to multiple calls to fputs/fprintf, etc. The default is to still write directly to the output stream, but the integrator can add a define of PINELOG_BUFFER_SZ to the CFLAGS, and this will allow the application to log messages that are shorter than the above size, including the timestamp, level and backtrace if any. - Optional module level logging. This allows more fine-grained debugging, where the application can control the log levels of the individual modules. By default, when modules are configured, they default to the global log level, but this can be overridden by the application.master
parent
5355a6ed8e
commit
3be94a24ba
225
Makefile.am
225
Makefile.am
|
@ -34,101 +34,198 @@ test_CFLAGS = \
|
|||
|
||||
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh
|
||||
TESTS = \
|
||||
test_ts_lvl_tr \
|
||||
test_ts_lvl_notr \
|
||||
test_ts_nolvl_tr \
|
||||
test_ts_nolvl_notr \
|
||||
test_nots_lvl_tr \
|
||||
test_nots_lvl_notr \
|
||||
test_nots_nolvl_tr \
|
||||
test_nots_nolvl_notr \
|
||||
bench_ts_lvl_tr \
|
||||
bench_ts_lvl_notr \
|
||||
bench_ts_nolvl_tr \
|
||||
bench_ts_nolvl_notr \
|
||||
bench_nots_lvl_tr \
|
||||
bench_nots_lvl_notr \
|
||||
bench_nots_nolvl_tr \
|
||||
bench_nots_nolvl_notr
|
||||
fp_test_ts_lvl_tr \
|
||||
fp_test_ts_lvl_notr \
|
||||
fp_test_ts_nolvl_tr \
|
||||
fp_test_ts_nolvl_notr \
|
||||
fp_test_nots_lvl_tr \
|
||||
fp_test_nots_lvl_notr \
|
||||
fp_test_nots_nolvl_tr \
|
||||
fp_test_nots_nolvl_notr \
|
||||
fp_bench_ts_lvl_tr \
|
||||
fp_bench_ts_lvl_notr \
|
||||
fp_bench_ts_nolvl_tr \
|
||||
fp_bench_ts_nolvl_notr \
|
||||
fp_bench_nots_lvl_tr \
|
||||
fp_bench_nots_lvl_notr \
|
||||
fp_bench_nots_nolvl_tr \
|
||||
fp_bench_nots_nolvl_notr \
|
||||
str_test_ts_lvl_tr \
|
||||
str_test_ts_lvl_notr \
|
||||
str_test_ts_nolvl_tr \
|
||||
str_test_ts_nolvl_notr \
|
||||
str_test_nots_lvl_tr \
|
||||
str_test_nots_lvl_notr \
|
||||
str_test_nots_nolvl_tr \
|
||||
str_test_nots_nolvl_notr \
|
||||
str_bench_ts_lvl_tr \
|
||||
str_bench_ts_lvl_notr \
|
||||
str_bench_ts_nolvl_tr \
|
||||
str_bench_ts_nolvl_notr \
|
||||
str_bench_nots_lvl_tr \
|
||||
str_bench_nots_lvl_notr \
|
||||
str_bench_nots_nolvl_tr \
|
||||
str_bench_nots_nolvl_notr
|
||||
|
||||
check_PROGRAMS = $(TESTS)
|
||||
test_ts_lvl_tr_SOURCES = $(test_SRCFILES)
|
||||
test_ts_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_test_ts_lvl_tr_SOURCES = $(test_SRCFILES)
|
||||
fp_test_ts_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=1
|
||||
test_ts_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_test_ts_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
test_ts_lvl_notr_SOURCES = $(test_SRCFILES)
|
||||
test_ts_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_test_ts_lvl_notr_SOURCES = $(test_SRCFILES)
|
||||
fp_test_ts_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=0
|
||||
test_ts_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_test_ts_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
test_ts_nolvl_tr_SOURCES = $(test_SRCFILES)
|
||||
test_ts_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_test_ts_nolvl_tr_SOURCES = $(test_SRCFILES)
|
||||
fp_test_ts_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=1
|
||||
test_ts_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_test_ts_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
test_ts_nolvl_notr_SOURCES = $(test_SRCFILES)
|
||||
test_ts_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_test_ts_nolvl_notr_SOURCES = $(test_SRCFILES)
|
||||
fp_test_ts_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=0
|
||||
test_ts_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_test_ts_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
test_nots_lvl_tr_SOURCES = $(test_SRCFILES)
|
||||
test_nots_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_test_nots_lvl_tr_SOURCES = $(test_SRCFILES)
|
||||
fp_test_nots_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=1
|
||||
test_nots_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_test_nots_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
test_nots_lvl_notr_SOURCES = $(test_SRCFILES)
|
||||
test_nots_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_test_nots_lvl_notr_SOURCES = $(test_SRCFILES)
|
||||
fp_test_nots_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=0
|
||||
test_nots_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_test_nots_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
test_nots_nolvl_tr_SOURCES = $(test_SRCFILES)
|
||||
test_nots_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_test_nots_nolvl_tr_SOURCES = $(test_SRCFILES)
|
||||
fp_test_nots_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=1
|
||||
test_nots_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_test_nots_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
test_nots_nolvl_notr_SOURCES = $(test_SRCFILES)
|
||||
test_nots_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_test_nots_nolvl_notr_SOURCES = $(test_SRCFILES)
|
||||
fp_test_nots_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=0
|
||||
test_nots_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_test_nots_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
bench_ts_lvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
bench_ts_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_bench_ts_lvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
fp_bench_ts_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=1
|
||||
bench_ts_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_bench_ts_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
bench_ts_lvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
bench_ts_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_bench_ts_lvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
fp_bench_ts_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=0
|
||||
bench_ts_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_bench_ts_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
bench_ts_nolvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
bench_ts_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_bench_ts_nolvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
fp_bench_ts_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=1
|
||||
bench_ts_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_bench_ts_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
bench_ts_nolvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
bench_ts_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_bench_ts_nolvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
fp_bench_ts_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=0
|
||||
bench_ts_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_bench_ts_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
bench_nots_lvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
bench_nots_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_bench_nots_lvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
fp_bench_nots_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=1
|
||||
bench_nots_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_bench_nots_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
bench_nots_lvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
bench_nots_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_bench_nots_lvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
fp_bench_nots_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=0
|
||||
bench_nots_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_bench_nots_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
bench_nots_nolvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
bench_nots_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_bench_nots_nolvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
fp_bench_nots_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=1
|
||||
bench_nots_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_bench_nots_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
bench_nots_nolvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
bench_nots_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
fp_bench_nots_nolvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
fp_bench_nots_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=0
|
||||
bench_nots_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
fp_bench_nots_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
test_CFLAGS += -DPINELOG_BUFFER_SZ=4096
|
||||
str_test_ts_lvl_tr_SOURCES = $(test_SRCFILES)
|
||||
str_test_ts_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=1
|
||||
str_test_ts_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_test_ts_lvl_notr_SOURCES = $(test_SRCFILES)
|
||||
str_test_ts_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=0
|
||||
str_test_ts_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_test_ts_nolvl_tr_SOURCES = $(test_SRCFILES)
|
||||
str_test_ts_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=1
|
||||
str_test_ts_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_test_ts_nolvl_notr_SOURCES = $(test_SRCFILES)
|
||||
str_test_ts_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=0
|
||||
str_test_ts_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_test_nots_lvl_tr_SOURCES = $(test_SRCFILES)
|
||||
str_test_nots_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=1
|
||||
str_test_nots_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_test_nots_lvl_notr_SOURCES = $(test_SRCFILES)
|
||||
str_test_nots_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=0
|
||||
str_test_nots_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_test_nots_nolvl_tr_SOURCES = $(test_SRCFILES)
|
||||
str_test_nots_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=1
|
||||
str_test_nots_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_test_nots_nolvl_notr_SOURCES = $(test_SRCFILES)
|
||||
str_test_nots_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=0
|
||||
str_test_nots_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_bench_ts_lvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
str_bench_ts_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=1
|
||||
str_bench_ts_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_bench_ts_lvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
str_bench_ts_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=0
|
||||
str_bench_ts_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_bench_ts_nolvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
str_bench_ts_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=1
|
||||
str_bench_ts_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_bench_ts_nolvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
str_bench_ts_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=1 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=0
|
||||
str_bench_ts_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_bench_nots_lvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
str_bench_nots_lvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=1
|
||||
str_bench_nots_lvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_bench_nots_lvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
str_bench_nots_lvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=1 -DPINELOG_SHOW_BACKTRACE=0
|
||||
str_bench_nots_lvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_bench_nots_nolvl_tr_SOURCES = $(bench_SRCFILES)
|
||||
str_bench_nots_nolvl_tr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=1
|
||||
str_bench_nots_nolvl_tr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
str_bench_nots_nolvl_notr_SOURCES = $(bench_SRCFILES)
|
||||
str_bench_nots_nolvl_notr_CFLAGS = $(WARN_CFLAGS) $(test_CFLAGS) \
|
||||
-DPINELOG_SHOW_DATE=0 -DPINELOG_SHOW_LEVEL=0 -DPINELOG_SHOW_BACKTRACE=0
|
||||
str_bench_nots_nolvl_notr_LDFLAGS = $(WARN_LDFLAGS)
|
||||
|
||||
|
|
155
pinelog.c
155
pinelog.c
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -24,6 +26,15 @@
|
|||
#define PINELOG_DEFAULT_LEVEL PINELOG_LVL_ERROR
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Buffer size is used to create an automatic buffer. Set to 0 to disable,
|
||||
* and write directly to the output stream. The drawback is that log messages
|
||||
* from multiple threads may be interleaved without a buffer.
|
||||
*/
|
||||
#ifndef PINELOG_BUFFER_SZ
|
||||
#define PINELOG_BUFFER_SZ 0
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* Configure logging parameters
|
||||
*********************************************************************/
|
||||
|
@ -76,6 +87,15 @@ static FILE *output_stream = NULL;
|
|||
/** Default logging level */
|
||||
static int log_level = PINELOG_DEFAULT_LEVEL;
|
||||
|
||||
/** Number of modules */
|
||||
static int num_modules = 0;
|
||||
|
||||
/** Per module logging levels */
|
||||
static int *module_level = NULL;
|
||||
|
||||
/** Module names */
|
||||
static const char **module_name = NULL;
|
||||
|
||||
/* Initialize defaults */
|
||||
#if defined __has_attribute
|
||||
# if __has_attribute(constructor)
|
||||
|
@ -88,6 +108,42 @@ void pinelog_set_defaults(void)
|
|||
log_level = PINELOG_DEFAULT_LEVEL;
|
||||
}
|
||||
|
||||
int pinelog_init(int count) {
|
||||
int rc = 0;
|
||||
int i;
|
||||
|
||||
if (count <= 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
num_modules = count;
|
||||
free(module_level);
|
||||
free(module_name);
|
||||
|
||||
module_level = calloc(sizeof(*module_level), count);
|
||||
if (module_level == NULL) {
|
||||
rc = errno;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
module_name = calloc(sizeof(*module_name), count);
|
||||
if (module_name == NULL) {
|
||||
rc = errno;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
module_level[i] = PINELOG_LVL_NOTSET;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
num_modules = 0;
|
||||
free(module_level);
|
||||
free(module_name);
|
||||
return rc;
|
||||
}
|
||||
#if defined __has_attribute
|
||||
# if __has_attribute(destructor)
|
||||
__attribute__((destructor))
|
||||
|
@ -153,15 +209,73 @@ int pinelog_set_level(int level)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pinelog_get_module_level(int module)
|
||||
{
|
||||
int global_level = pinelog_get_level();
|
||||
int level = global_level;
|
||||
|
||||
if (module >= 0 && module < num_modules) {
|
||||
level = module_level[module];
|
||||
if (level == PINELOG_LVL_NOTSET) {
|
||||
level = global_level;
|
||||
}
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
int pinelog_set_module_level(int module, int level)
|
||||
{
|
||||
if (module < 0 || module > num_modules) {
|
||||
if (module == PINELOG_MODULE_GLOBAL) {
|
||||
return pinelog_set_level(level);
|
||||
}
|
||||
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
if (level < PINELOG_LVL_NOTSET || level > PINELOG_LVL_TRACE) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
module_level[module] = level;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pinelog_setup_module(int module, const char *name)
|
||||
{
|
||||
if (module < 0 || module > num_modules) {
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
if (name == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
module_name[module] = name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Log the message to the output stream
|
||||
*********************************************************************/
|
||||
void pinelog_log_message(int level, const char *file, int line, const char *fmt, ...)
|
||||
void pinelog_log_message(int module, int level, const char *file, int line, const char *fmt, ...)
|
||||
{
|
||||
#if PINELOG_BUFFER_SZ
|
||||
char output_buffer[PINELOG_BUFFER_SZ];
|
||||
size_t buf_pos = 0;
|
||||
#endif
|
||||
|
||||
va_list ap;
|
||||
|
||||
/* Break out if the module is not in the acceptable range */
|
||||
if ((module < 0 || module >= num_modules ) && module != PINELOG_MODULE_GLOBAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset the level if we are in a module and the level is NOTSET */
|
||||
/* Don't log anything if the level is not severe enough */
|
||||
if (level > log_level || level < 0) {
|
||||
if (level > pinelog_get_module_level(module) || level < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -187,12 +301,17 @@ void pinelog_log_message(int level, const char *file, int line, const char *fmt,
|
|||
time_t t;
|
||||
struct tm tm1;
|
||||
struct tm *tmp;
|
||||
char date_string[30];
|
||||
t = time(NULL);
|
||||
tmp = localtime_r(&t, &tm1);
|
||||
if (tmp != NULL) {
|
||||
#if PINELOG_BUFFER_SZ
|
||||
buf_pos += strftime(output_buffer + buf_pos, sizeof(output_buffer) - buf_pos,
|
||||
"%F %T ", tmp);
|
||||
#else
|
||||
char date_string[30];
|
||||
strftime(date_string, sizeof(date_string), "%F %T ", tmp);
|
||||
fputs(date_string, output_stream);
|
||||
#endif
|
||||
}
|
||||
} while (0);
|
||||
#endif
|
||||
|
@ -208,18 +327,46 @@ void pinelog_log_message(int level, const char *file, int line, const char *fmt,
|
|||
PINELOG_TRACE_STR,
|
||||
};
|
||||
|
||||
#if PINELOG_BUFFER_SZ
|
||||
buf_pos += snprintf(output_buffer + buf_pos, sizeof(output_buffer) - buf_pos,
|
||||
"%s: ", level_strings[level]);
|
||||
#else
|
||||
fputs(level_strings[level], output_stream);
|
||||
fputs(": ", output_stream);
|
||||
#endif
|
||||
} while (0);
|
||||
#endif
|
||||
|
||||
#if PINELOG_SHOW_BACKTRACE
|
||||
#if PINELOG_BUFFER_SZ
|
||||
buf_pos += snprintf(output_buffer + buf_pos, sizeof(output_buffer) - buf_pos,
|
||||
"%s:%d ", file, line);
|
||||
#else
|
||||
fprintf(output_stream, "%s:%d ", file, line);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Set the module name if it is not the root */
|
||||
if (module != PINELOG_MODULE_GLOBAL) {
|
||||
#if PINELOG_BUFFER_SZ
|
||||
buf_pos += snprintf(output_buffer + buf_pos, sizeof(output_buffer) - buf_pos,
|
||||
"%s: ", module_name[module]);
|
||||
#else
|
||||
fprintf(output_stream, "%s: ", module_name[module]);
|
||||
#endif
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
#if PINELOG_BUFFER_SZ
|
||||
buf_pos += vsnprintf(output_buffer + buf_pos, sizeof(output_buffer) - buf_pos,
|
||||
fmt, ap);
|
||||
// Append a trailing newline to flush the log message
|
||||
buf_pos += snprintf(output_buffer + buf_pos, sizeof(output_buffer) - buf_pos, "\n");
|
||||
fputs(output_buffer, output_stream);
|
||||
#else
|
||||
vfprintf(output_stream, fmt, ap);
|
||||
va_end(ap);
|
||||
// Append a trailing newline to flush the log message
|
||||
fputs("\n", output_stream);
|
||||
#endif
|
||||
va_end(ap);
|
||||
}
|
||||
|
|
87
pinelog.h
87
pinelog.h
|
@ -34,6 +34,12 @@ extern "C" {
|
|||
* logged to the logging framework.
|
||||
*/
|
||||
enum {
|
||||
/**
|
||||
* In modules, it will defer to the global level.
|
||||
* Equivalent to \ref PINELOG_LVL_NONE for the global level
|
||||
*/
|
||||
PINELOG_LVL_NOTSET = -2,
|
||||
|
||||
/** No messages will be logged */
|
||||
PINELOG_LVL_NONE = -1,
|
||||
|
||||
|
@ -61,6 +67,25 @@ enum {
|
|||
*/
|
||||
void pinelog_set_defaults(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize pinelog to have these many modules
|
||||
*
|
||||
* @param[in] num_modules Maximum number of modules
|
||||
*
|
||||
* @returns 0 on success, errno on failure.
|
||||
*/
|
||||
int pinelog_init(int num_modules);
|
||||
|
||||
/**
|
||||
* @brief Save the current module name
|
||||
*
|
||||
* @param[in] module Module identifier
|
||||
* @param[in] name Module name - displayed in logs
|
||||
*
|
||||
* @returns 0 on success, errno on failure.
|
||||
*/
|
||||
int pinelog_setup_module(int module, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Close the output stream and terminate the logs
|
||||
*/
|
||||
|
@ -95,7 +120,7 @@ int pinelog_set_output_stream(FILE *stream);
|
|||
int pinelog_set_output_file(const char *file);
|
||||
|
||||
/**
|
||||
* @brief Set the logging level
|
||||
* @brief Set the global logging level
|
||||
*
|
||||
* @param[in] level Level to filter
|
||||
*
|
||||
|
@ -104,12 +129,32 @@ int pinelog_set_output_file(const char *file);
|
|||
int pinelog_set_level(int level);
|
||||
|
||||
/**
|
||||
* @brief Get the logging level
|
||||
* @brief Get the global logging level
|
||||
*
|
||||
* @returns the configured logging level
|
||||
* @returns the configured global logging level
|
||||
*/
|
||||
int pinelog_get_level(void);
|
||||
|
||||
/**
|
||||
* @brief Set the per-module logging level
|
||||
*
|
||||
* @param[in] module Module identifier
|
||||
* @param[in] level Level to filter
|
||||
*
|
||||
* @returns 0 on success, EINVAL if the level or module identifier is not valid
|
||||
*/
|
||||
int pinelog_set_module_level(int module, int level);
|
||||
|
||||
/**
|
||||
* @brief Get the per-module logging level
|
||||
*
|
||||
* @param[in] module Module identifier
|
||||
*
|
||||
* @returns the configured per-module logging level, or the global logging level
|
||||
* if the module identifier is outside the configured range.
|
||||
*/
|
||||
int pinelog_get_module_level(int module);
|
||||
|
||||
/**
|
||||
* @brief Log a message to the logger
|
||||
*
|
||||
|
@ -117,6 +162,7 @@ int pinelog_get_level(void);
|
|||
* never need to call this directly, but instead, should always use the
|
||||
* \code PINELOG_* macros.
|
||||
*
|
||||
* @param[in] module Module identifier
|
||||
* @param[in] level Level to log the message at
|
||||
* @param[in] fmt Format string
|
||||
*
|
||||
|
@ -124,10 +170,10 @@ int pinelog_get_level(void);
|
|||
*/
|
||||
#if defined __has_attribute
|
||||
# if __has_attribute(format)
|
||||
__attribute__((format(printf, 4, 5)))
|
||||
__attribute__((format(printf, 5, 6)))
|
||||
# endif
|
||||
#endif
|
||||
void pinelog_log_message(int level, const char *file, int line, const char *fmt, ...);
|
||||
void pinelog_log_message(int module, int level, const char *file, int line, const char *fmt, ...);
|
||||
|
||||
// Test harness will redefine pinelog_exit
|
||||
#ifndef PINELOG_TEST
|
||||
|
@ -144,42 +190,49 @@ void pinelog_log_message(int level, const char *file, int line, const char *fmt,
|
|||
# define PINELOG_FILE __FILE__
|
||||
#endif
|
||||
|
||||
// Global module - used for generic logging
|
||||
#define PINELOG_MODULE_GLOBAL -1
|
||||
|
||||
#ifndef PINELOG_MODULE
|
||||
#define PINELOG_MODULE PINELOG_MODULE_GLOBAL
|
||||
#endif
|
||||
|
||||
#define PINELOG_FATAL(fmt, ...) do { \
|
||||
if (PINELOG_LVL_FATAL <= pinelog_get_level()) { \
|
||||
pinelog_log_message(PINELOG_LVL_FATAL, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
if (PINELOG_LVL_FATAL <= pinelog_get_module_level(PINELOG_MODULE)) { \
|
||||
pinelog_log_message(PINELOG_MODULE, PINELOG_LVL_FATAL, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
pinelog_exit(1); \
|
||||
} while (0)
|
||||
|
||||
#define PINELOG_ERROR(fmt, ...) do { \
|
||||
if (PINELOG_LVL_ERROR <= pinelog_get_level()) { \
|
||||
pinelog_log_message(PINELOG_LVL_ERROR, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
if (PINELOG_LVL_ERROR <= pinelog_get_module_level(PINELOG_MODULE)) { \
|
||||
pinelog_log_message(PINELOG_MODULE, PINELOG_LVL_ERROR, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PINELOG_WARN(fmt, ...) do { \
|
||||
if (PINELOG_LVL_WARNING <= pinelog_get_level()) { \
|
||||
pinelog_log_message(PINELOG_LVL_WARNING, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
if (PINELOG_LVL_WARNING <= pinelog_get_module_level(PINELOG_MODULE)) { \
|
||||
pinelog_log_message(PINELOG_MODULE, PINELOG_LVL_WARNING, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define PINELOG_INFO(fmt, ...) do { \
|
||||
if (PINELOG_LVL_INFO <= pinelog_get_level()) { \
|
||||
pinelog_log_message(PINELOG_LVL_INFO, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
if (PINELOG_LVL_INFO <= pinelog_get_module_level(PINELOG_MODULE)) { \
|
||||
pinelog_log_message(PINELOG_MODULE, PINELOG_LVL_INFO, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define PINELOG_DEBUG(fmt, ...) do { \
|
||||
if (PINELOG_LVL_DEBUG <= pinelog_get_level()) { \
|
||||
pinelog_log_message(PINELOG_LVL_DEBUG, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
if (PINELOG_LVL_DEBUG <= pinelog_get_module_level(PINELOG_MODULE)) { \
|
||||
pinelog_log_message(PINELOG_MODULE, PINELOG_LVL_DEBUG, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* PINELOG_DISABLE_TRACE allows all traces to be compiled out */
|
||||
#ifndef PINELOG_DISABLE_TRACE
|
||||
#define PINELOG_TRACE(fmt, ...) do { \
|
||||
if (PINELOG_LVL_TRACE <= pinelog_get_level()) { \
|
||||
pinelog_log_message(PINELOG_LVL_TRACE, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
if (PINELOG_LVL_TRACE <= pinelog_get_module_level(PINELOG_MODULE)) { \
|
||||
pinelog_log_message(PINELOG_MODULE, PINELOG_LVL_TRACE, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
|
|
|
@ -64,7 +64,7 @@ static void dump_data(const char *type, size_t len, char *data)
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
static int test_setup(int level, int filter, const char *file, int line)
|
||||
static int test_setup(int module, int level, int filter, const char *file, int line)
|
||||
{
|
||||
expected_len = 0;
|
||||
memset(expected_output, 0, sizeof(expected_output));
|
||||
|
@ -114,6 +114,12 @@ static int test_setup(int level, int filter, const char *file, int line)
|
|||
"%s:%d ", basename, line);
|
||||
}
|
||||
|
||||
if (module >= 0) {
|
||||
static const char * modules[] = {"foo", "bar"};
|
||||
expected_len += snprintf(&expected_output[expected_len],
|
||||
sizeof(expected_output) - expected_len,
|
||||
"%s: ", modules[module]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -148,24 +154,29 @@ static void verify_defaults(void)
|
|||
|
||||
#define PINELOG_WARNING PINELOG_WARN
|
||||
|
||||
#define TEST_LOG(lvl, filter, fmt, ...) do { \
|
||||
if (test_setup(PINELOG_LVL_ ## lvl, PINELOG_LVL_ ## filter, \
|
||||
#define TEST_LOG(module, lvl, filter, fmt, ...) do { \
|
||||
if (test_setup(module, PINELOG_LVL_ ## lvl, PINELOG_LVL_ ## filter, \
|
||||
__FILE__, __LINE__)) \
|
||||
expected_len += snprintf(&expected_output[expected_len], \
|
||||
sizeof(expected_output) - expected_len, \
|
||||
fmt "\n", ##__VA_ARGS__); \
|
||||
PINELOG_ ## lvl (fmt, ##__VA_ARGS__); \
|
||||
test_teardown("Log " #lvl " filter " #filter); \
|
||||
switch (module) { \
|
||||
case -1: test_teardown("Global Log " #lvl " filter " #filter); break; \
|
||||
case 0: test_teardown("Module foo Log " #lvl " filter " #filter); break; \
|
||||
case 1: test_teardown("Module bar Log " #lvl " filter " #filter); break; \
|
||||
default: test_teardown("Module ??? Log " #lvl " filter " #filter); break; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define TEST(filter, fmt, ...) do { \
|
||||
#define TEST(module, filter, fmt, ...) do { \
|
||||
pinelog_set_level(PINELOG_LVL_ ## filter); \
|
||||
TEST_LOG(TRACE, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(DEBUG, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(INFO, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(WARNING, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(ERROR, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(FATAL, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(module, TRACE, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(module, DEBUG, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(module, INFO, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(module, WARNING, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(module, ERROR, filter, fmt, ##__VA_ARGS__); \
|
||||
TEST_LOG(module, FATAL, filter, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#if defined __has_attribute
|
||||
|
@ -210,14 +221,24 @@ int main(int argc, char **argv)
|
|||
|
||||
verify_defaults();
|
||||
|
||||
pinelog_init(2);
|
||||
pinelog_setup_module(0, "foo");
|
||||
pinelog_setup_module(1, "bar");
|
||||
|
||||
pinelog_set_output_stream(observed_stream_w);
|
||||
TEST(TRACE, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(DEBUG, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(INFO, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(WARNING, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(ERROR, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(FATAL, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(NONE, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
for (int i = -1; i < 2; i++) {
|
||||
#ifdef PINELOG_MODULE
|
||||
#undef PINELOG_MODULE
|
||||
#define PINELOG_MODULE i
|
||||
#endif
|
||||
TEST(i, TRACE, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(i, DEBUG, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(i, INFO, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(i, WARNING, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(i, ERROR, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(i, FATAL, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
TEST(i, NONE, "testing %s... %d, %f, %u", "testing", -1, 0.0, 1);
|
||||
}
|
||||
|
||||
printf("1..%u\n", test_id);
|
||||
|
||||
|
|
Loading…
Reference in New Issue