The logging API provides four main parts (basics, filtering, threading & blackbox). More...
#include <stdint.h>#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <errno.h>#include <syslog.h>#include <string.h>#include <qb/qbutil.h>#include <qb/qbconfig.h>
Data Structures | |
| struct | qb_log_callsite |
| An instance of this structure is created in a special ELF section at every dynamic debug callsite. More... | |
| union | qb_log_ctl2_arg_t |
Defines | |
| #define | LOG_TRACE (LOG_DEBUG + 1) |
| #define | QB_LOG_MAX_LEN 512 |
| #define | QB_LOG_STRERROR_MAX_LEN 128 |
| #define | QB_LOG_INIT_DATA(name) |
| #define | QB_LOG_TAG_LIBQB_MSG_BIT 31 |
| #define | QB_LOG_TAG_LIBQB_MSG (1 << QB_LOG_TAG_LIBQB_MSG_BIT) |
| #define | qb_logt(priority, tags, fmt, args...) |
| This is the function to generate a log message if you want to manually add tags. | |
| #define | qb_log(priority, fmt, args...) qb_logt(priority, 0, fmt, ##args) |
| This is the main function to generate a log message. | |
| #define | QB_XC '\a' |
| #define | QB_XS "\a" |
| #define | qb_perror(priority, fmt, args...) |
| This is similar to perror except it goes into the logging system. | |
| #define | qb_enter() qb_log(LOG_TRACE, "ENTERING %s()", __func__) |
| #define | qb_leave() qb_log(LOG_TRACE, "LEAVING %s()", __func__) |
| #define | QB_LOG_CTL2_I32(a) ((qb_log_ctl2_arg_t) { .i32 = (a) }) |
| #define | QB_LOG_CTL2_S(a) ((qb_log_ctl2_arg_t) { .s = (a) }) |
Typedefs | |
| typedef const char *(* | qb_log_tags_stringify_fn )(uint32_t tags) |
| typedef void(* | qb_log_filter_fn )(struct qb_log_callsite *cs) |
| typedef void(* | qb_log_logger_fn )(int32_t t, struct qb_log_callsite *cs, time_t timestamp, const char *msg) |
| typedef void(* | qb_log_vlogger_fn )(int32_t t, struct qb_log_callsite *cs, time_t timestamp, va_list ap) |
| typedef void(* | qb_log_close_fn )(int32_t t) |
| typedef void(* | qb_log_reload_fn )(int32_t t) |
Enumerations | |
| enum | qb_log_target_slot { QB_LOG_TARGET_START, QB_LOG_TARGET_STATIC_START = QB_LOG_TARGET_START, QB_LOG_SYSLOG = QB_LOG_TARGET_STATIC_START, QB_LOG_STDERR, QB_LOG_BLACKBOX, QB_LOG_STDOUT, QB_LOG_TARGET_STATIC_MAX, QB_LOG_TARGET_STATIC_END = QB_LOG_TARGET_STATIC_MAX - 1, QB_LOG_TARGET_DYNAMIC_START = QB_LOG_TARGET_STATIC_MAX, QB_LOG_TARGET_MAX = 32, QB_LOG_TARGET_DYNAMIC_END = QB_LOG_TARGET_MAX - 1, QB_LOG_TARGET_END = QB_LOG_TARGET_DYNAMIC_END } |
| enum | qb_log_target_state { QB_LOG_STATE_UNUSED = 1, QB_LOG_STATE_DISABLED = 2, QB_LOG_STATE_ENABLED = 3 } |
| enum | qb_log_conf { QB_LOG_CONF_ENABLED, QB_LOG_CONF_FACILITY, QB_LOG_CONF_DEBUG, QB_LOG_CONF_SIZE, QB_LOG_CONF_THREADED, QB_LOG_CONF_PRIORITY_BUMP, QB_LOG_CONF_STATE_GET, QB_LOG_CONF_FILE_SYNC, QB_LOG_CONF_EXTENDED, QB_LOG_CONF_IDENT } |
| enum | qb_log_filter_type { QB_LOG_FILTER_FILE, QB_LOG_FILTER_FUNCTION, QB_LOG_FILTER_FORMAT, QB_LOG_FILTER_FILE_REGEX, QB_LOG_FILTER_FUNCTION_REGEX, QB_LOG_FILTER_FORMAT_REGEX } |
| enum | qb_log_filter_conf { QB_LOG_FILTER_ADD, QB_LOG_FILTER_REMOVE, QB_LOG_FILTER_CLEAR_ALL, QB_LOG_TAG_SET, QB_LOG_TAG_CLEAR, QB_LOG_TAG_CLEAR_ALL } |
Functions | |
| void | qb_log_real_ (struct qb_log_callsite *cs,...) |
| Internal function: use qb_log() or qb_logt(). | |
| void | qb_log_real_va_ (struct qb_log_callsite *cs, va_list ap) |
| void | qb_log_from_external_source (const char *function, const char *filename, const char *format, uint8_t priority, uint32_t lineno, uint32_t tags,...) __attribute__((format(printf |
| This function is to import logs from other code (like libraries) that provide a callback with their logs. | |
| void struct qb_log_callsite * | qb_log_callsite_get (const char *function, const char *filename, const char *format, uint8_t priority, uint32_t lineno, uint32_t tags) |
| Get or create a callsite at the given position. | |
| void | qb_log_from_external_source_va (const char *function, const char *filename, const char *format, uint8_t priority, uint32_t lineno, uint32_t tags, va_list ap) __attribute__((format(printf |
| void | qb_log_init (const char *name, int32_t facility, uint8_t priority) |
| Init the logging system. | |
| void | qb_log_fini (void) |
| Logging system finalization function. | |
| int32_t | qb_log_callsites_register (struct qb_log_callsite *_start, struct qb_log_callsite *_stop) |
| If you are using dynamically loadable modules via dlopen() and you load them after qb_log_init() then after you load the module you will need to do the following to get the filters to work in that module:. | |
| void | qb_log_callsites_dump (void) |
| Dump the callsite info to stdout. | |
| int32_t | qb_log_ctl (int32_t target, enum qb_log_conf conf_type, int32_t arg) |
| Main logging control function. | |
| int32_t | qb_log_ctl2 (int32_t target, enum qb_log_conf conf_type, qb_log_ctl2_arg_t arg) |
| Extension of main logging control function accepting also strings. | |
| int32_t | qb_log_filter_ctl (int32_t value, enum qb_log_filter_conf c, enum qb_log_filter_type type, const char *text, uint8_t low_priority) |
| This allows you modify the 'tags' and 'targets' callsite fields at runtime. | |
| int32_t | qb_log_filter_ctl2 (int32_t value, enum qb_log_filter_conf c, enum qb_log_filter_type type, const char *text, uint8_t high_priority, uint8_t low_priority) |
| This extends qb_log_filter_ctl() by been able to provide a high_priority. | |
| int32_t | qb_log_filter_fn_set (qb_log_filter_fn fn) |
| Instead of using the qb_log_filter_ctl() functions you can apply the filters manually by defining a callback and setting the targets field using qb_bit_set() and qb_bit_clear() like the following below:. | |
| void | qb_log_tags_stringify_fn_set (qb_log_tags_stringify_fn fn) |
| Set the callback to map the 'tags' bit map to a string. | |
| void | qb_log_format_set (int32_t t, const char *format) |
| Set the format specifiers. | |
| int32_t | qb_log_file_open (const char *filename) |
| Open a log file. | |
| void | qb_log_file_close (int32_t t) |
| Close a log file and release is resources. | |
| int32_t | qb_log_thread_priority_set (int32_t policy, int32_t priority) |
| When using threaded logging set the pthread policy and priority. | |
| int32_t | qb_log_thread_start (void) |
| Start the logging pthread. | |
| ssize_t | qb_log_blackbox_write_to_file (const char *filename) |
| Write the blackbox to file. | |
| void | qb_log_blackbox_print_from_file (const char *filename) |
| Read the blackbox for file and print it out. | |
| int32_t | qb_log_custom_open (qb_log_logger_fn log_fn, qb_log_close_fn close_fn, qb_log_reload_fn reload_fn, void *user_data) |
| Open a custom log target. | |
| void | qb_log_custom_close (int32_t t) |
| Close a custom log target and release is resources. | |
| void * | qb_log_target_user_data_get (int32_t t) |
| Retrieve the user data set by either qb_log_custom_open or qb_log_target_user_data_set. | |
| int32_t | qb_log_target_user_data_set (int32_t t, void *user_data) |
| Associate user data with this log target. | |
| void | qb_log_target_format (int32_t target, struct qb_log_callsite *cs, time_t timestamp, const char *formatted_message, char *output_buffer) |
| format the callsite and timestamp info according to the format set using qb_log_format_set() It is intended to be used from your custom logger function. | |
| int32_t | qb_log_facility2int (const char *fname) |
| Convert string "auth" to equivalent number "LOG_AUTH" etc. | |
| const char * | qb_log_facility2str (int32_t fnum) |
| Convert number "LOG_AUTH" to equivalent string "auth" etc. | |
Variables | |
| struct qb_log_callsite | aligned |
| An instance of this structure is created in a special ELF section at every dynamic debug callsite. | |
| struct qb_log_callsite | __start___verbose [] |
| struct qb_log_callsite | __stop___verbose [] |
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);
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);
To workaround your syslog daemon filtering all messages > 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 (default QB_FALSE)
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);
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);
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
| #define LOG_TRACE (LOG_DEBUG + 1) |
| #define qb_enter | ( | ) | qb_log(LOG_TRACE, "ENTERING %s()", __func__) |
| #define qb_leave | ( | ) | qb_log(LOG_TRACE, "LEAVING %s()", __func__) |
| #define qb_log | ( | priority, | |||
| fmt, | |||||
| args... | ) | qb_logt(priority, 0, fmt, ##args) |
This is the main function to generate a log message.
| priority | this takes syslog priorities. | |
| fmt | usual printf style format specifiers | |
| args | usual printf style args |
| #define QB_LOG_CTL2_I32 | ( | a | ) | ((qb_log_ctl2_arg_t) { .i32 = (a) }) |
| #define QB_LOG_CTL2_S | ( | a | ) | ((qb_log_ctl2_arg_t) { .s = (a) }) |
| #define QB_LOG_INIT_DATA | ( | name | ) |
void name(void); \ void name(void) { if (__start___verbose != __stop___verbose) {assert(1);} } \ void __attribute__ ((constructor)) name(void);
| #define QB_LOG_MAX_LEN 512 |
| #define QB_LOG_STRERROR_MAX_LEN 128 |
| #define QB_LOG_TAG_LIBQB_MSG (1 << QB_LOG_TAG_LIBQB_MSG_BIT) |
| #define QB_LOG_TAG_LIBQB_MSG_BIT 31 |
| #define qb_logt | ( | priority, | |||
| tags, | |||||
| fmt, | |||||
| args... | ) |
do { \ static struct qb_log_callsite descriptor \ __attribute__((section("__verbose"), aligned(8))) = \ { __func__, __FILE__, fmt, priority, __LINE__, 0, tags }; \ qb_log_real_(&descriptor, ##args); \ } while(0)
This is the function to generate a log message if you want to manually add tags.
| priority | this takes syslog priorities. | |
| tags | this is a uint32_t that you can use with qb_log_tags_stringify_fn_set() to "tag" a log message with a feature or sub-system then you can use "%g" in the format specifer to print it out. | |
| fmt | usual printf style format specifiers | |
| args | usual printf style args |
| #define qb_perror | ( | priority, | |||
| fmt, | |||||
| args... | ) |
do { \ char _perr_buf_[QB_LOG_STRERROR_MAX_LEN]; \ const char *_perr_str_ = qb_strerror_r(errno, _perr_buf_, sizeof(_perr_buf_)); \ qb_logt(priority, 0, fmt ": %s (%d)", ##args, _perr_str_, errno); \ } while(0)
This is similar to perror except it goes into the logging system.
| priority | this takes syslog priorities. | |
| fmt | usual printf style format specifiers | |
| args | usual printf style args |
| #define QB_XC '\a' |
| #define QB_XS "\a" |
| typedef void(* qb_log_close_fn)(int32_t t) |
| typedef void(* qb_log_filter_fn)(struct qb_log_callsite *cs) |
| typedef void(* qb_log_logger_fn)(int32_t t, struct qb_log_callsite *cs, time_t timestamp, const char *msg) |
| typedef void(* qb_log_reload_fn)(int32_t t) |
| typedef const char*(* qb_log_tags_stringify_fn)(uint32_t tags) |
| typedef void(* qb_log_vlogger_fn)(int32_t t, struct qb_log_callsite *cs, time_t timestamp, va_list ap) |
| enum qb_log_conf |
| enum qb_log_filter_conf |
| enum qb_log_filter_type |
| enum qb_log_target_slot |
| enum qb_log_target_state |
| void qb_log_blackbox_print_from_file | ( | const char * | filename | ) |
Read the blackbox for file and print it out.
| ssize_t qb_log_blackbox_write_to_file | ( | const char * | filename | ) |
Write the blackbox to file.
| void struct qb_log_callsite* qb_log_callsite_get | ( | const char * | function, | |
| const char * | filename, | |||
| const char * | format, | |||
| uint8_t | priority, | |||
| uint32_t | lineno, | |||
| uint32_t | tags | |||
| ) | [read] |
Get or create a callsite at the given position.
The result can then be passed into qb_log_real_()
| function | originating function name | |
| filename | originating filename | |
| format | format string | |
| priority | this takes syslog priorities. | |
| lineno | file line number | |
| tags | the tag |
| void qb_log_callsites_dump | ( | void | ) |
Dump the callsite info to stdout.
| int32_t qb_log_callsites_register | ( | struct qb_log_callsite * | _start, | |
| struct qb_log_callsite * | _stop | |||
| ) |
If you are using dynamically loadable modules via dlopen() and you load them after qb_log_init() then after you load the module you will need to do the following to get the filters to work in that module:.
_start = dlsym (dl_handle, "__start___verbose"); _stop = dlsym (dl_handle, "__stop___verbose"); qb_log_callsites_register(_start, _stop);
| int32_t qb_log_ctl | ( | int32_t | target, | |
| enum qb_log_conf | conf_type, | |||
| int32_t | arg | |||
| ) |
Main logging control function.
| target | QB_LOG_SYSLOG, QB_LOG_STDERR or result from qb_log_file_open() | |
| conf_type | configuration directive ("what to configure") that accepts int32_t argument determining the new value unless ignored for particular directive altogether (incompatible directives: QB_LOG_CONF_IDENT) | |
| arg | the new value for a state-changing configuration directive, ignored otherwise |
| -errno | on error | |
| 0 | on success | |
| qb_log_target_state | for QB_LOG_CONF_STATE_GET |
| int32_t qb_log_ctl2 | ( | int32_t | target, | |
| enum qb_log_conf | conf_type, | |||
| qb_log_ctl2_arg_t | arg | |||
| ) |
Extension of main logging control function accepting also strings.
| target | QB_LOG_SYSLOG, QB_LOG_STDERR or result from qb_log_file_open() | |
| conf_type | configuration directive ("what to configure") that accepts either int32_t or a null-terminated string argument determining the new value unless ignored for particular directive (compatible directives: those valid for qb_log_ctl + QB_LOG_CONF_IDENT) | |
| arg | the new value for a state-changing configuration directive, ignored otherwise; for QB_LOG_CONF_IDENT, 's' member as new identifier to openlog(), for all qb_log_ctl-compatible ones, 'i32' member is assumed (although a preferred way is to use that original function directly as it allows for more type safety) |
QB_LOG_CTL2_I32 and QB_LOG_CTL2_S macros for a convenient on-the-fly construction of the object to be passed as an arg argument. | void qb_log_custom_close | ( | int32_t | t | ) |
Close a custom log target and release is resources.
| int32_t qb_log_custom_open | ( | qb_log_logger_fn | log_fn, | |
| qb_log_close_fn | close_fn, | |||
| qb_log_reload_fn | reload_fn, | |||
| void * | user_data | |||
| ) |
Open a custom log target.
| -errno | on error | |
| value | in inclusive range QB_LOG_TARGET_DYNAMIC_START to QB_LOG_TARGET_DYNAMIC_END (to be passed into other qb_log_* functions) |
| int32_t qb_log_facility2int | ( | const char * | fname | ) |
Convert string "auth" to equivalent number "LOG_AUTH" etc.
| const char* qb_log_facility2str | ( | int32_t | fnum | ) |
Convert number "LOG_AUTH" to equivalent string "auth" etc.
| void qb_log_file_close | ( | int32_t | t | ) |
Close a log file and release is resources.
| int32_t qb_log_file_open | ( | const char * | filename | ) |
Open a log file.
| -errno | on error | |
| value | in inclusive range QB_LOG_TARGET_DYNAMIC_START to QB_LOG_TARGET_DYNAMIC_END (to be passed into other qb_log_* functions) |
| int32_t qb_log_filter_ctl | ( | int32_t | value, | |
| enum qb_log_filter_conf | c, | |||
| enum qb_log_filter_type | type, | |||
| const char * | text, | |||
| uint8_t | low_priority | |||
| ) |
This allows you modify the 'tags' and 'targets' callsite fields at runtime.
| int32_t qb_log_filter_ctl2 | ( | int32_t | value, | |
| enum qb_log_filter_conf | c, | |||
| enum qb_log_filter_type | type, | |||
| const char * | text, | |||
| uint8_t | high_priority, | |||
| uint8_t | low_priority | |||
| ) |
This extends qb_log_filter_ctl() by been able to provide a high_priority.
| int32_t qb_log_filter_fn_set | ( | qb_log_filter_fn | fn | ) |
Instead of using the qb_log_filter_ctl() functions you can apply the filters manually by defining a callback and setting the targets field using qb_bit_set() and qb_bit_clear() like the following below:.
static void m_filter(struct qb_log_callsite *cs) { if ((cs->priority >= LOG_ALERT && cs->priority <= LOG_DEBUG) && strcmp(cs->filename, "my_c_file.c") == 0) { qb_bit_set(cs->targets, QB_LOG_SYSLOG); } else { qb_bit_clear(cs->targets, QB_LOG_SYSLOG); } }
| void qb_log_fini | ( | void | ) |
Logging system finalization function.
It releases any shared memory. Stops the logging thread if running. Flushes the last messages to their destinations.
| void qb_log_format_set | ( | int32_t | t, | |
| const char * | format | |||
| ) |
Set the format specifiers.
n FUNCTION NAME f FILENAME l FILELINE p PRIORITY t TIMESTAMP b BUFFER g TAGS N name (passed into qb_log_init) P PID H hostname
any number between % and character specify field length to pad or chop
| void qb_log_from_external_source | ( | const char * | function, | |
| const char * | filename, | |||
| const char * | format, | |||
| uint8_t | priority, | |||
| uint32_t | lineno, | |||
| uint32_t | tags, | |||
| ... | ||||
| ) |
This function is to import logs from other code (like libraries) that provide a callback with their logs.
| function | originating function name | |
| filename | originating filename | |
| format | format string | |
| priority | this takes syslog priorities. | |
| lineno | file line number | |
| tags | this is a uint32_t that you can use with qb_log_tags_stringify_fn_set() to "tag" a log message with a feature or sub-system then you can use "%g" in the format specifer to print it out. |
| void qb_log_from_external_source_va | ( | const char * | function, | |
| const char * | filename, | |||
| const char * | format, | |||
| uint8_t | priority, | |||
| uint32_t | lineno, | |||
| uint32_t | tags, | |||
| va_list | ap | |||
| ) |
| void qb_log_init | ( | const char * | name, | |
| int32_t | facility, | |||
| uint8_t | priority | |||
| ) |
Init the logging system.
| name | will be passed into openlog() | |
| facility | default for all new targets. | |
| priority | a basic filter with this priority will be added. |
| void qb_log_real_ | ( | struct qb_log_callsite * | cs, | |
| ... | ||||
| ) |
| void qb_log_real_va_ | ( | struct qb_log_callsite * | cs, | |
| va_list | ap | |||
| ) |
| void qb_log_tags_stringify_fn_set | ( | qb_log_tags_stringify_fn | fn | ) |
Set the callback to map the 'tags' bit map to a string.
| void qb_log_target_format | ( | int32_t | target, | |
| struct qb_log_callsite * | cs, | |||
| time_t | timestamp, | |||
| const char * | formatted_message, | |||
| char * | output_buffer | |||
| ) |
format the callsite and timestamp info according to the format set using qb_log_format_set() It is intended to be used from your custom logger function.
| void* qb_log_target_user_data_get | ( | int32_t | t | ) |
Retrieve the user data set by either qb_log_custom_open or qb_log_target_user_data_set.
| int32_t qb_log_target_user_data_set | ( | int32_t | t, | |
| void * | user_data | |||
| ) |
Associate user data with this log target.
| int32_t qb_log_thread_priority_set | ( | int32_t | policy, | |
| int32_t | priority | |||
| ) |
When using threaded logging set the pthread policy and priority.
| -errno | on error | |
| 0 | success |
| int32_t qb_log_thread_start | ( | void | ) |
Start the logging pthread.
| struct qb_log_callsite __start___verbose[] |
| struct qb_log_callsite __stop___verbose[] |
| struct qb_log_callsite aligned |
An instance of this structure is created in a special ELF section at every dynamic debug callsite.
At runtime, the special section is treated as an array of these.
1.6.1