Provided by: libqb-dev_2.0.8-1ubuntu2_amd64 bug

NAME

       qblog.h - The logging API provides four main parts (basics, filtering, threading & blackbox).

SYNOPSIS

       #include <qb/qblog.h>

DESCRIPTION

       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.

       Basic logging API.

       Call qb_log() to generate a log message. Then to write the message somewhere meaningful call qb_log_ctl()
       to configure the targets.

       Simplest possible use:

       main() {
            qb_log_init("simple-log", LOG_DAEMON, LOG_INFO);
               // ...
            qb_log(LOG_WARNING, "watch out");
               // ...
            qb_log_fini();
       }

       Configuring log targets.

       A log target can be syslog, stderr, the blackbox, stdout, or a text file.  By  default,  only  syslog  is
       enabled.  While  this  is usual for daemons, it is rarely appropriate for ordinary programs, which should
       disable it when other targets (see below) are to be used:

       qb_log_ctl(B_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);

       To enable a target do the following:

       qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);

       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   (falling   within   inclusive   range
       QB_LOG_TARGET_DYNAMIC_START up to QB_LOG_TARGET_DYNAMIC_END). 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);

       Once your targets are enabled/opened, you can configure them as follows: Configure the size of blackbox:

       qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 1024*10);

       Make logging to file threaded:

       qb_log_ctl(mytarget, QB_LOG_CONF_THREADED, QB_TRUE);

       Sometimes, syslog daemons are (pre)configured to filter messages not  exceeding  a  particular  priority.
       When  this  happens  to  be  the  logging  target, the designated priority of the message is passed along
       unchanged, possibly resulting in message loss. For messages up  to  LOG_DEBUG  importance,  this  can  be
       worked  around  by  proportionally  bumping the priorities to be passed to syslog (here, the step is such
       that LOG_DEBUG gets promoted to LOG_INFO):

       qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP,
                  LOG_INFO - LOG_DEBUG);

       To ensure all logs to file targets are fsync'ed (new messages expressly transferred to the storage device
       as they keep coming, otherwise defaults to QB_FALSE):

       qb_log_ctl(mytarget, QB_LOG_CONF_FILE_SYNC, QB_TRUE);

       Filtering messages.

       To have more power over what log messages go to which target you can apply filters to the  targets.  What
       happens is the desired callsites have the correct bit set. Then when the log message is generated it gets
       sent to the targets based on which bit is set in the callsite's "target" bitmap. Messages can be filtered
       based on the:

       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);

       So to make all logs from totem* (with a priority <= LOG_INFO) go to stderr, do the following:

       qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
                    QB_LOG_FILTER_FILE, "totem", LOG_INFO);

       So to make all logs with the substring "ringbuffer" go to stderr, do the following:

       qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
                    QB_LOG_FILTER_FORMAT, "ringbuffer", LOG_TRACE);

       Thread safe non-blocking logging.

       Logging  is  only  thread  safe  when  threaded  logging  is in use. If you plan on logging from multiple
       threads,  you  must  initialize  libqb's  logger  thread   and   use   qb_log_filter_ctl   to   set   the
       QB_LOG_CONF_THREADED flag on all the logging targets in use.

       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();
       }

       A blackbox for in-field diagnosis.

       This stores log messages in a ringbuffer so they can be written to file if the program crashes (you  will
       need to catch SIGSEGV). These can then be easily printed out later.

       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();
       }

       Tagging messages.

       You  can tag messages using the second argument to qb_logt() or by using qb_log_filter_ctl(). This can be
       used to add feature or sub-system information to the logs.

       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

NOTE

       the blackbox is not enabled by default.

SEE ALSO

       qb_log_filter_fn_set(3), qb_log_from_external_source_va2(3), qb_log_thread_start(3),
       qb_log_target_user_data_get(3), qb_log_tags_stringify_fn_set(3), qb_log_file_reopen(3), qb_log_fini(3),
       qb_log_callsites_dump(3), qb_log_ctl2(3), qb_log_target_user_data_set(3), qb_log_target_format(3),
       qb_log_thread_priority_set(3), qb_log_facility2int(3), qb_log_callsites_register(3),
       qb_log_filter_ctl2(3), qb_log_file_close(3), qb_log_format_set(3), qb_log_real_(3),
       qb_log_from_external_source_va(3), qb_log_callsite_get(3), qb_log_blackbox_write_to_file(3),
       qb_log_real_va_(3), qb_log_from_external_source(3), qb_log_blackbox_print_from_file(3),
       qb_log_facility2str(3), qb_log_callsite_get2(3), qb_log_ctl(3), qb_log_filter_ctl(3),
       qb_log_custom_close(3), qb_log_init(3), qb_log_file_open(3), qb_log_custom_open(3)

COPYRIGHT

       Copyright (c) 2017 Red Hat, Inc.

LIBQB                                              2023-07-21                                         QBLOG.H(3)