The logging API provides four main parts (basics, filtering, threading & blackbox). The idea behind this logging system is not to be prescriptive but to provide a set of tools to help the developer achieve what they want quickly and easily.
Simplest possible use:
main() { qb_log_init("simple-log", LOG_DAEMON, LOG_INFO); // ... qb_log(LOG_WARNING, "watch out"); // ... qb_log_fini(); }
To enable a target do the following:
syslog, stderr, the blackbox, and stdout are static (they don't need to be created, just enabled or disabled). However you can open multiple logfiles (QB_LOG_TARGET_MAX - QB_LOG_TARGET_STATIC_MAX). To do this, use the following code:mytarget = qb_log_file_open("/var/log/mylogfile"); qb_log_ctl(mytarget, QB_LOG_CONF_ENABLED, QB_TRUE);
qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 1024*10);
qb_log_ctl(mytarget, QB_LOG_CONF_THREADED, QB_TRUE);
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP, LOG_INFO - LOG_DEBUG);
qb_log_ctl(mytarget, QB_LOG_CONF_FILE_SYNC, QB_TRUE);
So to make all logs from evil_function() go to stderr, do the following:
qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FUNCTION, "evil_function", LOG_TRACE);
qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE, "totem", LOG_INFO);
qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FORMAT, "ringbuffer", LOG_TRACE);
To achieve non-blocking logging, so that any calls to write() or syslog() will not hold up your program, you can use threaded logging as well.Threaded logging use:
main() { qb_log_init("simple-log", LOG_DAEMON, LOG_INFO); qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, QB_TRUE); // ... daemonize(); // call this after you fork() qb_log_thread_start(); // ... qb_log(LOG_WARNING, "watch out"); // ... qb_log_fini(); }
Blackbox usage:
static void sigsegv_handler(int sig) { (void)signal (SIGSEGV, SIG_DFL); qb_log_blackbox_write_to_file("simple-log.fdata"); qb_log_fini(); raise(SIGSEGV); } main() { signal(SIGSEGV, sigsegv_handler); qb_log_init("simple-log", LOG_DAEMON, LOG_INFO); qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE, "*", LOG_DEBUG); qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 1024*10); qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE); // ... qb_log(LOG_WARNING, "watch out"); // ... qb_log_fini(); }
const char* my_tags_stringify(uint32_t tags) { if (qb_bit_is_set(tags, QB_LOG_TAG_LIBQB_MSG_BIT) { return "libqb"; } else if (tags == 3) { return "three"; } else { return "MAIN"; } } main() { // ... qb_log_tags_stringify_fn_set(my_tags_stringify); qb_log_format_set(QB_LOG_STDERR, "[%5g] %p %b"); // ... qb_logt(LOG_INFO, 3, "hello"); qb_logt(LOG_INFO, 0, "hello"); }
The code above will produce:
[libqb] some message [three] info hello [MAIN ] info hello