logging: strip down and clean `log.h` and `log.c`
[babeltrace.git] / src / logging / log.h
index 89ac5fc7c54ca3e8fffb858fc1a816fec5762add..93c9d6ed1376e6726099a4c627b60d89f8703197 100644 (file)
  * SPDX-License-Identifier: MIT
  *
  * Copyright (c) 2016 wonder-mice
+ * Copyright (c) 2016-2023 Philippe Proulx <pproulx@efficios.com>
  *
- * This is zf_log.h, modified with Babeltrace prefixes.
- * See <https://github.com/wonder-mice/zf_log/>.
+ * This is very inspired by zf_log.h (see
+ * <https://github.com/wonder-mice/zf_log/>), 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 <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <glib.h>
 #include <babeltrace2/babeltrace.h>
 
-/* Access private __BT_LOGGING_LEVEL_* macros. */
-#define __BT_IN_BABELTRACE_H
-#include <babeltrace2/logging-defs.h>
-#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 */
This page took 0.036421 seconds and 4 git commands to generate.