2 * This is zf_log.h, modified with Babeltrace prefixes.
3 * See <https://github.com/wonder-mice/zf_log/>.
4 * See logging/LICENSE in the Babeltrace source tree.
9 #ifndef BABELTRACE_LOGGING_INTERNAL_H
10 #define BABELTRACE_LOGGING_INTERNAL_H
16 #include <babeltrace2/babeltrace.h>
18 #include "common/macros.h"
19 #include "common/assert.h"
21 /* To detect incompatible changes you can define BT_LOG_VERSION_REQUIRED to be
22 * the current value of BT_LOG_VERSION before including this file (or via
23 * compiler command line):
25 * #define BT_LOG_VERSION_REQUIRED 4
26 * #include "logging.h"
28 * Compilation will fail when included file has different version.
30 #define BT_LOG_VERSION 4
31 #if defined(BT_LOG_VERSION_REQUIRED)
32 #if BT_LOG_VERSION_REQUIRED != BT_LOG_VERSION
33 #error different bt_log version required
37 /* Log level guideline:
38 * - BT_LOG_FATAL - happened something impossible and absolutely unexpected.
39 * Process can't continue and must be terminated.
40 * Example: division by zero, unexpected modifications from other thread.
41 * - BT_LOG_ERROR - happened something possible, but highly unexpected. The
42 * process is able to recover and continue execution.
43 * Example: out of memory (could also be FATAL if not handled properly).
44 * - BT_LOG_WARNING - happened something that *usually* should not happen and
45 * significantly changes application behavior for some period of time.
46 * Example: configuration file not found, auth error.
47 * - BT_LOG_INFO - happened significant life cycle event or major state
49 * Example: app started, user logged in.
50 * - BT_LOG_DEBUG - minimal set of events that could help to reconstruct the
51 * execution path. Usually disabled in release builds.
52 * - BT_LOG_TRACE - all other events. Usually disabled in release builds.
54 * *Ideally*, log file of debugged, well tested, production ready application
55 * should be empty or very small. Choosing a right log level is as important as
56 * providing short and self descriptive log message.
58 #define BT_LOG_TRACE BT_LOGGING_LEVEL_TRACE
59 #define BT_LOG_DEBUG BT_LOGGING_LEVEL_DEBUG
60 #define BT_LOG_INFO BT_LOGGING_LEVEL_INFO
61 #define BT_LOG_WARNING BT_LOGGING_LEVEL_WARNING
62 #define BT_LOG_ERROR BT_LOGGING_LEVEL_ERROR
63 #define BT_LOG_FATAL BT_LOGGING_LEVEL_FATAL
64 #define BT_LOG_NONE BT_LOGGING_LEVEL_NONE
66 /* "Current" log level is a compile time check and has no runtime overhead. Log
67 * level that is below current log level it said to be "disabled".
68 * Otherwise, it's "enabled". Log messages that are disabled has no
69 * runtime overhead - they are converted to no-op by preprocessor and
70 * then eliminated by compiler. Current log level is configured per
71 * compilation module (.c/.cpp/.m file) by defining BT_LOG_DEF_LEVEL or
72 * BT_MINIMAL_LOG_LEVEL. BT_MINIMAL_LOG_LEVEL has higer priority and
73 * when defined overrides value provided by BT_LOG_DEF_LEVEL.
75 * Common practice is to define default current log level with BT_LOG_DEF_LEVEL
76 * in build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire
79 * CC_ARGS := -DBT_LOG_DEF_LEVEL=BT_LOG_INFO
81 * And when necessary to override it with BT_MINIMAL_LOG_LEVEL in .c/.cpp/.m files
82 * before including bt_log.h:
84 * #define BT_MINIMAL_LOG_LEVEL BT_LOG_TRACE
85 * #include "logging.h"
87 * If both BT_LOG_DEF_LEVEL and BT_MINIMAL_LOG_LEVEL are undefined, then
88 * BT_LOG_INFO will be used for release builds (BT_DEBUG_MODE is NOT
89 * defined) and BT_LOG_DEBUG otherwise (BT_DEBUG_MODE is defined).
91 #if defined(BT_MINIMAL_LOG_LEVEL)
92 #define _BT_MINIMAL_LOG_LEVEL BT_MINIMAL_LOG_LEVEL
93 #elif defined(BT_LOG_DEF_LEVEL)
94 #define _BT_MINIMAL_LOG_LEVEL BT_LOG_DEF_LEVEL
97 #define _BT_MINIMAL_LOG_LEVEL BT_LOG_DEBUG
99 #define _BT_MINIMAL_LOG_LEVEL BT_LOG_INFO
103 /* "Output" log level is a runtime check. When log level is below output log
104 * level it said to be "turned off" (or just "off" for short). Otherwise
105 * it's "turned on" (or just "on"). Log levels that were "disabled" (see
106 * BT_MINIMAL_LOG_LEVEL and BT_LOG_DEF_LEVEL) can't be "turned on", but
107 * "enabled" log levels could be "turned off". Only messages with log
108 * level which is "turned on" will reach output facility. All other
109 * messages will be ignored (and their arguments will not be evaluated).
110 * Output log level is a global property and configured per process
111 * using bt_log_set_output_level() function which can be called at any
114 * Though in some cases it could be useful to configure output log level per
115 * compilation module or per library. There are two ways to achieve that:
116 * - Define BT_LOG_OUTPUT_LEVEL to expresion that evaluates to desired output
118 * - Copy bt_log.h and bt_log.c files into your library and build it with
119 * BT_LOG_LIBRARY_PREFIX defined to library specific prefix. See
120 * BT_LOG_LIBRARY_PREFIX for more details.
122 * When defined, BT_LOG_OUTPUT_LEVEL must evaluate to integral value
123 * that corresponds to desired output log level. Use it only when
124 * compilation module is required to have output log level which is
125 * different from global output log level set by
126 * bt_log_set_output_level() function. For other cases, consider
127 * defining BT_MINIMAL_LOG_LEVEL or using bt_log_set_output_level()
132 * #define BT_LOG_OUTPUT_LEVEL g_module_log_level
133 * #include "logging.h"
134 * static int g_module_log_level = BT_LOG_INFO;
135 * static void foo() {
136 * BT_LOGI("Will check g_module_log_level for output log level");
138 * void debug_log(bool on) {
139 * g_module_log_level = on? BT_LOG_DEBUG: BT_LOG_INFO;
142 * Note on performance. This expression will be evaluated each time
143 * message is logged (except when message log level is "disabled" - see
144 * BT_MINIMAL_LOG_LEVEL for details). Keep this expression as simple as
145 * possible, otherwise it will not only add runtime overhead, but also
146 * will increase size of call site (which will result in larger
147 * executable). The prefered way is to use integer variable (as in
148 * example above). If structure must be used, log_level field must be
149 * the first field in this structure:
151 * #define BT_LOG_OUTPUT_LEVEL (g_config.log_level)
152 * #include "logging.h"
155 * unsigned other_field;
158 * static config g_config = {BT_LOG_INFO, 0, ...};
160 * This allows compiler to generate more compact load instruction (no need to
161 * specify offset since it's zero). Calling a function to get output log level
162 * is generaly a bad idea, since it will increase call site size and runtime
163 * overhead even further.
165 #if defined(BT_LOG_OUTPUT_LEVEL)
166 #define _BT_LOG_OUTPUT_LEVEL BT_LOG_OUTPUT_LEVEL
169 * We disallow this to make sure Babeltrace modules always
170 * have their own local log level.
172 #error No log level symbol specified: please define BT_LOG_OUTPUT_LEVEL before including this header.
175 /* "Tag" is a compound string that could be associated with a log message. It
176 * consists of tag prefix and tag (both are optional).
178 * Tag prefix is a global property and configured per process using
179 * bt_log_set_tag_prefix() function. Tag prefix identifies context in which
180 * component or module is running (e.g. process name). For example, the same
181 * library could be used in both client and server processes that work on the
182 * same machine. Tag prefix could be used to easily distinguish between them.
183 * For more details about tag prefix see bt_log_set_tag_prefix() function. Tag
186 * Tag identifies component or module. It is configured per compilation module
187 * (.c/.cpp/.m file) by defining BT_LOG_TAG or BT_LOG_DEF_TAG. BT_LOG_TAG has
188 * higer priority and when defined overrides value provided by BT_LOG_DEF_TAG.
189 * When defined, value must evaluate to (const char *), so for strings double
190 * quotes must be used.
192 * Default tag could be defined with BT_LOG_DEF_TAG in build script (e.g.
193 * Makefile, CMakeLists.txt, gyp, etc.) for the entire project or target:
195 * CC_ARGS := -DBT_LOG_DEF_TAG=\"MISC\"
197 * And when necessary could be overriden with BT_LOG_TAG in .c/.cpp/.m files
198 * before including bt_log.h:
200 * #define BT_LOG_TAG "MAIN"
201 * #include "logging.h"
203 * If both BT_LOG_DEF_TAG and BT_LOG_TAG are undefined no tag will be added to
204 * the log message (tag prefix still could be added though).
208 * 04-29 22:43:20.244 40059 1299 I hello.MAIN Number of arguments: 1
210 * | +- tag (e.g. module)
211 * +- tag prefix (e.g. process name)
213 #if defined(BT_LOG_TAG)
214 #define _BT_LOG_TAG BT_LOG_TAG
215 #elif defined(BT_LOG_DEF_TAG)
216 #define _BT_LOG_TAG BT_LOG_DEF_TAG
218 #define _BT_LOG_TAG 0
221 /* Source location is part of a log line that describes location (function or
222 * method name, file name and line number, e.g. "runloop@main.cpp:68") of a
223 * log statement that produced it.
224 * Source location formats are:
225 * - BT_LOG_SRCLOC_NONE - don't add source location to log line.
226 * - BT_LOG_SRCLOC_SHORT - add source location in short form (file and line
227 * number, e.g. "@main.cpp:68").
228 * - BT_LOG_SRCLOC_LONG - add source location in long form (function or method
229 * name, file and line number, e.g. "runloop@main.cpp:68").
231 #define BT_LOG_SRCLOC_NONE 0
232 #define BT_LOG_SRCLOC_SHORT 1
233 #define BT_LOG_SRCLOC_LONG 2
235 #define _BT_LOG_SRCLOC BT_LOG_SRCLOC_LONG
237 #if BT_LOG_SRCLOC_LONG == _BT_LOG_SRCLOC
238 #define _BT_LOG_SRCLOC_FUNCTION _BT_LOG_FUNCTION
240 #define _BT_LOG_SRCLOC_FUNCTION 0
243 /* Censoring provides conditional logging of secret information, also known as
244 * Personally Identifiable Information (PII) or Sensitive Personal Information
245 * (SPI). Censoring can be either enabled (BT_LOG_CENSORED) or disabled
246 * (BT_LOG_UNCENSORED). When censoring is enabled, log statements marked as
247 * "secrets" will be ignored and will have zero overhead (arguments also will
250 #define BT_LOG_CENSORED 1
251 #define BT_LOG_UNCENSORED 0
253 /* Censoring is configured per compilation module (.c/.cpp/.m file) by defining
254 * BT_LOG_DEF_CENSORING or BT_LOG_CENSORING. BT_LOG_CENSORING has higer priority
255 * and when defined overrides value provided by BT_LOG_DEF_CENSORING.
257 * Common practice is to define default censoring with BT_LOG_DEF_CENSORING in
258 * build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire
261 * CC_ARGS := -DBT_LOG_DEF_CENSORING=BT_LOG_CENSORED
263 * And when necessary to override it with BT_LOG_CENSORING in .c/.cpp/.m files
264 * before including bt_log.h (consider doing it only for debug purposes and be
265 * very careful not to push such temporary changes to source control):
267 * #define BT_LOG_CENSORING BT_LOG_UNCENSORED
268 * #include "logging.h"
270 * If both BT_LOG_DEF_CENSORING and BT_LOG_CENSORING are undefined, then
271 * BT_LOG_CENSORED will be used for release builds (BT_DEBUG_MODE is NOT
272 * defined) and BT_LOG_UNCENSORED otherwise (BT_DEBUG_MODE is defined).
274 #if defined(BT_LOG_CENSORING)
275 #define _BT_LOG_CENSORING BT_LOG_CENSORING
276 #elif defined(BT_LOG_DEF_CENSORING)
277 #define _BT_LOG_CENSORING BT_LOG_DEF_CENSORING
280 #define _BT_LOG_CENSORING BT_LOG_UNCENSORED
282 #define _BT_LOG_CENSORING BT_LOG_CENSORED
286 /* Check censoring at compile time. Evaluates to true when censoring is disabled
287 * (i.e. when secrets will be logged). For example:
291 * getSocialSecurityNumber(ssn);
292 * BT_LOGI("Customer ssn: %s", ssn);
295 * See BT_LOG_SECRET() macro for a more convenient way of guarding single log
298 #define BT_LOG_SECRETS (BT_LOG_UNCENSORED == _BT_LOG_CENSORING)
300 /* Static (compile-time) initialization support allows to configure logging
301 * before entering main() function. This mostly useful in C++ where functions
302 * and methods could be called during initialization of global objects. Those
303 * functions and methods could record log messages too and for that reason
304 * static initialization of logging configuration is customizable.
306 * Macros below allow to specify values to use for initial configuration:
307 * - BT_LOG_EXTERN_TAG_PREFIX - tag prefix (default: none)
308 * - BT_LOG_EXTERN_GLOBAL_FORMAT - global format options (default: see
309 * BT_LOG_MEM_WIDTH in bt_log.c)
310 * - BT_LOG_EXTERN_GLOBAL_OUTPUT - global output facility (default: stderr or
311 * platform specific, see BT_LOG_USE_XXX macros in bt_log.c)
312 * - BT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL - global output log level (default: 0 -
313 * all levals are "turned on")
315 * For example, in log_config.c:
317 * #include "logging.h"
318 * BT_LOG_DEFINE_TAG_PREFIX = "MyApp";
319 * BT_LOG_DEFINE_GLOBAL_FORMAT = {CUSTOM_MEM_WIDTH};
320 * BT_LOG_DEFINE_GLOBAL_OUTPUT = {BT_LOG_PUT_STD, custom_output_callback, 0};
321 * BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL = BT_LOG_INFO;
323 * However, to use any of those macros bt_log library must be compiled with
324 * following macros defined:
325 * - to use BT_LOG_DEFINE_TAG_PREFIX define BT_LOG_EXTERN_TAG_PREFIX
326 * - to use BT_LOG_DEFINE_GLOBAL_FORMAT define BT_LOG_EXTERN_GLOBAL_FORMAT
327 * - to use BT_LOG_DEFINE_GLOBAL_OUTPUT define BT_LOG_EXTERN_GLOBAL_OUTPUT
328 * - to use BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL define
329 * BT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL
331 * When bt_log library compiled with one of BT_LOG_EXTERN_XXX macros defined,
332 * corresponding BT_LOG_DEFINE_XXX macro MUST be used exactly once somewhere.
333 * Otherwise build will fail with link error (undefined symbol).
335 #define BT_LOG_DEFINE_TAG_PREFIX BT_HIDDEN const char *_bt_log_tag_prefix
336 #define BT_LOG_DEFINE_GLOBAL_FORMAT BT_HIDDEN bt_log_format _bt_log_global_format
337 #define BT_LOG_DEFINE_GLOBAL_OUTPUT BT_HIDDEN bt_log_output _bt_log_global_output
338 #define BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL BT_HIDDEN int _bt_log_global_output_lvl
340 /* Pointer to global format options. Direct modification is not allowed. Use
341 * bt_log_set_mem_width() instead. Could be used to initialize bt_log_spec
344 * const bt_log_output g_output = {BT_LOG_PUT_STD, output_callback, 0};
345 * const bt_log_spec g_spec = {BT_LOG_GLOBAL_FORMAT, &g_output};
346 * BT_LOGI_AUX(&g_spec, "Hello");
348 #define BT_LOG_GLOBAL_FORMAT ((const bt_log_format *)&_bt_log_global_format)
350 /* Pointer to global output variable. Direct modification is not allowed. Use
351 * bt_log_set_output_v() or bt_log_set_output_p() instead. Could be used to
352 * initialize bt_log_spec structure:
354 * const bt_log_format g_format = {40};
355 * const bt_log_spec g_spec = {g_format, BT_LOG_GLOBAL_OUTPUT};
356 * BT_LOGI_AUX(&g_spec, "Hello");
358 #define BT_LOG_GLOBAL_OUTPUT ((const bt_log_output *)&_bt_log_global_output)
360 /* When defined, all library symbols produced by linker will be prefixed with
361 * provided value. That allows to use bt_log library privately in another
362 * libraries without exposing bt_log symbols in their original form (to avoid
363 * possible conflicts with other libraries / components that also could use
364 * bt_log for logging). Value must be without quotes, for example:
366 * CC_ARGS := -DBT_LOG_LIBRARY_PREFIX=my_lib_
368 * Note, that in this mode BT_LOG_LIBRARY_PREFIX must be defined when building
369 * bt_log library AND it also must be defined to the same value when building
370 * a library that uses it. For example, consider fictional KittyHttp library
371 * that wants to use bt_log for logging. First approach that could be taken is
372 * to add bt_log.h and bt_log.c to the KittyHttp's source code tree directly.
373 * In that case it will be enough just to define BT_LOG_LIBRARY_PREFIX in
374 * KittyHttp's build script:
376 * // KittyHttp/CMakeLists.txt
377 * target_compile_definitions(KittyHttp PRIVATE
378 * "BT_LOG_LIBRARY_PREFIX=KittyHttp_")
380 * If KittyHttp doesn't want to include bt_log source code in its source tree
381 * and wants to build bt_log as a separate library than bt_log library must be
382 * built with BT_LOG_LIBRARY_PREFIX defined to KittyHttp_ AND KittyHttp library
383 * itself also needs to define BT_LOG_LIBRARY_PREFIX to KittyHttp_. It can do
384 * so either in its build script, as in example above, or by providing a
385 * wrapper header that KittyHttp library will need to use instead of bt_log.h:
387 * // KittyHttpLogging.h
388 * #define BT_LOG_LIBRARY_PREFIX KittyHttp_
389 * #include "logging.h"
391 * Regardless of the method chosen, the end result is that bt_log symbols will
392 * be prefixed with "KittyHttp_", so if a user of KittyHttp (say DogeBrowser)
393 * also uses bt_log for logging, they will not interferer with each other. Both
394 * will have their own log level, output facility, format options etc.
396 #ifdef BT_LOG_LIBRARY_PREFIX
397 #define _BT_LOG_DECOR__(prefix, name) prefix ## name
398 #define _BT_LOG_DECOR_(prefix, name) _BT_LOG_DECOR__(prefix, name)
399 #define _BT_LOG_DECOR(name) _BT_LOG_DECOR_(BT_LOG_LIBRARY_PREFIX, name)
401 #define bt_log_set_tag_prefix _BT_LOG_DECOR(bt_log_set_tag_prefix)
402 #define bt_log_set_mem_width _BT_LOG_DECOR(bt_log_set_mem_width)
403 #define bt_log_set_output_level _BT_LOG_DECOR(bt_log_set_output_level)
404 #define bt_log_set_output_v _BT_LOG_DECOR(bt_log_set_output_v)
405 #define bt_log_set_output_p _BT_LOG_DECOR(bt_log_set_output_p)
406 #define bt_log_out_stderr_callback _BT_LOG_DECOR(bt_log_out_stderr_callback)
407 #define _bt_log_tag_prefix _BT_LOG_DECOR(_bt_log_tag_prefix)
408 #define _bt_log_global_format _BT_LOG_DECOR(_bt_log_global_format)
409 #define _bt_log_global_output _BT_LOG_DECOR(_bt_log_global_output)
410 #define _bt_log_global_output_lvl _BT_LOG_DECOR(_bt_log_global_output_lvl)
411 #define _bt_log_write_d _BT_LOG_DECOR(_bt_log_write_d)
412 #define _bt_log_write_aux_d _BT_LOG_DECOR(_bt_log_write_aux_d)
413 #define _bt_log_write _BT_LOG_DECOR(_bt_log_write)
414 #define _bt_log_write_aux _BT_LOG_DECOR(_bt_log_write_aux)
415 #define _bt_log_write_mem_d _BT_LOG_DECOR(_bt_log_write_mem_d)
416 #define _bt_log_write_mem_aux_d _BT_LOG_DECOR(_bt_log_write_mem_aux_d)
417 #define _bt_log_write_mem _BT_LOG_DECOR(_bt_log_write_mem)
418 #define _bt_log_write_mem_aux _BT_LOG_DECOR(_bt_log_write_mem_aux)
419 #define _bt_log_stderr_spec _BT_LOG_DECOR(_bt_log_stderr_spec)
422 #if defined(__printflike)
423 #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \
424 __printflike(str_index, first_to_check)
425 #elif defined(__MINGW_PRINTF_FORMAT)
426 #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \
427 __attribute__((format(__MINGW_PRINTF_FORMAT, str_index, first_to_check)))
428 #elif defined(__GNUC__)
429 #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \
430 __attribute__((format(__printf__, str_index, first_to_check)))
432 #define _BT_LOG_PRINTFLIKE(str_index, first_to_check)
435 #if (defined(_WIN32) || defined(_WIN64)) && !defined(__GNUC__)
436 #define _BT_LOG_FUNCTION __FUNCTION__
438 #define _BT_LOG_FUNCTION __func__
441 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
442 #define _BT_LOG_INLINE __inline
443 #define _BT_LOG_IF(cond) \
444 __pragma(warning(push)) \
445 __pragma(warning(disable:4127)) \
447 __pragma(warning(pop))
448 #define _BT_LOG_WHILE(cond) \
449 __pragma(warning(push)) \
450 __pragma(warning(disable:4127)) \
452 __pragma(warning(pop))
454 #define _BT_LOG_INLINE inline
455 #define _BT_LOG_IF(cond) if(cond)
456 #define _BT_LOG_WHILE(cond) while(cond)
458 #define _BT_LOG_NEVER _BT_LOG_IF(0)
459 #define _BT_LOG_ONCE _BT_LOG_WHILE(0)
465 /* Set tag prefix. Prefix will be separated from the tag with dot ('.').
466 * Use 0 or empty string to disable (default). Common use is to set it to
467 * the process (or build target) name (e.g. to separate client and server
468 * processes). Function will NOT copy provided prefix string, but will store the
469 * pointer. Hence specified prefix string must remain valid. See
470 * BT_LOG_DEFINE_TAG_PREFIX for a way to set it before entering main() function.
471 * See BT_LOG_TAG for more information about tag and tag prefix.
473 void bt_log_set_tag_prefix(const char *const prefix
);
475 /* Set number of bytes per log line in memory (ASCII-HEX) output. Example:
477 * I hello.MAIN 4c6f72656d20697073756d20646f6c6f Lorem ipsum dolo
478 * |<- w bytes ->| |<- w chars ->|
480 * See BT_LOGF_MEM and BT_LOGF_MEM_AUX for more details.
482 void bt_log_set_mem_width(const unsigned w
);
484 /* Set "output" log level. See BT_MINIMAL_LOG_LEVEL and BT_LOG_OUTPUT_LEVEL for more
485 * info about log levels.
487 void bt_log_set_output_level(const int lvl
);
489 /* Put mask is a set of flags that define what fields will be added to each
490 * log message. Default value is BT_LOG_PUT_STD and other flags could be used to
491 * alter its behavior. See bt_log_set_output_v() for more details.
493 * Note about BT_LOG_PUT_SRC: it will be added only in debug builds
494 * (BT_DEBUG_MODE is defined).
498 BT_LOG_PUT_CTX
= 1 << 0, /* context (time, pid, tid, log level) */
499 BT_LOG_PUT_TAG
= 1 << 1, /* tag (including tag prefix) */
500 BT_LOG_PUT_SRC
= 1 << 2, /* source location (file, line, function) */
501 BT_LOG_PUT_MSG
= 1 << 3, /* message text (formatted string) */
502 BT_LOG_PUT_STD
= 0xffff, /* everything (default) */
505 typedef struct bt_log_message
507 int lvl
; /* Log level of the message */
508 const char *tag
; /* Associated tag (without tag prefix) */
509 char *buf
; /* Buffer start */
510 char *e
; /* Buffer end (last position where EOL with 0 could be written) */
511 char *p
; /* Buffer content end (append position) */
512 char *tag_b
; /* Prefixed tag start */
513 char *tag_e
; /* Prefixed tag end (if != tag_b, points to msg separator) */
514 char *msg_b
; /* Message start (expanded format string) */
518 /* Type of output callback function. It will be called for each log line allowed
519 * by both "current" and "output" log levels ("enabled" and "turned on").
520 * Callback function is allowed to modify content of the buffers pointed by the
521 * msg, but it's not allowed to modify any of msg fields. Buffer pointed by msg
522 * is UTF-8 encoded (no BOM mark).
524 typedef void (*bt_log_output_cb
)(const bt_log_message
*msg
, void *arg
);
526 /* Format options. For more details see bt_log_set_mem_width().
528 typedef struct bt_log_format
530 unsigned mem_width
; /* Bytes per line in memory (ASCII-HEX) dump */
536 typedef struct bt_log_output
538 unsigned mask
; /* What to put into log line buffer (see BT_LOG_PUT_XXX) */
539 void *arg
; /* User provided output callback argument */
540 bt_log_output_cb callback
; /* Output callback function */
544 /* Set output callback function.
546 * Mask allows to control what information will be added to the log line buffer
547 * before callback function is invoked. Default mask value is BT_LOG_PUT_STD.
549 void bt_log_set_output_v(const unsigned mask
, void *const arg
,
550 const bt_log_output_cb callback
);
551 static _BT_LOG_INLINE
void bt_log_set_output_p(const bt_log_output
*const output
)
553 bt_log_set_output_v(output
->mask
, output
->arg
, output
->callback
);
556 /* Used with _AUX macros and allows to override global format and output
557 * facility. Use BT_LOG_GLOBAL_FORMAT and BT_LOG_GLOBAL_OUTPUT for values from
558 * global configuration. Example:
560 * static const bt_log_output module_output = {
561 * BT_LOG_PUT_STD, 0, custom_output_callback
563 * static const bt_log_spec module_spec = {
564 * BT_LOG_GLOBAL_FORMAT, &module_output
566 * BT_LOGI_AUX(&module_spec, "Position: %ix%i", x, y);
568 * See BT_LOGF_AUX and BT_LOGF_MEM_AUX for details.
570 typedef struct bt_log_spec
572 const bt_log_format
*format
;
573 const bt_log_output
*output
;
581 /* Execute log statement if condition is true. Example:
583 * BT_LOG_IF(1 < 2, BT_LOGI("Log this"));
584 * BT_LOG_IF(1 > 2, BT_LOGI("Don't log this"));
586 * Keep in mind though, that if condition can't be evaluated at compile time,
587 * then it will be evaluated at run time. This will increase exectuable size
588 * and can have noticeable performance overhead. Try to limit conditions to
589 * expressions that can be evaluated at compile time.
591 #define BT_LOG_IF(cond, f) do { _BT_LOG_IF((cond)) { f; } } _BT_LOG_ONCE
593 /* Mark log statement as "secret". Log statements that are marked as secrets
594 * will NOT be executed when censoring is enabled (see BT_LOG_CENSORED).
597 * BT_LOG_SECRET(BT_LOGI("Credit card: %s", credit_card));
598 * BT_LOG_SECRET(BT_LOGD_MEM(cipher, cipher_sz, "Cipher bytes:"));
600 #define BT_LOG_SECRET(f) BT_LOG_IF(BT_LOG_SECRETS, f)
602 /* Check "current" log level at compile time (ignoring "output" log level).
603 * Evaluates to true when specified log level is enabled. For example:
605 * #if BT_LOG_ENABLED_DEBUG
606 * const char *const g_enum_strings[] = {
607 * "enum_value_0", "enum_value_1", "enum_value_2"
611 * #if BT_LOG_ENABLED_DEBUG
612 * BT_LOGD("enum value: %s", g_enum_strings[v]);
615 * See BT_MINIMAL_LOG_LEVEL for details.
617 #define BT_LOG_ENABLED(lvl) ((lvl) >= _BT_MINIMAL_LOG_LEVEL)
618 #define BT_LOG_ENABLED_TRACE BT_LOG_ENABLED(BT_LOG_TRACE)
619 #define BT_LOG_ENABLED_DEBUG BT_LOG_ENABLED(BT_LOG_DEBUG)
620 #define BT_LOG_ENABLED_INFO BT_LOG_ENABLED(BT_LOG_INFO)
621 #define BT_LOG_ENABLED_WARNING BT_LOG_ENABLED(BT_LOG_WARNING)
622 #define BT_LOG_ENABLED_ERROR BT_LOG_ENABLED(BT_LOG_ERROR)
623 #define BT_LOG_ENABLED_FATAL BT_LOG_ENABLED(BT_LOG_FATAL)
625 /* Check "output" log level at run time (taking into account "current" log
626 * level as well). Evaluates to true when specified log level is turned on AND
627 * enabled. For example:
629 * if (BT_LOG_ON_DEBUG)
632 * sha256(data_ptr, data_sz, hash);
633 * BT_LOGD("data: len=%u, sha256=%s", data_sz, hash);
636 * See BT_LOG_OUTPUT_LEVEL for details.
638 #define BT_LOG_ON_CUR_LVL(lvl, cur_lvl) \
639 (BT_LOG_ENABLED((lvl)) && (lvl) >= (cur_lvl))
640 #define BT_LOG_ON(lvl) \
641 (BT_LOG_ENABLED((lvl)) && (lvl) >= _BT_LOG_OUTPUT_LEVEL)
642 #define BT_LOG_ON_TRACE BT_LOG_ON(BT_LOG_TRACE)
643 #define BT_LOG_ON_DEBUG BT_LOG_ON(BT_LOG_DEBUG)
644 #define BT_LOG_ON_INFO BT_LOG_ON(BT_LOG_INFO)
645 #define BT_LOG_ON_WARNING BT_LOG_ON(BT_LOG_WARNING)
646 #define BT_LOG_ON_ERROR BT_LOG_ON(BT_LOG_ERROR)
647 #define BT_LOG_ON_FATAL BT_LOG_ON(BT_LOG_FATAL)
653 extern const char *_bt_log_tag_prefix
;
654 extern bt_log_format _bt_log_global_format
;
655 extern bt_log_output _bt_log_global_output
;
656 extern int _bt_log_global_output_lvl
;
657 extern const bt_log_spec _bt_log_stderr_spec
;
660 void _bt_log_write_d(
661 const char *const func
, const char *const file
, const unsigned line
,
662 const int lvl
, const char *const tag
,
663 const char *const fmt
, ...) _BT_LOG_PRINTFLIKE(6, 7);
666 void _bt_log_write_aux_d(
667 const char *const func
, const char *const file
, const unsigned line
,
668 const bt_log_spec
*const log
, const int lvl
, const char *const tag
,
669 const char *const fmt
, ...) _BT_LOG_PRINTFLIKE(7, 8);
673 const int lvl
, const char *const tag
,
674 const char *const fmt
, ...) _BT_LOG_PRINTFLIKE(3, 4);
677 void _bt_log_write_aux(
678 const bt_log_spec
*const log
, const int lvl
, const char *const tag
,
679 const char *const fmt
, ...) _BT_LOG_PRINTFLIKE(4, 5);
682 void _bt_log_write_mem_d(
683 const char *const func
, const char *const file
, const unsigned line
,
684 const int lvl
, const char *const tag
,
685 const void *const d
, const unsigned d_sz
,
686 const char *const fmt
, ...) _BT_LOG_PRINTFLIKE(8, 9);
689 void _bt_log_write_mem_aux_d(
690 const char *const func
, const char *const file
, const unsigned line
,
691 const bt_log_spec
*const log
, const int lvl
, const char *const tag
,
692 const void *const d
, const unsigned d_sz
,
693 const char *const fmt
, ...) _BT_LOG_PRINTFLIKE(9, 10);
696 void _bt_log_write_mem(
697 const int lvl
, const char *const tag
,
698 const void *const d
, const unsigned d_sz
,
699 const char *const fmt
, ...) _BT_LOG_PRINTFLIKE(5, 6);
702 void _bt_log_write_mem_aux(
703 const bt_log_spec
*const log
, const int lvl
, const char *const tag
,
704 const void *const d
, const unsigned d_sz
,
705 const char *const fmt
, ...) _BT_LOG_PRINTFLIKE(6, 7);
711 /* Message logging macros:
712 * - BT_LOGT("format string", args, ...)
713 * - BT_LOGD("format string", args, ...)
714 * - BT_LOGI("format string", args, ...)
715 * - BT_LOGW("format string", args, ...)
716 * - BT_LOGE("format string", args, ...)
717 * - BT_LOGF("format string", args, ...)
719 * Message and error string (errno) logging macros:
720 * - BT_LOGT_ERRNO("initial message", "format string", args, ...)
721 * - BT_LOGD_ERRNO("initial message", "format string", args, ...)
722 * - BT_LOGI_ERRNO("initial message", "format string", args, ...)
723 * - BT_LOGW_ERRNO("initial message", "format string", args, ...)
724 * - BT_LOGE_ERRNO("initial message", "format string", args, ...)
725 * - BT_LOGF_ERRNO("initial message", "format string", args, ...)
727 * Memory logging macros:
728 * - BT_LOGT_MEM(data_ptr, data_sz, "format string", args, ...)
729 * - BT_LOGD_MEM(data_ptr, data_sz, "format string", args, ...)
730 * - BT_LOGI_MEM(data_ptr, data_sz, "format string", args, ...)
731 * - BT_LOGW_MEM(data_ptr, data_sz, "format string", args, ...)
732 * - BT_LOGE_MEM(data_ptr, data_sz, "format string", args, ...)
733 * - BT_LOGF_MEM(data_ptr, data_sz, "format string", args, ...)
735 * Auxiliary logging macros:
736 * - BT_LOGT_AUX(&log_instance, "format string", args, ...)
737 * - BT_LOGD_AUX(&log_instance, "format string", args, ...)
738 * - BT_LOGI_AUX(&log_instance, "format string", args, ...)
739 * - BT_LOGW_AUX(&log_instance, "format string", args, ...)
740 * - BT_LOGE_AUX(&log_instance, "format string", args, ...)
741 * - BT_LOGF_AUX(&log_instance, "format string", args, ...)
743 * Auxiliary memory logging macros:
744 * - BT_LOGT_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
745 * - BT_LOGD_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
746 * - BT_LOGI_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
747 * - BT_LOGW_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
748 * - BT_LOGE_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
749 * - BT_LOGF_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
751 * Preformatted string logging macros:
752 * - BT_LOGT_STR("preformatted string");
753 * - BT_LOGD_STR("preformatted string");
754 * - BT_LOGI_STR("preformatted string");
755 * - BT_LOGW_STR("preformatted string");
756 * - BT_LOGE_STR("preformatted string");
757 * - BT_LOGF_STR("preformatted string");
759 * Explicit log level and tag macros:
760 * - BT_LOG_WRITE(level, tag, "format string", args, ...)
761 * - BT_LOG_WRITE_MEM(level, tag, data_ptr, data_sz, "format string", args, ...)
762 * - BT_LOG_WRITE_AUX(&log_instance, level, tag, "format string", args, ...)
763 * - BT_LOG_WRITE_MEM_AUX(&log_instance, level, tag, data_ptr, data_sz,
764 * "format string", args, ...)
766 * Explicit log level, current log level, and tag:
767 * - BT_LOG_WRITE_CUR_LVL(level, cur_level, tag, "format string", args, ...)
769 * Format string follows printf() conventions. Both data_ptr and data_sz could
770 * be 0. Tag can be 0 as well. Most compilers will verify that type of arguments
771 * match format specifiers in format string.
773 * Library assuming UTF-8 encoding for all strings (char *), including format
776 #if BT_LOG_SRCLOC_NONE == _BT_LOG_SRCLOC
777 #define BT_LOG_WRITE(lvl, tag, ...) \
779 if (BT_LOG_ON(lvl)) \
780 _bt_log_write(lvl, tag, __VA_ARGS__); \
782 #define BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, ...) \
784 if (BT_LOG_ON_CUR_LVL((lvl), (cur_lvl))) \
785 _bt_log_write(lvl, tag, __VA_ARGS__); \
787 #define BT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \
789 if (BT_LOG_ON(lvl)) \
790 _bt_log_write_mem(lvl, tag, d, d_sz, __VA_ARGS__); \
792 #define BT_LOG_WRITE_AUX(log, lvl, tag, ...) \
794 if (BT_LOG_ON(lvl)) \
795 _bt_log_write_aux(log, lvl, tag, __VA_ARGS__); \
797 #define BT_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \
799 if (BT_LOG_ON(lvl)) \
800 _bt_log_write_mem_aux(log, lvl, tag, d, d_sz, __VA_ARGS__); \
803 #define BT_LOG_WRITE(lvl, tag, ...) \
805 if (BT_LOG_ON(lvl)) \
806 _bt_log_write_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
807 lvl, tag, __VA_ARGS__); \
809 #define BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, ...) \
811 if (BT_LOG_ON_CUR_LVL((lvl), (cur_lvl))) \
812 _bt_log_write_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
813 lvl, tag, __VA_ARGS__); \
815 #define BT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \
817 if (BT_LOG_ON(lvl)) \
818 _bt_log_write_mem_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
819 lvl, tag, d, d_sz, __VA_ARGS__); \
821 #define BT_LOG_WRITE_AUX(log, lvl, tag, ...) \
823 if (BT_LOG_ON(lvl)) \
824 _bt_log_write_aux_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
825 log, lvl, tag, __VA_ARGS__); \
827 #define BT_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \
829 if (BT_LOG_ON(lvl)) \
830 _bt_log_write_mem_aux_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
831 log, lvl, tag, d, d_sz, __VA_ARGS__); \
835 #define BT_LOG_WRITE_ERRNO_CUR_LVL(lvl, cur_lvl, tag, _msg, _fmt, args...) \
837 const char *error_str; \
838 error_str = g_strerror(errno); \
839 BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, _msg ": %s" _fmt, error_str, ## args); \
842 #define BT_LOG_WRITE_ERRNO(lvl, tag, _msg, _fmt, args...) \
844 BT_LOG_WRITE_ERRNO_CUR_LVL(lvl, _BT_LOG_OUTPUT_LEVEL, tag, _msg, _fmt, ## args); \
847 static _BT_LOG_INLINE
void _bt_log_unused(const int dummy
, ...) {(void)dummy
;}
849 #define _BT_LOG_UNUSED(...) \
850 do { _BT_LOG_NEVER _bt_log_unused(0, __VA_ARGS__); } _BT_LOG_ONCE
852 #if BT_LOG_ENABLED_TRACE
853 #define BT_LOGT(...) \
854 BT_LOG_WRITE(BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__)
855 #define BT_LOGT_ERRNO(...) \
856 BT_LOG_WRITE_ERRNO(BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__)
857 #define BT_LOGT_AUX(log, ...) \
858 BT_LOG_WRITE_AUX(log, BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__)
859 #define BT_LOGT_MEM(d, d_sz, ...) \
860 BT_LOG_WRITE_MEM(BT_LOG_TRACE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
861 #define BT_LOGT_MEM_AUX(log, d, d_sz, ...) \
862 BT_LOG_WRITE_MEM(log, BT_LOG_TRACE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
864 #define BT_LOGT(...) _BT_LOG_UNUSED(__VA_ARGS__)
865 #define BT_LOGT_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
866 #define BT_LOGT_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
867 #define BT_LOGT_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
870 #if BT_LOG_ENABLED_DEBUG
871 #define BT_LOGD(...) \
872 BT_LOG_WRITE(BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__)
873 #define BT_LOGD_ERRNO(...) \
874 BT_LOG_WRITE_ERRNO(BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__)
875 #define BT_LOGD_AUX(log, ...) \
876 BT_LOG_WRITE_AUX(log, BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__)
877 #define BT_LOGD_MEM(d, d_sz, ...) \
878 BT_LOG_WRITE_MEM(BT_LOG_DEBUG, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
879 #define BT_LOGD_MEM_AUX(log, d, d_sz, ...) \
880 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_DEBUG, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
882 #define BT_LOGD(...) _BT_LOG_UNUSED(__VA_ARGS__)
883 #define BT_LOGD_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
884 #define BT_LOGD_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
885 #define BT_LOGD_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
888 #if BT_LOG_ENABLED_INFO
889 #define BT_LOGI(...) \
890 BT_LOG_WRITE(BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__)
891 #define BT_LOGI_ERRNO(...) \
892 BT_LOG_WRITE_ERRNO(BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__)
893 #define BT_LOGI_AUX(log, ...) \
894 BT_LOG_WRITE_AUX(log, BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__)
895 #define BT_LOGI_MEM(d, d_sz, ...) \
896 BT_LOG_WRITE_MEM(BT_LOG_INFO, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
897 #define BT_LOGI_MEM_AUX(log, d, d_sz, ...) \
898 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_INFO, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
900 #define BT_LOGI(...) _BT_LOG_UNUSED(__VA_ARGS__)
901 #define BT_LOGI_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
902 #define BT_LOGI_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
903 #define BT_LOGI_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
906 #if BT_LOG_ENABLED_WARNING
907 #define BT_LOGW(...) \
908 BT_LOG_WRITE(BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__)
909 #define BT_LOGW_ERRNO(...) \
910 BT_LOG_WRITE_ERRNO(BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__)
911 #define BT_LOGW_AUX(log, ...) \
912 BT_LOG_WRITE_AUX(log, BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__)
913 #define BT_LOGW_MEM(d, d_sz, ...) \
914 BT_LOG_WRITE_MEM(BT_LOG_WARNING, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
915 #define BT_LOGW_MEM_AUX(log, d, d_sz, ...) \
916 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_WARNING, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
918 #define BT_LOGW(...) _BT_LOG_UNUSED(__VA_ARGS__)
919 #define BT_LOGW_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
920 #define BT_LOGW_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
921 #define BT_LOGW_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
924 #if BT_LOG_ENABLED_ERROR
925 #define BT_LOGE(...) \
926 BT_LOG_WRITE(BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__)
927 #define BT_LOGE_ERRNO(...) \
928 BT_LOG_WRITE_ERRNO(BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__)
929 #define BT_LOGE_AUX(log, ...) \
930 BT_LOG_WRITE_AUX(log, BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__)
931 #define BT_LOGE_MEM(d, d_sz, ...) \
932 BT_LOG_WRITE_MEM(BT_LOG_ERROR, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
933 #define BT_LOGE_MEM_AUX(log, d, d_sz, ...) \
934 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_ERROR, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
936 #define BT_LOGE(...) _BT_LOG_UNUSED(__VA_ARGS__)
937 #define BT_LOGE_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
938 #define BT_LOGE_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
939 #define BT_LOGE_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
942 #if BT_LOG_ENABLED_FATAL
943 #define BT_LOGF(...) \
944 BT_LOG_WRITE(BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__)
945 #define BT_LOGF_ERRNO(...) \
946 BT_LOG_WRITE_ERRNO(BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__)
947 #define BT_LOGF_AUX(log, ...) \
948 BT_LOG_WRITE_AUX(log, BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__)
949 #define BT_LOGF_MEM(d, d_sz, ...) \
950 BT_LOG_WRITE_MEM(BT_LOG_FATAL, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
951 #define BT_LOGF_MEM_AUX(log, d, d_sz, ...) \
952 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_FATAL, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
954 #define BT_LOGF(...) _BT_LOG_UNUSED(__VA_ARGS__)
955 #define BT_LOGF_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
956 #define BT_LOGF_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
957 #define BT_LOGF_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
960 #define BT_LOGT_STR(s) BT_LOGT("%s", (s))
961 #define BT_LOGD_STR(s) BT_LOGD("%s", (s))
962 #define BT_LOGI_STR(s) BT_LOGI("%s", (s))
963 #define BT_LOGW_STR(s) BT_LOGW("%s", (s))
964 #define BT_LOGE_STR(s) BT_LOGE("%s", (s))
965 #define BT_LOGF_STR(s) BT_LOGF("%s", (s))
971 /* Output to standard error stream. Library uses it by default, though in few
972 * cases it could be necessary to specify it explicitly. For example, when
973 * bt_log library is compiled with BT_LOG_EXTERN_GLOBAL_OUTPUT, application must
974 * define and initialize global output variable:
976 * BT_LOG_DEFINE_GLOBAL_OUTPUT = {BT_LOG_OUT_STDERR};
978 * Another example is when using custom output, stderr could be used as a
979 * fallback when custom output facility failed to initialize:
981 * bt_log_set_output_v(BT_LOG_OUT_STDERR);
983 enum { BT_LOG_OUT_STDERR_MASK
= BT_LOG_PUT_STD
};
986 void bt_log_out_stderr_callback(const bt_log_message
*const msg
, void *arg
);
987 #define BT_LOG_OUT_STDERR BT_LOG_OUT_STDERR_MASK, 0, bt_log_out_stderr_callback
989 /* Predefined spec for stderr. Uses global format options (BT_LOG_GLOBAL_FORMAT)
990 * and BT_LOG_OUT_STDERR. Could be used to force output to stderr for a
991 * particular message. Example:
993 * f = fopen("foo.log", "w");
995 * BT_LOGE_AUX(BT_LOG_STDERR, "Failed to open log file");
997 #define BT_LOG_STDERR (&_bt_log_stderr_spec)
1000 * Returns the equivalent letter of the log level `level`.
1002 * `level` must be a valid log level.
1005 char bt_log_get_letter_from_level(int level
)
1019 case BT_LOG_WARNING
:
1039 * Returns the log level for the string `str`, or -1 if `str` is not a
1040 * valid log level string.
1043 int bt_log_get_level_from_string(const char *str
)
1049 if (strcmp(str
, "TRACE") == 0 ||
1050 strcmp(str
, "T") == 0) {
1051 level
= BT_LOG_TRACE
;
1052 } else if (strcmp(str
, "DEBUG") == 0 ||
1053 strcmp(str
, "D") == 0) {
1054 level
= BT_LOG_DEBUG
;
1055 } else if (strcmp(str
, "INFO") == 0 ||
1056 strcmp(str
, "I") == 0) {
1057 level
= BT_LOG_INFO
;
1058 } else if (strcmp(str
, "WARN") == 0 ||
1059 strcmp(str
, "WARNING") == 0 ||
1060 strcmp(str
, "W") == 0) {
1061 level
= BT_LOG_WARNING
;
1062 } else if (strcmp(str
, "ERROR") == 0 ||
1063 strcmp(str
, "E") == 0) {
1064 level
= BT_LOG_ERROR
;
1065 } else if (strcmp(str
, "FATAL") == 0 ||
1066 strcmp(str
, "F") == 0) {
1067 level
= BT_LOG_FATAL
;
1068 } else if (strcmp(str
, "NONE") == 0 ||
1069 strcmp(str
, "N") == 0) {
1070 level
= BT_LOG_NONE
;
1072 /* FIXME: Should we warn here? How? */
1079 * Returns the log level for the letter `letter`, or -1 if `letter` is
1080 * not a valid log level string.
1083 int bt_log_get_level_from_letter(char letter
)
1085 char str
[] = {letter
, '\0'};
1087 return bt_log_get_level_from_string(str
);
1091 int bt_log_get_level_from_env(const char *var
)
1093 const char *varval
= getenv(var
);
1094 int level
= BT_LOG_NONE
;
1100 level
= bt_log_get_level_from_string(varval
);
1102 /* FIXME: Should we warn here? How? */
1103 level
= BT_LOG_NONE
;
1110 #define BT_LOG_LEVEL_EXTERN_SYMBOL(_level_sym) \
1111 extern int _level_sym
1113 #define BT_LOG_INIT_LOG_LEVEL(_level_sym, _env_var) \
1114 BT_HIDDEN int _level_sym = BT_LOG_NONE; \
1116 void __attribute__((constructor)) _bt_log_level_ctor(void) \
1118 _level_sym = bt_log_get_level_from_env(_env_var); \
1121 #define BT_LOG_SUPPORTED
1127 #endif /* BABELTRACE_LOGGING_INTERNAL_H */