X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Flogging%2Flog.h;h=93c9d6ed1376e6726099a4c627b60d89f8703197;hb=71436ae48cd2fcfcc59ae9a7da909e29a191145c;hp=89ac5fc7c54ca3e8fffb858fc1a816fec5762add;hpb=78c888d139a40b58b10a2c92829cbb2c814ad766;p=babeltrace.git diff --git a/src/logging/log.h b/src/logging/log.h index 89ac5fc7..93c9d6ed 100644 --- a/src/logging/log.h +++ b/src/logging/log.h @@ -2,1125 +2,388 @@ * SPDX-License-Identifier: MIT * * Copyright (c) 2016 wonder-mice + * Copyright (c) 2016-2023 Philippe Proulx * - * This is zf_log.h, modified with Babeltrace prefixes. - * See . + * This is very inspired by zf_log.h (see + * ), but modified (mostly + * stripped down) for the use cases of Babeltrace. */ -#pragma once - -#ifndef BABELTRACE_LOGGING_INTERNAL_H -#define BABELTRACE_LOGGING_INTERNAL_H +#ifndef BABELTRACE_LOGGING_LOG_H +#define BABELTRACE_LOGGING_LOG_H #include #include #include #include +#include #include -/* Access private __BT_LOGGING_LEVEL_* macros. */ -#define __BT_IN_BABELTRACE_H -#include -#undef __BT_IN_BABELTRACE_H - -#include "common/macros.h" -#include "common/assert.h" - -/* To detect incompatible changes you can define BT_LOG_VERSION_REQUIRED to be - * the current value of BT_LOG_VERSION before including this file (or via - * compiler command line): - * - * #define BT_LOG_VERSION_REQUIRED 4 - * #include "logging.h" - * - * Compilation will fail when included file has different version. - */ -#define BT_LOG_VERSION 4 -#if defined(BT_LOG_VERSION_REQUIRED) - #if BT_LOG_VERSION_REQUIRED != BT_LOG_VERSION - #error different bt_log version required - #endif -#endif - -/* Log level guideline: - * - BT_LOG_FATAL - happened something impossible and absolutely unexpected. - * Process can't continue and must be terminated. - * Example: division by zero, unexpected modifications from other thread. - * - BT_LOG_ERROR - happened something possible, but highly unexpected. The - * process is able to recover and continue execution. - * Example: out of memory (could also be FATAL if not handled properly). - * - BT_LOG_WARNING - happened something that *usually* should not happen and - * significantly changes application behavior for some period of time. - * Example: configuration file not found, auth error. - * - BT_LOG_INFO - happened significant life cycle event or major state - * transition. - * Example: app started, user logged in. - * - BT_LOG_DEBUG - minimal set of events that could help to reconstruct the - * execution path. Usually disabled in release builds. - * - BT_LOG_TRACE - all other events. Usually disabled in release builds. - * - * *Ideally*, log file of debugged, well tested, production ready application - * should be empty or very small. Choosing a right log level is as important as - * providing short and self descriptive log message. - */ -#define BT_LOG_TRACE __BT_LOGGING_LEVEL_TRACE -#define BT_LOG_DEBUG __BT_LOGGING_LEVEL_DEBUG -#define BT_LOG_INFO __BT_LOGGING_LEVEL_INFO -#define BT_LOG_WARNING __BT_LOGGING_LEVEL_WARNING -#define BT_LOG_ERROR __BT_LOGGING_LEVEL_ERROR -#define BT_LOG_FATAL __BT_LOGGING_LEVEL_FATAL -#define BT_LOG_NONE __BT_LOGGING_LEVEL_NONE - -/* "Current" log level is a compile time check and has no runtime overhead. Log - * level that is below current log level it said to be "disabled". - * Otherwise, it's "enabled". Log messages that are disabled has no - * runtime overhead - they are converted to no-op by preprocessor and - * then eliminated by compiler. Current log level is configured per - * compilation module (.c/.cpp/.m file) by defining BT_LOG_DEF_LEVEL or - * BT_MINIMAL_LOG_LEVEL. BT_MINIMAL_LOG_LEVEL has higer priority and - * when defined overrides value provided by BT_LOG_DEF_LEVEL. - * - * Common practice is to define default current log level with BT_LOG_DEF_LEVEL - * in build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire - * project or target: - * - * CC_ARGS := -DBT_LOG_DEF_LEVEL=BT_LOG_INFO - * - * And when necessary to override it with BT_MINIMAL_LOG_LEVEL in .c/.cpp/.m files - * before including bt_log.h: - * - * #define BT_MINIMAL_LOG_LEVEL BT_LOG_TRACE - * #include "logging.h" - * - * If both BT_LOG_DEF_LEVEL and BT_MINIMAL_LOG_LEVEL are undefined, then - * BT_LOG_INFO will be used for release builds (BT_DEBUG_MODE is NOT - * defined) and BT_LOG_DEBUG otherwise (BT_DEBUG_MODE is defined). - */ -#if defined(BT_MINIMAL_LOG_LEVEL) - #define _BT_MINIMAL_LOG_LEVEL BT_MINIMAL_LOG_LEVEL -#elif defined(BT_LOG_DEF_LEVEL) - #define _BT_MINIMAL_LOG_LEVEL BT_LOG_DEF_LEVEL -#else - #ifdef BT_DEBUG_MODE - #define _BT_MINIMAL_LOG_LEVEL BT_LOG_DEBUG - #else - #define _BT_MINIMAL_LOG_LEVEL BT_LOG_INFO - #endif -#endif +#include "log-api.h" -/* "Output" log level is a runtime check. When log level is below output log - * level it said to be "turned off" (or just "off" for short). Otherwise - * it's "turned on" (or just "on"). Log levels that were "disabled" (see - * BT_MINIMAL_LOG_LEVEL and BT_LOG_DEF_LEVEL) can't be "turned on", but - * "enabled" log levels could be "turned off". Only messages with log - * level which is "turned on" will reach output facility. All other - * messages will be ignored (and their arguments will not be evaluated). - * Output log level is a global property and configured per process - * using bt_log_set_output_level() function which can be called at any - * time. +/* + * `BT_LOG_OUTPUT_LEVEL` (expression having the type `int`, optional): + * valid expression evaluating to the current (run-time) log level. * - * Though in some cases it could be useful to configure output log level per - * compilation module or per library. There are two ways to achieve that: - * - Define BT_LOG_OUTPUT_LEVEL to expresion that evaluates to desired output - * log level. - * - Copy bt_log.h and bt_log.c files into your library and build it with - * BT_LOG_LIBRARY_PREFIX defined to library specific prefix. See - * BT_LOG_LIBRARY_PREFIX for more details. + * This is configured per translation unit. * - * When defined, BT_LOG_OUTPUT_LEVEL must evaluate to integral value - * that corresponds to desired output log level. Use it only when - * compilation module is required to have output log level which is - * different from global output log level set by - * bt_log_set_output_level() function. For other cases, consider - * defining BT_MINIMAL_LOG_LEVEL or using bt_log_set_output_level() - * function. + * Note that BT_LOG*() statements will evaluate this expression each + * time if their level is equally or less verbose than + * `BT_LOG_MINIMAL_LEVEL`. Keep this expression as simple as possible, + * otherwise it will not only add run-time overhead, but also will + * increase the size of call sites (which will result in larger + * executable). * * Example: * - * #define BT_LOG_OUTPUT_LEVEL g_module_log_level - * #include "logging.h" - * static int g_module_log_level = BT_LOG_INFO; - * static void foo() { - * BT_LOGI("Will check g_module_log_level for output log level"); - * } - * void debug_log(bool on) { - * g_module_log_level = on? BT_LOG_DEBUG: BT_LOG_INFO; - * } - * - * Note on performance. This expression will be evaluated each time - * message is logged (except when message log level is "disabled" - see - * BT_MINIMAL_LOG_LEVEL for details). Keep this expression as simple as - * possible, otherwise it will not only add runtime overhead, but also - * will increase size of call site (which will result in larger - * executable). The prefered way is to use integer variable (as in - * example above). If structure must be used, log_level field must be - * the first field in this structure: + * #define BT_LOG_OUTPUT_LEVEL log_level + * #include "logging/log.h" * - * #define BT_LOG_OUTPUT_LEVEL (g_config.log_level) - * #include "logging.h" - * struct config { - * int log_level; - * unsigned other_field; - * [...] - * }; - * static config g_config = {BT_LOG_INFO, 0, ...}; - * - * This allows compiler to generate more compact load instruction (no need to - * specify offset since it's zero). Calling a function to get output log level - * is generaly a bad idea, since it will increase call site size and runtime - * overhead even further. + * If missing, you may only use logging macros having a `_cur_lvl` + * parameter. */ -#if defined(BT_LOG_OUTPUT_LEVEL) - #define _BT_LOG_OUTPUT_LEVEL BT_LOG_OUTPUT_LEVEL -#endif - -/* "Tag" is a compound string that could be associated with a log message. It - * consists of tag prefix and tag (both are optional). - * - * Tag prefix is a global property and configured per process using - * bt_log_set_tag_prefix() function. Tag prefix identifies context in which - * component or module is running (e.g. process name). For example, the same - * library could be used in both client and server processes that work on the - * same machine. Tag prefix could be used to easily distinguish between them. - * For more details about tag prefix see bt_log_set_tag_prefix() function. Tag - * prefix - * - * Tag identifies component or module. It is configured per compilation module - * (.c/.cpp/.m file) by defining BT_LOG_TAG or BT_LOG_DEF_TAG. BT_LOG_TAG has - * higer priority and when defined overrides value provided by BT_LOG_DEF_TAG. - * When defined, value must evaluate to (const char *), so for strings double - * quotes must be used. - * - * Default tag could be defined with BT_LOG_DEF_TAG in build script (e.g. - * Makefile, CMakeLists.txt, gyp, etc.) for the entire project or target: - * - * CC_ARGS := -DBT_LOG_DEF_TAG=\"MISC\" - * - * And when necessary could be overriden with BT_LOG_TAG in .c/.cpp/.m files - * before including bt_log.h: - * - * #define BT_LOG_TAG "MAIN" - * #include "logging.h" - * - * If both BT_LOG_DEF_TAG and BT_LOG_TAG are undefined no tag will be added to - * the log message (tag prefix still could be added though). - * - * Output example: - * - * 04-29 22:43:20.244 40059 1299 I hello.MAIN Number of arguments: 1 - * | | - * | +- tag (e.g. module) - * +- tag prefix (e.g. process name) - */ -#if defined(BT_LOG_TAG) - #define _BT_LOG_TAG BT_LOG_TAG -#elif defined(BT_LOG_DEF_TAG) - #define _BT_LOG_TAG BT_LOG_DEF_TAG -#else - #define _BT_LOG_TAG 0 -#endif - -/* Source location is part of a log line that describes location (function or - * method name, file name and line number, e.g. "runloop@main.cpp:68") of a - * log statement that produced it. - * Source location formats are: - * - BT_LOG_SRCLOC_NONE - don't add source location to log line. - * - BT_LOG_SRCLOC_SHORT - add source location in short form (file and line - * number, e.g. "@main.cpp:68"). - * - BT_LOG_SRCLOC_LONG - add source location in long form (function or method - * name, file and line number, e.g. "runloop@main.cpp:68"). - */ -#define BT_LOG_SRCLOC_NONE 0 -#define BT_LOG_SRCLOC_SHORT 1 -#define BT_LOG_SRCLOC_LONG 2 - -#define _BT_LOG_SRCLOC BT_LOG_SRCLOC_LONG - -#if BT_LOG_SRCLOC_LONG == _BT_LOG_SRCLOC - #define _BT_LOG_SRCLOC_FUNCTION _BT_LOG_FUNCTION +#ifdef BT_LOG_OUTPUT_LEVEL +# define _BT_LOG_OUTPUT_LEVEL BT_LOG_OUTPUT_LEVEL #else - #define _BT_LOG_SRCLOC_FUNCTION 0 +# define _BT_LOG_OUTPUT_LEVEL "Please define `BT_LOG_OUTPUT_LEVEL`" #endif -/* Censoring provides conditional logging of secret information, also known as - * Personally Identifiable Information (PII) or Sensitive Personal Information - * (SPI). Censoring can be either enabled (BT_LOG_CENSORED) or disabled - * (BT_LOG_UNCENSORED). When censoring is enabled, log statements marked as - * "secrets" will be ignored and will have zero overhead (arguments also will - * not be evaluated). - */ -#define BT_LOG_CENSORED 1 -#define BT_LOG_UNCENSORED 0 - -/* Censoring is configured per compilation module (.c/.cpp/.m file) by defining - * BT_LOG_DEF_CENSORING or BT_LOG_CENSORING. BT_LOG_CENSORING has higer priority - * and when defined overrides value provided by BT_LOG_DEF_CENSORING. - * - * Common practice is to define default censoring with BT_LOG_DEF_CENSORING in - * build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire - * project or target: - * - * CC_ARGS := -DBT_LOG_DEF_CENSORING=BT_LOG_CENSORED - * - * And when necessary to override it with BT_LOG_CENSORING in .c/.cpp/.m files - * before including bt_log.h (consider doing it only for debug purposes and be - * very careful not to push such temporary changes to source control): - * - * #define BT_LOG_CENSORING BT_LOG_UNCENSORED - * #include "logging.h" - * - * If both BT_LOG_DEF_CENSORING and BT_LOG_CENSORING are undefined, then - * BT_LOG_CENSORED will be used for release builds (BT_DEBUG_MODE is NOT - * defined) and BT_LOG_UNCENSORED otherwise (BT_DEBUG_MODE is defined). - */ -#if defined(BT_LOG_CENSORING) - #define _BT_LOG_CENSORING BT_LOG_CENSORING -#elif defined(BT_LOG_DEF_CENSORING) - #define _BT_LOG_CENSORING BT_LOG_DEF_CENSORING -#else - #ifdef BT_DEBUG_MODE - #define _BT_LOG_CENSORING BT_LOG_UNCENSORED - #else - #define _BT_LOG_CENSORING BT_LOG_CENSORED - #endif -#endif - -/* Check censoring at compile time. Evaluates to true when censoring is disabled - * (i.e. when secrets will be logged). For example: - * - * #if BT_LOG_SECRETS - * char ssn[16]; - * getSocialSecurityNumber(ssn); - * BT_LOGI("Customer ssn: %s", ssn); - * #endif - * - * See BT_LOG_SECRET() macro for a more convenient way of guarding single log - * statement. - */ -#define BT_LOG_SECRETS (BT_LOG_UNCENSORED == _BT_LOG_CENSORING) - -/* Static (compile-time) initialization support allows to configure logging - * before entering main() function. This mostly useful in C++ where functions - * and methods could be called during initialization of global objects. Those - * functions and methods could record log messages too and for that reason - * static initialization of logging configuration is customizable. - * - * Macros below allow to specify values to use for initial configuration: - * - BT_LOG_EXTERN_TAG_PREFIX - tag prefix (default: none) - * - BT_LOG_EXTERN_GLOBAL_FORMAT - global format options (default: see - * BT_LOG_MEM_WIDTH in bt_log.c) - * - BT_LOG_EXTERN_GLOBAL_OUTPUT - global output facility (default: stderr or - * platform specific, see BT_LOG_USE_XXX macros in bt_log.c) - * - BT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL - global output log level (default: 0 - - * all levals are "turned on") - * - * For example, in log_config.c: - * - * #include "logging.h" - * BT_LOG_DEFINE_TAG_PREFIX = "MyApp"; - * BT_LOG_DEFINE_GLOBAL_FORMAT = {CUSTOM_MEM_WIDTH}; - * BT_LOG_DEFINE_GLOBAL_OUTPUT = {BT_LOG_PUT_STD, custom_output_callback, 0}; - * BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL = BT_LOG_INFO; - * - * However, to use any of those macros bt_log library must be compiled with - * following macros defined: - * - to use BT_LOG_DEFINE_TAG_PREFIX define BT_LOG_EXTERN_TAG_PREFIX - * - to use BT_LOG_DEFINE_GLOBAL_FORMAT define BT_LOG_EXTERN_GLOBAL_FORMAT - * - to use BT_LOG_DEFINE_GLOBAL_OUTPUT define BT_LOG_EXTERN_GLOBAL_OUTPUT - * - to use BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL define - * BT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL - * - * When bt_log library compiled with one of BT_LOG_EXTERN_XXX macros defined, - * corresponding BT_LOG_DEFINE_XXX macro MUST be used exactly once somewhere. - * Otherwise build will fail with link error (undefined symbol). - */ -#define BT_LOG_DEFINE_TAG_PREFIX const char *_bt_log_tag_prefix -#define BT_LOG_DEFINE_GLOBAL_FORMAT bt_log_format _bt_log_global_format -#define BT_LOG_DEFINE_GLOBAL_OUTPUT bt_log_output _bt_log_global_output -#define BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL int _bt_log_global_output_lvl - -/* Pointer to global format options. Direct modification is not allowed. Use - * bt_log_set_mem_width() instead. Could be used to initialize bt_log_spec - * structure: - * - * const bt_log_output g_output = {BT_LOG_PUT_STD, output_callback, 0}; - * const bt_log_spec g_spec = {BT_LOG_GLOBAL_FORMAT, &g_output}; - * BT_LOGI_AUX(&g_spec, "Hello"); - */ -#define BT_LOG_GLOBAL_FORMAT ((const bt_log_format *)&_bt_log_global_format) - -/* Pointer to global output variable. Direct modification is not allowed. Use - * bt_log_set_output_v() or bt_log_set_output_p() instead. Could be used to - * initialize bt_log_spec structure: - * - * const bt_log_format g_format = {40}; - * const bt_log_spec g_spec = {g_format, BT_LOG_GLOBAL_OUTPUT}; - * BT_LOGI_AUX(&g_spec, "Hello"); - */ -#define BT_LOG_GLOBAL_OUTPUT ((const bt_log_output *)&_bt_log_global_output) - -/* When defined, all library symbols produced by linker will be prefixed with - * provided value. That allows to use bt_log library privately in another - * libraries without exposing bt_log symbols in their original form (to avoid - * possible conflicts with other libraries / components that also could use - * bt_log for logging). Value must be without quotes, for example: - * - * CC_ARGS := -DBT_LOG_LIBRARY_PREFIX=my_lib_ - * - * Note, that in this mode BT_LOG_LIBRARY_PREFIX must be defined when building - * bt_log library AND it also must be defined to the same value when building - * a library that uses it. For example, consider fictional KittyHttp library - * that wants to use bt_log for logging. First approach that could be taken is - * to add bt_log.h and bt_log.c to the KittyHttp's source code tree directly. - * In that case it will be enough just to define BT_LOG_LIBRARY_PREFIX in - * KittyHttp's build script: - * - * // KittyHttp/CMakeLists.txt - * target_compile_definitions(KittyHttp PRIVATE - * "BT_LOG_LIBRARY_PREFIX=KittyHttp_") +/* + * `BT_LOG_TAG` (expression having the type `const char *`, optional): + * component or module identifier. * - * If KittyHttp doesn't want to include bt_log source code in its source tree - * and wants to build bt_log as a separate library than bt_log library must be - * built with BT_LOG_LIBRARY_PREFIX defined to KittyHttp_ AND KittyHttp library - * itself also needs to define BT_LOG_LIBRARY_PREFIX to KittyHttp_. It can do - * so either in its build script, as in example above, or by providing a - * wrapper header that KittyHttp library will need to use instead of bt_log.h: + * This is configured per translation unit. * - * // KittyHttpLogging.h - * #define BT_LOG_LIBRARY_PREFIX KittyHttp_ - * #include "logging.h" + * Example: * - * Regardless of the method chosen, the end result is that bt_log symbols will - * be prefixed with "KittyHttp_", so if a user of KittyHttp (say DogeBrowser) - * also uses bt_log for logging, they will not interferer with each other. Both - * will have their own log level, output facility, format options etc. + * // ... + * #define BT_LOG_TAG "MY.MODULE" + * #include "logging/log.h" */ -#ifdef BT_LOG_LIBRARY_PREFIX - #define _BT_LOG_DECOR__(prefix, name) prefix ## name - #define _BT_LOG_DECOR_(prefix, name) _BT_LOG_DECOR__(prefix, name) - #define _BT_LOG_DECOR(name) _BT_LOG_DECOR_(BT_LOG_LIBRARY_PREFIX, name) - - #define bt_log_set_tag_prefix _BT_LOG_DECOR(bt_log_set_tag_prefix) - #define bt_log_set_mem_width _BT_LOG_DECOR(bt_log_set_mem_width) - #define bt_log_set_output_level _BT_LOG_DECOR(bt_log_set_output_level) - #define bt_log_set_output_v _BT_LOG_DECOR(bt_log_set_output_v) - #define bt_log_set_output_p _BT_LOG_DECOR(bt_log_set_output_p) - #define bt_log_out_stderr_callback _BT_LOG_DECOR(bt_log_out_stderr_callback) - #define _bt_log_tag_prefix _BT_LOG_DECOR(_bt_log_tag_prefix) - #define _bt_log_global_format _BT_LOG_DECOR(_bt_log_global_format) - #define _bt_log_global_output _BT_LOG_DECOR(_bt_log_global_output) - #define _bt_log_global_output_lvl _BT_LOG_DECOR(_bt_log_global_output_lvl) - #define _bt_log_write_d _BT_LOG_DECOR(_bt_log_write_d) - #define _bt_log_write_aux_d _BT_LOG_DECOR(_bt_log_write_aux_d) - #define _bt_log_write _BT_LOG_DECOR(_bt_log_write) - #define _bt_log_write_aux _BT_LOG_DECOR(_bt_log_write_aux) - #define _bt_log_write_mem_d _BT_LOG_DECOR(_bt_log_write_mem_d) - #define _bt_log_write_mem_aux_d _BT_LOG_DECOR(_bt_log_write_mem_aux_d) - #define _bt_log_write_mem _BT_LOG_DECOR(_bt_log_write_mem) - #define _bt_log_write_mem_aux _BT_LOG_DECOR(_bt_log_write_mem_aux) - #define _bt_log_stderr_spec _BT_LOG_DECOR(_bt_log_stderr_spec) -#endif - -#if defined(__printflike) - #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \ - __printflike(str_index, first_to_check) -#elif defined(__MINGW_PRINTF_FORMAT) - #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \ - __attribute__((format(__MINGW_PRINTF_FORMAT, str_index, first_to_check))) -#elif defined(__GNUC__) - #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \ - __attribute__((format(__printf__, str_index, first_to_check))) -#else - #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) -#endif - -#if (defined(_WIN32) || defined(_WIN64)) && !defined(__GNUC__) - #define _BT_LOG_FUNCTION __FUNCTION__ -#else - #define _BT_LOG_FUNCTION __func__ -#endif - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - #define _BT_LOG_INLINE __inline - #define _BT_LOG_IF(cond) \ - __pragma(warning(push)) \ - __pragma(warning(disable:4127)) \ - if(cond) \ - __pragma(warning(pop)) - #define _BT_LOG_WHILE(cond) \ - __pragma(warning(push)) \ - __pragma(warning(disable:4127)) \ - while(cond) \ - __pragma(warning(pop)) +#ifdef BT_LOG_TAG +# define _BT_LOG_TAG BT_LOG_TAG #else - #define _BT_LOG_INLINE inline - #define _BT_LOG_IF(cond) if(cond) - #define _BT_LOG_WHILE(cond) while(cond) +# define _BT_LOG_TAG NULL #endif -#define _BT_LOG_NEVER _BT_LOG_IF(0) -#define _BT_LOG_ONCE _BT_LOG_WHILE(0) -#ifdef __cplusplus -extern "C" { -#endif - -/* Set tag prefix. Prefix will be separated from the tag with dot ('.'). - * Use 0 or empty string to disable (default). Common use is to set it to - * the process (or build target) name (e.g. to separate client and server - * processes). Function will NOT copy provided prefix string, but will store the - * pointer. Hence specified prefix string must remain valid. See - * BT_LOG_DEFINE_TAG_PREFIX for a way to set it before entering main() function. - * See BT_LOG_TAG for more information about tag and tag prefix. - */ -void bt_log_set_tag_prefix(const char *const prefix); - -/* Set number of bytes per log line in memory (ASCII-HEX) output. Example: - * - * I hello.MAIN 4c6f72656d20697073756d20646f6c6f Lorem ipsum dolo - * |<- w bytes ->| |<- w chars ->| - * - * See BT_LOGF_MEM and BT_LOGF_MEM_AUX for more details. +/* + * BT_LOG_ON_CUR_LVL() using `BT_LOG_OUTPUT_LEVEL` as the current + * (run-time) level. */ -void bt_log_set_mem_width(const unsigned w); +#define BT_LOG_ON(_lvl) BT_LOG_ON_CUR_LVL(_lvl, _BT_LOG_OUTPUT_LEVEL) +#define BT_LOG_ON_TRACE BT_LOG_ON(BT_LOG_TRACE) +#define BT_LOG_ON_DEBUG BT_LOG_ON(BT_LOG_DEBUG) +#define BT_LOG_ON_INFO BT_LOG_ON(BT_LOG_INFO) +#define BT_LOG_ON_WARNING BT_LOG_ON(BT_LOG_WARNING) +#define BT_LOG_ON_ERROR BT_LOG_ON(BT_LOG_ERROR) +#define BT_LOG_ON_FATAL BT_LOG_ON(BT_LOG_FATAL) -/* Set "output" log level. See BT_MINIMAL_LOG_LEVEL and BT_LOG_OUTPUT_LEVEL for more - * info about log levels. +/* + * BT_LOG_WRITE_CUR_LVL() using `BT_LOG_OUTPUT_LEVEL` as the current + * (run-time) level. */ -void bt_log_set_output_level(const int lvl); +#define BT_LOG_WRITE(_lvl, _tag, _msg) \ + BT_LOG_WRITE_CUR_LVL((_lvl), _BT_LOG_OUTPUT_LEVEL, (_tag), (_msg)) -/* Put mask is a set of flags that define what fields will be added to each - * log message. Default value is BT_LOG_PUT_STD and other flags could be used to - * alter its behavior. See bt_log_set_output_v() for more details. - * - * Note about BT_LOG_PUT_SRC: it will be added only in debug builds - * (BT_DEBUG_MODE is defined). +/* + * BT_LOG_WRITE_PRINTF_CUR_LVL() using `BT_LOG_OUTPUT_LEVEL` as the + * current (run-time) level. */ -enum -{ - BT_LOG_PUT_CTX = 1 << 0, /* context (time, pid, tid, log level) */ - BT_LOG_PUT_TAG = 1 << 1, /* tag (including tag prefix) */ - BT_LOG_PUT_SRC = 1 << 2, /* source location (file, line, function) */ - BT_LOG_PUT_MSG = 1 << 3, /* message text (formatted string) */ - BT_LOG_PUT_STD = 0xffff, /* everything (default) */ -}; - -typedef struct bt_log_message -{ - int lvl; /* Log level of the message */ - const char *tag; /* Associated tag (without tag prefix) */ - char *buf; /* Buffer start */ - char *e; /* Buffer end (last position where EOL with 0 could be written) */ - char *p; /* Buffer content end (append position) */ - char *tag_b; /* Prefixed tag start */ - char *tag_e; /* Prefixed tag end (if != tag_b, points to msg separator) */ - char *msg_b; /* Message start (expanded format string) */ -} -bt_log_message; +#define BT_LOG_WRITE_PRINTF(_lvl, _tag, _fmt, ...) \ + BT_LOG_WRITE_PRINTF_CUR_LVL((_lvl), _BT_LOG_OUTPUT_LEVEL, \ + (_tag), (_fmt), ##__VA_ARGS__) -/* Type of output callback function. It will be called for each log line allowed - * by both "current" and "output" log levels ("enabled" and "turned on"). - * Callback function is allowed to modify content of the buffers pointed by the - * msg, but it's not allowed to modify any of msg fields. Buffer pointed by msg - * is UTF-8 encoded (no BOM mark). +/* + * BT_LOG_WRITE_MEM_CUR_LVL() using `BT_LOG_OUTPUT_LEVEL` as the current + * (run-time) level. */ -typedef void (*bt_log_output_cb)(const bt_log_message *msg, void *arg); +#define BT_LOG_WRITE_MEM(_lvl, _tag, _mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM_CUR_LVL((_lvl), _BT_LOG_OUTPUT_LEVEL, (_tag), \ + (_mem_data), (_mem_len), (_msg)) -/* Format options. For more details see bt_log_set_mem_width(). +/* + * BT_LOG_WRITE_MEM_PRINTF_CUR_LVL() using `BT_LOG_OUTPUT_LEVEL` as the + * current (run-time) level. */ -typedef struct bt_log_format -{ - unsigned mem_width; /* Bytes per line in memory (ASCII-HEX) dump */ -} -bt_log_format; +#define BT_LOG_WRITE_MEM_PRINTF(_lvl, _tag, _mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF_CUR_LVL((_lvl), _BT_LOG_OUTPUT_LEVEL, \ + (_tag), (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) -/* Output facility. +/* + * BT_LOG_WRITE_ERRNO_CUR_LVL() using `BT_LOG_OUTPUT_LEVEL` as the + * current (run-time) level. */ -typedef struct bt_log_output -{ - unsigned mask; /* What to put into log line buffer (see BT_LOG_PUT_XXX) */ - void *arg; /* User provided output callback argument */ - bt_log_output_cb callback; /* Output callback function */ -} -bt_log_output; +#define BT_LOG_WRITE_ERRNO(_lvl, _tag, _init_msg, _msg) \ + BT_LOG_WRITE_ERRNO_CUR_LVL((_lvl), _BT_LOG_OUTPUT_LEVEL, \ + (_tag), (_init_msg), (_msg)) -/* Set output callback function. - * - * Mask allows to control what information will be added to the log line buffer - * before callback function is invoked. Default mask value is BT_LOG_PUT_STD. +/* + * BT_LOG_WRITE_ERRNO_PRINTF_CUR_LVL() using `BT_LOG_OUTPUT_LEVEL` as + * the current (run-time) level. */ -void bt_log_set_output_v(const unsigned mask, void *const arg, - const bt_log_output_cb callback); -static _BT_LOG_INLINE void bt_log_set_output_p(const bt_log_output *const output) -{ - bt_log_set_output_v(output->mask, output->arg, output->callback); -} +#define BT_LOG_WRITE_ERRNO_PRINTF(_lvl, _tag, _init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF_CUR_LVL((_lvl), _BT_LOG_OUTPUT_LEVEL, \ + (_tag), (_init_msg), (_fmt), ##__VA_ARGS__) -/* Used with _AUX macros and allows to override global format and output - * facility. Use BT_LOG_GLOBAL_FORMAT and BT_LOG_GLOBAL_OUTPUT for values from - * global configuration. Example: - * - * static const bt_log_output module_output = { - * BT_LOG_PUT_STD, 0, custom_output_callback - * }; - * static const bt_log_spec module_spec = { - * BT_LOG_GLOBAL_FORMAT, &module_output - * }; - * BT_LOGI_AUX(&module_spec, "Position: %ix%i", x, y); - * - * See BT_LOGF_AUX and BT_LOGF_MEM_AUX for details. - */ -typedef struct bt_log_spec +/* Internal: no-op function when a log level is disabled */ +static inline +void _bt_log_unused(int dummy __attribute__((unused)), ...) { - const bt_log_format *format; - const bt_log_output *output; -} -bt_log_spec; - -#ifdef __cplusplus } -#endif - -/* Execute log statement if condition is true. Example: - * - * BT_LOG_IF(1 < 2, BT_LOGI("Log this")); - * BT_LOG_IF(1 > 2, BT_LOGI("Don't log this")); - * - * Keep in mind though, that if condition can't be evaluated at compile time, - * then it will be evaluated at run time. This will increase exectuable size - * and can have noticeable performance overhead. Try to limit conditions to - * expressions that can be evaluated at compile time. - */ -#define BT_LOG_IF(cond, f) do { _BT_LOG_IF((cond)) { f; } } _BT_LOG_ONCE - -/* Mark log statement as "secret". Log statements that are marked as secrets - * will NOT be executed when censoring is enabled (see BT_LOG_CENSORED). - * Example: - * - * BT_LOG_SECRET(BT_LOGI("Credit card: %s", credit_card)); - * BT_LOG_SECRET(BT_LOGD_MEM(cipher, cipher_sz, "Cipher bytes:")); - */ -#define BT_LOG_SECRET(f) BT_LOG_IF(BT_LOG_SECRETS, f) - -/* Check "current" log level at compile time (ignoring "output" log level). - * Evaluates to true when specified log level is enabled. For example: - * - * #if BT_LOG_ENABLED_DEBUG - * const char *const g_enum_strings[] = { - * "enum_value_0", "enum_value_1", "enum_value_2" - * }; - * #endif - * // ... - * #if BT_LOG_ENABLED_DEBUG - * BT_LOGD("enum value: %s", g_enum_strings[v]); - * #endif - * - * See BT_MINIMAL_LOG_LEVEL for details. - */ -#define BT_LOG_ENABLED(lvl) ((lvl) >= _BT_MINIMAL_LOG_LEVEL) -#define BT_LOG_ENABLED_TRACE BT_LOG_ENABLED(BT_LOG_TRACE) -#define BT_LOG_ENABLED_DEBUG BT_LOG_ENABLED(BT_LOG_DEBUG) -#define BT_LOG_ENABLED_INFO BT_LOG_ENABLED(BT_LOG_INFO) -#define BT_LOG_ENABLED_WARNING BT_LOG_ENABLED(BT_LOG_WARNING) -#define BT_LOG_ENABLED_ERROR BT_LOG_ENABLED(BT_LOG_ERROR) -#define BT_LOG_ENABLED_FATAL BT_LOG_ENABLED(BT_LOG_FATAL) - -/* Check "output" log level at run time (taking into account "current" log - * level as well). Evaluates to true when specified log level is turned on AND - * enabled. For example: - * - * if (BT_LOG_ON_DEBUG) - * { - * char hash[65]; - * sha256(data_ptr, data_sz, hash); - * BT_LOGD("data: len=%u, sha256=%s", data_sz, hash); - * } - * - * See BT_LOG_OUTPUT_LEVEL for details. - */ -#define BT_LOG_ON_CUR_LVL(lvl, cur_lvl) \ - G_UNLIKELY(BT_LOG_ENABLED((lvl)) && (lvl) >= (cur_lvl)) -#define BT_LOG_ON(lvl) \ - G_UNLIKELY(BT_LOG_ENABLED((lvl)) && (lvl) >= _BT_LOG_OUTPUT_LEVEL) -#define BT_LOG_ON_TRACE BT_LOG_ON(BT_LOG_TRACE) -#define BT_LOG_ON_DEBUG BT_LOG_ON(BT_LOG_DEBUG) -#define BT_LOG_ON_INFO BT_LOG_ON(BT_LOG_INFO) -#define BT_LOG_ON_WARNING BT_LOG_ON(BT_LOG_WARNING) -#define BT_LOG_ON_ERROR BT_LOG_ON(BT_LOG_ERROR) -#define BT_LOG_ON_FATAL BT_LOG_ON(BT_LOG_FATAL) - -#ifdef __cplusplus -extern "C" { -#endif - -extern const char *_bt_log_tag_prefix; -extern bt_log_format _bt_log_global_format; -extern bt_log_output _bt_log_global_output; -extern int _bt_log_global_output_lvl; -extern const bt_log_spec _bt_log_stderr_spec; - -void _bt_log_write_d( - const char *const func, const char *const file, const unsigned line, - const int lvl, const char *const tag, - const char *const fmt, ...) _BT_LOG_PRINTFLIKE(6, 7); - -void _bt_log_write_aux_d( - const char *const func, const char *const file, const unsigned line, - const bt_log_spec *const log, const int lvl, const char *const tag, - const char *const fmt, ...) _BT_LOG_PRINTFLIKE(7, 8); - -void _bt_log_write( - const int lvl, const char *const tag, - const char *const fmt, ...) _BT_LOG_PRINTFLIKE(3, 4); - -void _bt_log_write_aux( - const bt_log_spec *const log, const int lvl, const char *const tag, - const char *const fmt, ...) _BT_LOG_PRINTFLIKE(4, 5); - -void _bt_log_write_mem_d( - const char *const func, const char *const file, const unsigned line, - const int lvl, const char *const tag, - const void *const d, const unsigned d_sz, - const char *const fmt, ...) _BT_LOG_PRINTFLIKE(8, 9); - -void _bt_log_write_mem_aux_d( - const char *const func, const char *const file, const unsigned line, - const bt_log_spec *const log, const int lvl, const char *const tag, - const void *const d, const unsigned d_sz, - const char *const fmt, ...) _BT_LOG_PRINTFLIKE(9, 10); - -void _bt_log_write_mem( - const int lvl, const char *const tag, - const void *const d, const unsigned d_sz, - const char *const fmt, ...) _BT_LOG_PRINTFLIKE(5, 6); - -void _bt_log_write_mem_aux( - const bt_log_spec *const log, const int lvl, const char *const tag, - const void *const d, const unsigned d_sz, - const char *const fmt, ...) _BT_LOG_PRINTFLIKE(6, 7); - -#ifdef __cplusplus -} -#endif - -/* Message logging macros: - * - BT_LOGT("format string", args, ...) - * - BT_LOGD("format string", args, ...) - * - BT_LOGI("format string", args, ...) - * - BT_LOGW("format string", args, ...) - * - BT_LOGE("format string", args, ...) - * - BT_LOGF("format string", args, ...) - * - * Message and error string (errno) logging macros: - * - BT_LOGT_ERRNO("initial message", "format string", args, ...) - * - BT_LOGD_ERRNO("initial message", "format string", args, ...) - * - BT_LOGI_ERRNO("initial message", "format string", args, ...) - * - BT_LOGW_ERRNO("initial message", "format string", args, ...) - * - BT_LOGE_ERRNO("initial message", "format string", args, ...) - * - BT_LOGF_ERRNO("initial message", "format string", args, ...) - * - * Memory logging macros: - * - BT_LOGT_MEM(data_ptr, data_sz, "format string", args, ...) - * - BT_LOGD_MEM(data_ptr, data_sz, "format string", args, ...) - * - BT_LOGI_MEM(data_ptr, data_sz, "format string", args, ...) - * - BT_LOGW_MEM(data_ptr, data_sz, "format string", args, ...) - * - BT_LOGE_MEM(data_ptr, data_sz, "format string", args, ...) - * - BT_LOGF_MEM(data_ptr, data_sz, "format string", args, ...) - * - * Auxiliary logging macros: - * - BT_LOGT_AUX(&log_instance, "format string", args, ...) - * - BT_LOGD_AUX(&log_instance, "format string", args, ...) - * - BT_LOGI_AUX(&log_instance, "format string", args, ...) - * - BT_LOGW_AUX(&log_instance, "format string", args, ...) - * - BT_LOGE_AUX(&log_instance, "format string", args, ...) - * - BT_LOGF_AUX(&log_instance, "format string", args, ...) - * - * Auxiliary memory logging macros: - * - BT_LOGT_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) - * - BT_LOGD_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) - * - BT_LOGI_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) - * - BT_LOGW_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) - * - BT_LOGE_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) - * - BT_LOGF_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) - * - * Preformatted string logging macros: - * - BT_LOGT_STR("preformatted string"); - * - BT_LOGD_STR("preformatted string"); - * - BT_LOGI_STR("preformatted string"); - * - BT_LOGW_STR("preformatted string"); - * - BT_LOGE_STR("preformatted string"); - * - BT_LOGF_STR("preformatted string"); - * - * Explicit log level and tag macros: - * - BT_LOG_WRITE(level, tag, "format string", args, ...) - * - BT_LOG_WRITE_MEM(level, tag, data_ptr, data_sz, "format string", args, ...) - * - BT_LOG_WRITE_AUX(&log_instance, level, tag, "format string", args, ...) - * - BT_LOG_WRITE_MEM_AUX(&log_instance, level, tag, data_ptr, data_sz, - * "format string", args, ...) - * - * Explicit log level, current log level, and tag: - * - BT_LOG_WRITE_CUR_LVL(level, cur_level, tag, "format string", args, ...) - * - * Format string follows printf() conventions. Both data_ptr and data_sz could - * be 0. Tag can be 0 as well. Most compilers will verify that type of arguments - * match format specifiers in format string. - * - * Library assuming UTF-8 encoding for all strings (char *), including format - * string itself. - */ -#if BT_LOG_SRCLOC_NONE == _BT_LOG_SRCLOC - #define BT_LOG_WRITE(lvl, tag, ...) \ - do { \ - if (BT_LOG_ON(lvl)) \ - _bt_log_write(lvl, tag, __VA_ARGS__); \ - } _BT_LOG_ONCE - #define BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, ...) \ - do { \ - if (BT_LOG_ON_CUR_LVL((lvl), (cur_lvl))) \ - _bt_log_write(lvl, tag, __VA_ARGS__); \ - } _BT_LOG_ONCE - #define BT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \ - do { \ - if (BT_LOG_ON(lvl)) \ - _bt_log_write_mem(lvl, tag, d, d_sz, __VA_ARGS__); \ - } _BT_LOG_ONCE - #define BT_LOG_WRITE_AUX(log, lvl, tag, ...) \ - do { \ - if (BT_LOG_ON(lvl)) \ - _bt_log_write_aux(log, lvl, tag, __VA_ARGS__); \ - } _BT_LOG_ONCE - #define BT_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \ - do { \ - if (BT_LOG_ON(lvl)) \ - _bt_log_write_mem_aux(log, lvl, tag, d, d_sz, __VA_ARGS__); \ - } _BT_LOG_ONCE -#else - #define BT_LOG_WRITE(lvl, tag, ...) \ - do { \ - if (BT_LOG_ON(lvl)) \ - _bt_log_write_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \ - lvl, tag, __VA_ARGS__); \ - } _BT_LOG_ONCE - #define BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, ...) \ - do { \ - if (BT_LOG_ON_CUR_LVL((lvl), (cur_lvl))) \ - _bt_log_write_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \ - lvl, tag, __VA_ARGS__); \ - } _BT_LOG_ONCE - #define BT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \ - do { \ - if (BT_LOG_ON(lvl)) \ - _bt_log_write_mem_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \ - lvl, tag, d, d_sz, __VA_ARGS__); \ - } _BT_LOG_ONCE - #define BT_LOG_WRITE_AUX(log, lvl, tag, ...) \ - do { \ - if (BT_LOG_ON(lvl)) \ - _bt_log_write_aux_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \ - log, lvl, tag, __VA_ARGS__); \ - } _BT_LOG_ONCE - #define BT_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \ - do { \ - if (BT_LOG_ON(lvl)) \ - _bt_log_write_mem_aux_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \ - log, lvl, tag, d, d_sz, __VA_ARGS__); \ - } _BT_LOG_ONCE -#endif - -#define BT_LOG_WRITE_ERRNO_CUR_LVL(lvl, cur_lvl, tag, _msg, _fmt, args...) \ - do { \ - const char *error_str; \ - error_str = g_strerror(errno); \ - BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, _msg ": %s" _fmt, error_str, ## args); \ - } _BT_LOG_ONCE - -#define BT_LOG_WRITE_ERRNO(lvl, tag, _msg, _fmt, args...) \ - do { \ - BT_LOG_WRITE_ERRNO_CUR_LVL(lvl, _BT_LOG_OUTPUT_LEVEL, tag, _msg, _fmt, ## args); \ - } _BT_LOG_ONCE - -static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;} #define _BT_LOG_UNUSED(...) \ - do { _BT_LOG_NEVER _bt_log_unused(0, __VA_ARGS__); } _BT_LOG_ONCE + do { if (0) _bt_log_unused(0, ##__VA_ARGS__); } while (0) +/* Trace level logging macros using `BT_LOG_TAG` */ #if BT_LOG_ENABLED_TRACE - #define BT_LOGT(...) \ - BT_LOG_WRITE(BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGT_ERRNO(...) \ - BT_LOG_WRITE_ERRNO(BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGT_AUX(log, ...) \ - BT_LOG_WRITE_AUX(log, BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGT_MEM(d, d_sz, ...) \ - BT_LOG_WRITE_MEM(BT_LOG_TRACE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) - #define BT_LOGT_MEM_AUX(log, d, d_sz, ...) \ - BT_LOG_WRITE_MEM(log, BT_LOG_TRACE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) +# define BT_LOGT_STR_CUR_LVL(_cur_lvl, _msg) \ + BT_LOG_WRITE_CUR_LVL(BT_LOG_TRACE, (_cur_lvl), _BT_LOG_TAG, (_msg)) +# define BT_LOGT_STR(_msg) \ + BT_LOG_WRITE(BT_LOG_TRACE, _BT_LOG_TAG, (_msg)) +# define BT_LOGT_CUR_LVL(_cur_lvl, _fmt, ...) \ + BT_LOG_WRITE_PRINTF_CUR_LVL(BT_LOG_TRACE, (_cur_lvl), _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGT(_fmt, ...) \ + BT_LOG_WRITE_PRINTF(BT_LOG_TRACE, _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGT_MEM_STR_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM_CUR_LVL(BT_LOG_TRACE, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGT_MEM_STR(_mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM(BT_LOG_TRACE, _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGT_MEM_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF_CUR_LVL(BT_LOG_TRACE, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGT_MEM(_mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF(BT_LOG_TRACE, _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGT_ERRNO_STR_CUR_LVL(_cur_lvl, _init_msg, _msg) \ + BT_LOG_WRITE_ERRNO_CUR_LVL(BT_LOG_TRACE, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGT_ERRNO_STR(_init_msg, _msg) \ + BT_LOG_WRITE_ERRNO(BT_LOG_TRACE, _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGT_ERRNO_CUR_LVL(_cur_lvl, _init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF_CUR_LVL(BT_LOG_TRACE, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) +# define BT_LOGT_ERRNO(_init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF(BT_LOG_TRACE, _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) #else - #define BT_LOGT(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGT_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGT_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGT_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGT_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) -#endif - +# define BT_LOGT_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_MEM_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_MEM_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_MEM_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_ERRNO_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_ERRNO_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_ERRNO_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGT_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) +#endif /* BT_LOG_ENABLED_TRACE */ + +/* Debug level logging macros using `BT_LOG_TAG` */ #if BT_LOG_ENABLED_DEBUG - #define BT_LOGD(...) \ - BT_LOG_WRITE(BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGD_ERRNO(...) \ - BT_LOG_WRITE_ERRNO(BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGD_AUX(log, ...) \ - BT_LOG_WRITE_AUX(log, BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGD_MEM(d, d_sz, ...) \ - BT_LOG_WRITE_MEM(BT_LOG_DEBUG, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) - #define BT_LOGD_MEM_AUX(log, d, d_sz, ...) \ - BT_LOG_WRITE_MEM_AUX(log, BT_LOG_DEBUG, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) +# define BT_LOGD_STR_CUR_LVL(_cur_lvl, _msg) \ + BT_LOG_WRITE_CUR_LVL(BT_LOG_DEBUG, (_cur_lvl), _BT_LOG_TAG, (_msg)) +# define BT_LOGD_STR(_msg) \ + BT_LOG_WRITE(BT_LOG_DEBUG, _BT_LOG_TAG, (_msg)) +# define BT_LOGD_CUR_LVL(_cur_lvl, _fmt, ...) \ + BT_LOG_WRITE_PRINTF_CUR_LVL(BT_LOG_DEBUG, (_cur_lvl), _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGD(_fmt, ...) \ + BT_LOG_WRITE_PRINTF(BT_LOG_DEBUG, _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGD_MEM_STR_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM_CUR_LVL(BT_LOG_DEBUG, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGD_MEM_STR(_mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM(BT_LOG_DEBUG, _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGD_MEM_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF_CUR_LVL(BT_LOG_DEBUG, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGD_MEM(_mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF(BT_LOG_DEBUG, _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGD_ERRNO_STR_CUR_LVL(_cur_lvl, _init_msg, _msg) \ + BT_LOG_WRITE_ERRNO_CUR_LVL(BT_LOG_DEBUG, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGD_ERRNO_STR(_init_msg, _msg) \ + BT_LOG_WRITE_ERRNO(BT_LOG_DEBUG, _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGD_ERRNO_CUR_LVL(_cur_lvl, _init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF_CUR_LVL(BT_LOG_DEBUG, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) +# define BT_LOGD_ERRNO(_init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF(BT_LOG_DEBUG, _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) #else - #define BT_LOGD(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGD_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGD_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGD_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGD_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) -#endif - +# define BT_LOGD_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_MEM_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_MEM_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_MEM_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_ERRNO_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_ERRNO_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_ERRNO_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGD_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) +#endif /* BT_LOG_ENABLED_DEBUG */ + +/* Info level logging macros using `BT_LOG_TAG` */ #if BT_LOG_ENABLED_INFO - #define BT_LOGI(...) \ - BT_LOG_WRITE(BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGI_ERRNO(...) \ - BT_LOG_WRITE_ERRNO(BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGI_AUX(log, ...) \ - BT_LOG_WRITE_AUX(log, BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGI_MEM(d, d_sz, ...) \ - BT_LOG_WRITE_MEM(BT_LOG_INFO, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) - #define BT_LOGI_MEM_AUX(log, d, d_sz, ...) \ - BT_LOG_WRITE_MEM_AUX(log, BT_LOG_INFO, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) +# define BT_LOGI_STR_CUR_LVL(_cur_lvl, _msg) \ + BT_LOG_WRITE_CUR_LVL(BT_LOG_INFO, (_cur_lvl), _BT_LOG_TAG, (_msg)) +# define BT_LOGI_STR(_msg) \ + BT_LOG_WRITE(BT_LOG_INFO, _BT_LOG_TAG, (_msg)) +# define BT_LOGI_CUR_LVL(_cur_lvl, _fmt, ...) \ + BT_LOG_WRITE_PRINTF_CUR_LVL(BT_LOG_INFO, (_cur_lvl), _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGI(_fmt, ...) \ + BT_LOG_WRITE_PRINTF(BT_LOG_INFO, _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGI_MEM_STR_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM_CUR_LVL(BT_LOG_INFO, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGI_MEM_STR(_mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM(BT_LOG_INFO, _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGI_MEM_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF_CUR_LVL(BT_LOG_INFO, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGI_MEM(_mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF(BT_LOG_INFO, _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGI_ERRNO_STR_CUR_LVL(_cur_lvl, _init_msg, _msg) \ + BT_LOG_WRITE_ERRNO_CUR_LVL(BT_LOG_INFO, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGI_ERRNO_STR(_init_msg, _msg) \ + BT_LOG_WRITE_ERRNO(BT_LOG_INFO, _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGI_ERRNO_CUR_LVL(_cur_lvl, _init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF_CUR_LVL(BT_LOG_INFO, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) +# define BT_LOGI_ERRNO(_init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF(BT_LOG_INFO, _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) #else - #define BT_LOGI(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGI_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGI_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGI_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGI_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) -#endif - +# define BT_LOGI_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_MEM_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_MEM_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_MEM_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_ERRNO_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_ERRNO_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_ERRNO_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGI_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) +#endif /* BT_LOG_ENABLED_INFO */ + +/* Warning level logging macros using `BT_LOG_TAG` */ #if BT_LOG_ENABLED_WARNING - #define BT_LOGW(...) \ - BT_LOG_WRITE(BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGW_ERRNO(...) \ - BT_LOG_WRITE_ERRNO(BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGW_AUX(log, ...) \ - BT_LOG_WRITE_AUX(log, BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGW_MEM(d, d_sz, ...) \ - BT_LOG_WRITE_MEM(BT_LOG_WARNING, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) - #define BT_LOGW_MEM_AUX(log, d, d_sz, ...) \ - BT_LOG_WRITE_MEM_AUX(log, BT_LOG_WARNING, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) +# define BT_LOGW_STR_CUR_LVL(_cur_lvl, _msg) \ + BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING, (_cur_lvl), _BT_LOG_TAG, (_msg)) +# define BT_LOGW_STR(_msg) \ + BT_LOG_WRITE(BT_LOG_WARNING, _BT_LOG_TAG, (_msg)) +# define BT_LOGW_CUR_LVL(_cur_lvl, _fmt, ...) \ + BT_LOG_WRITE_PRINTF_CUR_LVL(BT_LOG_WARNING, (_cur_lvl), _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGW(_fmt, ...) \ + BT_LOG_WRITE_PRINTF(BT_LOG_WARNING, _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGW_MEM_STR_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM_CUR_LVL(BT_LOG_WARNING, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGW_MEM_STR(_mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM(BT_LOG_WARNING, _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGW_MEM_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF_CUR_LVL(BT_LOG_WARNING, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGW_MEM(_mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF(BT_LOG_WARNING, _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGW_ERRNO_STR_CUR_LVL(_cur_lvl, _init_msg, _msg) \ + BT_LOG_WRITE_ERRNO_CUR_LVL(BT_LOG_WARNING, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGW_ERRNO_STR(_init_msg, _msg) \ + BT_LOG_WRITE_ERRNO(BT_LOG_WARNING, _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGW_ERRNO_CUR_LVL(_cur_lvl, _init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF_CUR_LVL(BT_LOG_WARNING, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) +# define BT_LOGW_ERRNO(_init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF(BT_LOG_WARNING, _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) #else - #define BT_LOGW(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGW_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGW_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGW_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGW_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) -#endif - +# define BT_LOGW_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_MEM_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_MEM_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_MEM_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_ERRNO_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_ERRNO_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_ERRNO_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGW_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) +#endif /* BT_LOG_ENABLED_WARNING */ + +/* Error level logging macros using `BT_LOG_TAG` */ #if BT_LOG_ENABLED_ERROR - #define BT_LOGE(...) \ - BT_LOG_WRITE(BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGE_ERRNO(...) \ - BT_LOG_WRITE_ERRNO(BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGE_AUX(log, ...) \ - BT_LOG_WRITE_AUX(log, BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGE_MEM(d, d_sz, ...) \ - BT_LOG_WRITE_MEM(BT_LOG_ERROR, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) - #define BT_LOGE_MEM_AUX(log, d, d_sz, ...) \ - BT_LOG_WRITE_MEM_AUX(log, BT_LOG_ERROR, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) +# define BT_LOGE_STR_CUR_LVL(_cur_lvl, _msg) \ + BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR, (_cur_lvl), _BT_LOG_TAG, (_msg)) +# define BT_LOGE_STR(_msg) \ + BT_LOG_WRITE(BT_LOG_ERROR, _BT_LOG_TAG, (_msg)) +# define BT_LOGE_CUR_LVL(_cur_lvl, _fmt, ...) \ + BT_LOG_WRITE_PRINTF_CUR_LVL(BT_LOG_ERROR, (_cur_lvl), _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGE(_fmt, ...) \ + BT_LOG_WRITE_PRINTF(BT_LOG_ERROR, _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGE_MEM_STR_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM_CUR_LVL(BT_LOG_ERROR, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGE_MEM_STR(_mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM(BT_LOG_ERROR, _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGE_MEM_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF_CUR_LVL(BT_LOG_ERROR, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGE_MEM(_mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF(BT_LOG_ERROR, _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGE_ERRNO_STR_CUR_LVL(_cur_lvl, _init_msg, _msg) \ + BT_LOG_WRITE_ERRNO_CUR_LVL(BT_LOG_ERROR, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGE_ERRNO_STR(_init_msg, _msg) \ + BT_LOG_WRITE_ERRNO(BT_LOG_ERROR, _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGE_ERRNO_CUR_LVL(_cur_lvl, _init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF_CUR_LVL(BT_LOG_ERROR, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) +# define BT_LOGE_ERRNO(_init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF(BT_LOG_ERROR, _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) #else - #define BT_LOGE(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGE_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGE_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGE_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGE_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) -#endif - +# define BT_LOGE_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_MEM_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_MEM_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_MEM_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_ERRNO_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_ERRNO_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_ERRNO_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGE_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) +#endif /* BT_LOG_ENABLED_ERROR */ + +/* Fatal level logging macros using `BT_LOG_TAG` */ #if BT_LOG_ENABLED_FATAL - #define BT_LOGF(...) \ - BT_LOG_WRITE(BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGF_ERRNO(...) \ - BT_LOG_WRITE_ERRNO(BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGF_AUX(log, ...) \ - BT_LOG_WRITE_AUX(log, BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGF_MEM(d, d_sz, ...) \ - BT_LOG_WRITE_MEM(BT_LOG_FATAL, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) - #define BT_LOGF_MEM_AUX(log, d, d_sz, ...) \ - BT_LOG_WRITE_MEM_AUX(log, BT_LOG_FATAL, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) +# define BT_LOGF_STR_CUR_LVL(_cur_lvl, _msg) \ + BT_LOG_WRITE_CUR_LVL(BT_LOG_FATAL, (_cur_lvl), _BT_LOG_TAG, (_msg)) +# define BT_LOGF_STR(_msg) \ + BT_LOG_WRITE(BT_LOG_FATAL, _BT_LOG_TAG, (_msg)) +# define BT_LOGF_CUR_LVL(_cur_lvl, _fmt, ...) \ + BT_LOG_WRITE_PRINTF_CUR_LVL(BT_LOG_FATAL, (_cur_lvl), _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGF(_fmt, ...) \ + BT_LOG_WRITE_PRINTF(BT_LOG_FATAL, _BT_LOG_TAG, (_fmt), ##__VA_ARGS__) +# define BT_LOGF_MEM_STR_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM_CUR_LVL(BT_LOG_FATAL, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGF_MEM_STR(_mem_data, _mem_len, _msg) \ + BT_LOG_WRITE_MEM(BT_LOG_FATAL, _BT_LOG_TAG, (_mem_data), (_mem_len), (_msg)) +# define BT_LOGF_MEM_CUR_LVL(_cur_lvl, _mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF_CUR_LVL(BT_LOG_FATAL, (_cur_lvl), _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGF_MEM(_mem_data, _mem_len, _fmt, ...) \ + BT_LOG_WRITE_MEM_PRINTF(BT_LOG_FATAL, _BT_LOG_TAG, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__) +# define BT_LOGF_ERRNO_STR_CUR_LVL(_cur_lvl, _init_msg, _msg) \ + BT_LOG_WRITE_ERRNO_CUR_LVL(BT_LOG_FATAL, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGF_ERRNO_STR(_init_msg, _msg) \ + BT_LOG_WRITE_ERRNO(BT_LOG_FATAL, _BT_LOG_TAG, (_init_msg), (_msg)) +# define BT_LOGF_ERRNO_CUR_LVL(_cur_lvl, _init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF_CUR_LVL(BT_LOG_FATAL, (_cur_lvl), _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) +# define BT_LOGF_ERRNO(_init_msg, _fmt, ...) \ + BT_LOG_WRITE_ERRNO_PRINTF(BT_LOG_FATAL, _BT_LOG_TAG, (_init_msg), (_fmt), ##__VA_ARGS__) #else - #define BT_LOGF(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGF_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGF_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGF_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGF_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) -#endif - -#define BT_LOGT_STR(s) BT_LOGT("%s", (s)) -#define BT_LOGD_STR(s) BT_LOGD("%s", (s)) -#define BT_LOGI_STR(s) BT_LOGI("%s", (s)) -#define BT_LOGW_STR(s) BT_LOGW("%s", (s)) -#define BT_LOGE_STR(s) BT_LOGE("%s", (s)) -#define BT_LOGF_STR(s) BT_LOGF("%s", (s)) - -#ifdef __cplusplus -extern "C" { -#endif - -/* Output to standard error stream. Library uses it by default, though in few - * cases it could be necessary to specify it explicitly. For example, when - * bt_log library is compiled with BT_LOG_EXTERN_GLOBAL_OUTPUT, application must - * define and initialize global output variable: - * - * BT_LOG_DEFINE_GLOBAL_OUTPUT = {BT_LOG_OUT_STDERR}; - * - * Another example is when using custom output, stderr could be used as a - * fallback when custom output facility failed to initialize: - * - * bt_log_set_output_v(BT_LOG_OUT_STDERR); - */ -enum { BT_LOG_OUT_STDERR_MASK = BT_LOG_PUT_STD }; - -void bt_log_out_stderr_callback(const bt_log_message *const msg, void *arg); -#define BT_LOG_OUT_STDERR BT_LOG_OUT_STDERR_MASK, 0, bt_log_out_stderr_callback - -/* Predefined spec for stderr. Uses global format options (BT_LOG_GLOBAL_FORMAT) - * and BT_LOG_OUT_STDERR. Could be used to force output to stderr for a - * particular message. Example: - * - * f = fopen("foo.log", "w"); - * if (!f) - * BT_LOGE_AUX(BT_LOG_STDERR, "Failed to open log file"); - */ -#define BT_LOG_STDERR (&_bt_log_stderr_spec) - -/* - * Returns the equivalent letter of the log level `level`. - * - * `level` must be a valid log level. - */ -static inline -char bt_log_get_letter_from_level(int level) -{ - char letter; - - switch (level) { - case BT_LOG_TRACE: - letter = 'T'; - break; - case BT_LOG_DEBUG: - letter = 'D'; - break; - case BT_LOG_INFO: - letter = 'I'; - break; - case BT_LOG_WARNING: - letter = 'W'; - break; - case BT_LOG_ERROR: - letter = 'E'; - break; - case BT_LOG_FATAL: - letter = 'F'; - break; - case BT_LOG_NONE: - letter = 'N'; - break; - default: - abort(); - } - - return letter; -} - -/* - * Returns the log level for the string `str`, or -1 if `str` is not a - * valid log level string. - */ -static inline -int bt_log_get_level_from_string(const char *str) -{ - int level = -1; - - BT_ASSERT(str); - - if (strcmp(str, "TRACE") == 0 || - strcmp(str, "T") == 0) { - level = BT_LOG_TRACE; - } else if (strcmp(str, "DEBUG") == 0 || - strcmp(str, "D") == 0) { - level = BT_LOG_DEBUG; - } else if (strcmp(str, "INFO") == 0 || - strcmp(str, "I") == 0) { - level = BT_LOG_INFO; - } else if (strcmp(str, "WARN") == 0 || - strcmp(str, "WARNING") == 0 || - strcmp(str, "W") == 0) { - level = BT_LOG_WARNING; - } else if (strcmp(str, "ERROR") == 0 || - strcmp(str, "E") == 0) { - level = BT_LOG_ERROR; - } else if (strcmp(str, "FATAL") == 0 || - strcmp(str, "F") == 0) { - level = BT_LOG_FATAL; - } else if (strcmp(str, "NONE") == 0 || - strcmp(str, "N") == 0) { - level = BT_LOG_NONE; - } else { - /* FIXME: Should we warn here? How? */ - } - - return level; -} +# define BT_LOGF_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_MEM_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_MEM_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_MEM_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_ERRNO_STR_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_ERRNO_STR(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_ERRNO_CUR_LVL(...) _BT_LOG_UNUSED(__VA_ARGS__) +# define BT_LOGF_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) +#endif /* BT_LOG_ENABLED_FATAL */ /* - * Returns the log level for the letter `letter`, or -1 if `letter` is - * not a valid log level string. + * Tell the world that `log.h` was included without having to rely on + * the specific include guard. */ -static inline -int bt_log_get_level_from_letter(char letter) -{ - char str[] = {letter, '\0'}; - - return bt_log_get_level_from_string(str); -} - -static inline -int bt_log_get_level_from_env(const char *var) -{ - const char *varval = getenv(var); - int level = BT_LOG_NONE; - - if (!varval) { - goto end; - } - - level = bt_log_get_level_from_string(varval); - if (level < 0) { - /* FIXME: Should we warn here? How? */ - level = BT_LOG_NONE; - } - -end: - return level; -} - -#define BT_LOG_LEVEL_EXTERN_SYMBOL(_level_sym) \ - extern int _level_sym - -#define BT_LOG_INIT_LOG_LEVEL(_level_sym, _env_var) \ - int _level_sym = BT_LOG_NONE; \ - static \ - void __attribute__((constructor)) _bt_log_level_ctor(void) \ - { \ - _level_sym = bt_log_get_level_from_env(_env_var); \ - } - #define BT_LOG_SUPPORTED -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_LOGGING_INTERNAL_H */ +#endif /* BABELTRACE_LOGGING_LOG_H */