lib: force user to include `<babeltrace2/babeltrace.h>`
[babeltrace.git] / src / logging / log.h
CommitLineData
beb0fb75
PP
1/*
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.
5 */
6
7#pragma once
8
9#ifndef BABELTRACE_LOGGING_INTERNAL_H
10#define BABELTRACE_LOGGING_INTERNAL_H
11
91d81473 12#include <errno.h>
373c938b
PP
13#include <stdlib.h>
14#include <stdio.h>
91d81473 15#include <string.h>
4fa90f32
PP
16#include <babeltrace2/babeltrace.h>
17
91d81473 18#include "common/macros.h"
6b06582d 19#include "common/assert.h"
beb0fb75
PP
20
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):
24 *
25 * #define BT_LOG_VERSION_REQUIRED 4
578e048b 26 * #include "logging.h"
beb0fb75
PP
27 *
28 * Compilation will fail when included file has different version.
29 */
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
34 #endif
35#endif
36
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).
770538dd 44 * - BT_LOG_WARNING - happened something that *usually* should not happen and
beb0fb75
PP
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
48 * transition.
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.
ef267d12 52 * - BT_LOG_TRACE - all other events. Usually disabled in release builds.
beb0fb75
PP
53 *
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.
57 */
ef267d12 58#define BT_LOG_TRACE BT_LOGGING_LEVEL_TRACE
beb0fb75
PP
59#define BT_LOG_DEBUG BT_LOGGING_LEVEL_DEBUG
60#define BT_LOG_INFO BT_LOGGING_LEVEL_INFO
770538dd 61#define BT_LOG_WARNING BT_LOGGING_LEVEL_WARNING
beb0fb75
PP
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
65
66/* "Current" log level is a compile time check and has no runtime overhead. Log
510400a9
PP
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.
beb0fb75
PP
74 *
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
77 * project or target:
78 *
79 * CC_ARGS := -DBT_LOG_DEF_LEVEL=BT_LOG_INFO
80 *
510400a9 81 * And when necessary to override it with BT_MINIMAL_LOG_LEVEL in .c/.cpp/.m files
beb0fb75
PP
82 * before including bt_log.h:
83 *
510400a9 84 * #define BT_MINIMAL_LOG_LEVEL BT_LOG_TRACE
578e048b 85 * #include "logging.h"
beb0fb75 86 *
510400a9 87 * If both BT_LOG_DEF_LEVEL and BT_MINIMAL_LOG_LEVEL are undefined, then
3f3b1761
PP
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).
beb0fb75 90 */
510400a9
PP
91#if defined(BT_MINIMAL_LOG_LEVEL)
92 #define _BT_MINIMAL_LOG_LEVEL BT_MINIMAL_LOG_LEVEL
beb0fb75 93#elif defined(BT_LOG_DEF_LEVEL)
510400a9 94 #define _BT_MINIMAL_LOG_LEVEL BT_LOG_DEF_LEVEL
beb0fb75 95#else
3f3b1761 96 #ifdef BT_DEBUG_MODE
510400a9 97 #define _BT_MINIMAL_LOG_LEVEL BT_LOG_DEBUG
3f3b1761 98 #else
510400a9 99 #define _BT_MINIMAL_LOG_LEVEL BT_LOG_INFO
beb0fb75
PP
100 #endif
101#endif
102
103/* "Output" log level is a runtime check. When log level is below output log
510400a9
PP
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
112 * time.
beb0fb75
PP
113 *
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
117 * log level.
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.
121 *
510400a9
PP
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()
128 * function.
beb0fb75
PP
129 *
130 * Example:
131 *
132 * #define BT_LOG_OUTPUT_LEVEL g_module_log_level
578e048b 133 * #include "logging.h"
beb0fb75
PP
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");
137 * }
138 * void debug_log(bool on) {
139 * g_module_log_level = on? BT_LOG_DEBUG: BT_LOG_INFO;
140 * }
141 *
510400a9
PP
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:
beb0fb75
PP
150 *
151 * #define BT_LOG_OUTPUT_LEVEL (g_config.log_level)
578e048b 152 * #include "logging.h"
beb0fb75
PP
153 * struct config {
154 * int log_level;
155 * unsigned other_field;
156 * [...]
157 * };
158 * static config g_config = {BT_LOG_INFO, 0, ...};
159 *
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.
164 */
165#if defined(BT_LOG_OUTPUT_LEVEL)
166 #define _BT_LOG_OUTPUT_LEVEL BT_LOG_OUTPUT_LEVEL
167#else
00a52b39
PP
168 /*
169 * We disallow this to make sure Babeltrace modules always
170 * have their own local log level.
171 */
172 #error No log level symbol specified: please define BT_LOG_OUTPUT_LEVEL before including this header.
beb0fb75
PP
173#endif
174
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).
177 *
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
184 * prefix
185 *
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.
191 *
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:
194 *
195 * CC_ARGS := -DBT_LOG_DEF_TAG=\"MISC\"
196 *
197 * And when necessary could be overriden with BT_LOG_TAG in .c/.cpp/.m files
198 * before including bt_log.h:
199 *
200 * #define BT_LOG_TAG "MAIN"
578e048b 201 * #include "logging.h"
beb0fb75
PP
202 *
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).
205 *
206 * Output example:
207 *
208 * 04-29 22:43:20.244 40059 1299 I hello.MAIN Number of arguments: 1
209 * | |
210 * | +- tag (e.g. module)
211 * +- tag prefix (e.g. process name)
212 */
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
217#else
218 #define _BT_LOG_TAG 0
219#endif
220
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").
230 */
231#define BT_LOG_SRCLOC_NONE 0
232#define BT_LOG_SRCLOC_SHORT 1
233#define BT_LOG_SRCLOC_LONG 2
234
235/* Source location format is configured per compilation module (.c/.cpp/.m
236 * file) by defining BT_LOG_DEF_SRCLOC or BT_LOG_SRCLOC. BT_LOG_SRCLOC has
237 * higer priority and when defined overrides value provided by
238 * BT_LOG_DEF_SRCLOC.
239 *
240 * Common practice is to define default format with BT_LOG_DEF_SRCLOC in
241 * build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire
242 * project or target:
243 *
244 * CC_ARGS := -DBT_LOG_DEF_SRCLOC=BT_LOG_SRCLOC_LONG
245 *
246 * And when necessary to override it with BT_LOG_SRCLOC in .c/.cpp/.m files
247 * before including bt_log.h:
248 *
249 * #define BT_LOG_SRCLOC BT_LOG_SRCLOC_NONE
578e048b 250 * #include "logging.h"
beb0fb75
PP
251 *
252 * If both BT_LOG_DEF_SRCLOC and BT_LOG_SRCLOC are undefined, then
3f3b1761
PP
253 * BT_LOG_SRCLOC_NONE will be used for release builds (BT_DEBUG_MODE is
254 * NOT defined) and BT_LOG_SRCLOC_LONG otherwise (BT_DEBUG_MODE is
255 * defined).
beb0fb75
PP
256 */
257#if defined(BT_LOG_SRCLOC)
258 #define _BT_LOG_SRCLOC BT_LOG_SRCLOC
259#elif defined(BT_LOG_DEF_SRCLOC)
260 #define _BT_LOG_SRCLOC BT_LOG_DEF_SRCLOC
261#else
3f3b1761 262 #ifdef BT_DEBUG_MODE
beb0fb75 263 #define _BT_LOG_SRCLOC BT_LOG_SRCLOC_LONG
3f3b1761
PP
264 #else
265 #define _BT_LOG_SRCLOC BT_LOG_SRCLOC_NONE
beb0fb75
PP
266 #endif
267#endif
268#if BT_LOG_SRCLOC_LONG == _BT_LOG_SRCLOC
269 #define _BT_LOG_SRCLOC_FUNCTION _BT_LOG_FUNCTION
270#else
271 #define _BT_LOG_SRCLOC_FUNCTION 0
272#endif
273
274/* Censoring provides conditional logging of secret information, also known as
275 * Personally Identifiable Information (PII) or Sensitive Personal Information
276 * (SPI). Censoring can be either enabled (BT_LOG_CENSORED) or disabled
277 * (BT_LOG_UNCENSORED). When censoring is enabled, log statements marked as
278 * "secrets" will be ignored and will have zero overhead (arguments also will
279 * not be evaluated).
280 */
281#define BT_LOG_CENSORED 1
282#define BT_LOG_UNCENSORED 0
283
284/* Censoring is configured per compilation module (.c/.cpp/.m file) by defining
285 * BT_LOG_DEF_CENSORING or BT_LOG_CENSORING. BT_LOG_CENSORING has higer priority
286 * and when defined overrides value provided by BT_LOG_DEF_CENSORING.
287 *
288 * Common practice is to define default censoring with BT_LOG_DEF_CENSORING in
289 * build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire
290 * project or target:
291 *
292 * CC_ARGS := -DBT_LOG_DEF_CENSORING=BT_LOG_CENSORED
293 *
294 * And when necessary to override it with BT_LOG_CENSORING in .c/.cpp/.m files
295 * before including bt_log.h (consider doing it only for debug purposes and be
296 * very careful not to push such temporary changes to source control):
297 *
298 * #define BT_LOG_CENSORING BT_LOG_UNCENSORED
578e048b 299 * #include "logging.h"
beb0fb75
PP
300 *
301 * If both BT_LOG_DEF_CENSORING and BT_LOG_CENSORING are undefined, then
3f3b1761
PP
302 * BT_LOG_CENSORED will be used for release builds (BT_DEBUG_MODE is NOT
303 * defined) and BT_LOG_UNCENSORED otherwise (BT_DEBUG_MODE is defined).
beb0fb75
PP
304 */
305#if defined(BT_LOG_CENSORING)
306 #define _BT_LOG_CENSORING BT_LOG_CENSORING
307#elif defined(BT_LOG_DEF_CENSORING)
308 #define _BT_LOG_CENSORING BT_LOG_DEF_CENSORING
309#else
3f3b1761 310 #ifdef BT_DEBUG_MODE
beb0fb75 311 #define _BT_LOG_CENSORING BT_LOG_UNCENSORED
3f3b1761
PP
312 #else
313 #define _BT_LOG_CENSORING BT_LOG_CENSORED
beb0fb75
PP
314 #endif
315#endif
316
317/* Check censoring at compile time. Evaluates to true when censoring is disabled
318 * (i.e. when secrets will be logged). For example:
319 *
320 * #if BT_LOG_SECRETS
321 * char ssn[16];
322 * getSocialSecurityNumber(ssn);
323 * BT_LOGI("Customer ssn: %s", ssn);
324 * #endif
325 *
326 * See BT_LOG_SECRET() macro for a more convenient way of guarding single log
327 * statement.
328 */
329#define BT_LOG_SECRETS (BT_LOG_UNCENSORED == _BT_LOG_CENSORING)
330
331/* Static (compile-time) initialization support allows to configure logging
332 * before entering main() function. This mostly useful in C++ where functions
333 * and methods could be called during initialization of global objects. Those
334 * functions and methods could record log messages too and for that reason
335 * static initialization of logging configuration is customizable.
336 *
337 * Macros below allow to specify values to use for initial configuration:
338 * - BT_LOG_EXTERN_TAG_PREFIX - tag prefix (default: none)
339 * - BT_LOG_EXTERN_GLOBAL_FORMAT - global format options (default: see
340 * BT_LOG_MEM_WIDTH in bt_log.c)
341 * - BT_LOG_EXTERN_GLOBAL_OUTPUT - global output facility (default: stderr or
342 * platform specific, see BT_LOG_USE_XXX macros in bt_log.c)
343 * - BT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL - global output log level (default: 0 -
344 * all levals are "turned on")
345 *
346 * For example, in log_config.c:
347 *
578e048b 348 * #include "logging.h"
beb0fb75
PP
349 * BT_LOG_DEFINE_TAG_PREFIX = "MyApp";
350 * BT_LOG_DEFINE_GLOBAL_FORMAT = {CUSTOM_MEM_WIDTH};
351 * BT_LOG_DEFINE_GLOBAL_OUTPUT = {BT_LOG_PUT_STD, custom_output_callback, 0};
352 * BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL = BT_LOG_INFO;
353 *
354 * However, to use any of those macros bt_log library must be compiled with
355 * following macros defined:
356 * - to use BT_LOG_DEFINE_TAG_PREFIX define BT_LOG_EXTERN_TAG_PREFIX
357 * - to use BT_LOG_DEFINE_GLOBAL_FORMAT define BT_LOG_EXTERN_GLOBAL_FORMAT
358 * - to use BT_LOG_DEFINE_GLOBAL_OUTPUT define BT_LOG_EXTERN_GLOBAL_OUTPUT
359 * - to use BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL define
360 * BT_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL
361 *
362 * When bt_log library compiled with one of BT_LOG_EXTERN_XXX macros defined,
363 * corresponding BT_LOG_DEFINE_XXX macro MUST be used exactly once somewhere.
364 * Otherwise build will fail with link error (undefined symbol).
365 */
4f1c7f2e
JG
366#define BT_LOG_DEFINE_TAG_PREFIX BT_HIDDEN const char *_bt_log_tag_prefix
367#define BT_LOG_DEFINE_GLOBAL_FORMAT BT_HIDDEN bt_log_format _bt_log_global_format
368#define BT_LOG_DEFINE_GLOBAL_OUTPUT BT_HIDDEN bt_log_output _bt_log_global_output
369#define BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL BT_HIDDEN int _bt_log_global_output_lvl
beb0fb75
PP
370
371/* Pointer to global format options. Direct modification is not allowed. Use
372 * bt_log_set_mem_width() instead. Could be used to initialize bt_log_spec
373 * structure:
374 *
375 * const bt_log_output g_output = {BT_LOG_PUT_STD, output_callback, 0};
376 * const bt_log_spec g_spec = {BT_LOG_GLOBAL_FORMAT, &g_output};
377 * BT_LOGI_AUX(&g_spec, "Hello");
378 */
379#define BT_LOG_GLOBAL_FORMAT ((const bt_log_format *)&_bt_log_global_format)
380
381/* Pointer to global output variable. Direct modification is not allowed. Use
382 * bt_log_set_output_v() or bt_log_set_output_p() instead. Could be used to
383 * initialize bt_log_spec structure:
384 *
385 * const bt_log_format g_format = {40};
386 * const bt_log_spec g_spec = {g_format, BT_LOG_GLOBAL_OUTPUT};
387 * BT_LOGI_AUX(&g_spec, "Hello");
388 */
389#define BT_LOG_GLOBAL_OUTPUT ((const bt_log_output *)&_bt_log_global_output)
390
391/* When defined, all library symbols produced by linker will be prefixed with
392 * provided value. That allows to use bt_log library privately in another
393 * libraries without exposing bt_log symbols in their original form (to avoid
394 * possible conflicts with other libraries / components that also could use
395 * bt_log for logging). Value must be without quotes, for example:
396 *
397 * CC_ARGS := -DBT_LOG_LIBRARY_PREFIX=my_lib_
398 *
399 * Note, that in this mode BT_LOG_LIBRARY_PREFIX must be defined when building
400 * bt_log library AND it also must be defined to the same value when building
401 * a library that uses it. For example, consider fictional KittyHttp library
402 * that wants to use bt_log for logging. First approach that could be taken is
403 * to add bt_log.h and bt_log.c to the KittyHttp's source code tree directly.
404 * In that case it will be enough just to define BT_LOG_LIBRARY_PREFIX in
405 * KittyHttp's build script:
406 *
407 * // KittyHttp/CMakeLists.txt
408 * target_compile_definitions(KittyHttp PRIVATE
409 * "BT_LOG_LIBRARY_PREFIX=KittyHttp_")
410 *
411 * If KittyHttp doesn't want to include bt_log source code in its source tree
412 * and wants to build bt_log as a separate library than bt_log library must be
413 * built with BT_LOG_LIBRARY_PREFIX defined to KittyHttp_ AND KittyHttp library
414 * itself also needs to define BT_LOG_LIBRARY_PREFIX to KittyHttp_. It can do
415 * so either in its build script, as in example above, or by providing a
416 * wrapper header that KittyHttp library will need to use instead of bt_log.h:
417 *
418 * // KittyHttpLogging.h
419 * #define BT_LOG_LIBRARY_PREFIX KittyHttp_
578e048b 420 * #include "logging.h"
beb0fb75
PP
421 *
422 * Regardless of the method chosen, the end result is that bt_log symbols will
423 * be prefixed with "KittyHttp_", so if a user of KittyHttp (say DogeBrowser)
424 * also uses bt_log for logging, they will not interferer with each other. Both
425 * will have their own log level, output facility, format options etc.
426 */
427#ifdef BT_LOG_LIBRARY_PREFIX
428 #define _BT_LOG_DECOR__(prefix, name) prefix ## name
429 #define _BT_LOG_DECOR_(prefix, name) _BT_LOG_DECOR__(prefix, name)
430 #define _BT_LOG_DECOR(name) _BT_LOG_DECOR_(BT_LOG_LIBRARY_PREFIX, name)
431
432 #define bt_log_set_tag_prefix _BT_LOG_DECOR(bt_log_set_tag_prefix)
433 #define bt_log_set_mem_width _BT_LOG_DECOR(bt_log_set_mem_width)
434 #define bt_log_set_output_level _BT_LOG_DECOR(bt_log_set_output_level)
435 #define bt_log_set_output_v _BT_LOG_DECOR(bt_log_set_output_v)
436 #define bt_log_set_output_p _BT_LOG_DECOR(bt_log_set_output_p)
437 #define bt_log_out_stderr_callback _BT_LOG_DECOR(bt_log_out_stderr_callback)
438 #define _bt_log_tag_prefix _BT_LOG_DECOR(_bt_log_tag_prefix)
439 #define _bt_log_global_format _BT_LOG_DECOR(_bt_log_global_format)
440 #define _bt_log_global_output _BT_LOG_DECOR(_bt_log_global_output)
441 #define _bt_log_global_output_lvl _BT_LOG_DECOR(_bt_log_global_output_lvl)
442 #define _bt_log_write_d _BT_LOG_DECOR(_bt_log_write_d)
443 #define _bt_log_write_aux_d _BT_LOG_DECOR(_bt_log_write_aux_d)
444 #define _bt_log_write _BT_LOG_DECOR(_bt_log_write)
445 #define _bt_log_write_aux _BT_LOG_DECOR(_bt_log_write_aux)
446 #define _bt_log_write_mem_d _BT_LOG_DECOR(_bt_log_write_mem_d)
447 #define _bt_log_write_mem_aux_d _BT_LOG_DECOR(_bt_log_write_mem_aux_d)
448 #define _bt_log_write_mem _BT_LOG_DECOR(_bt_log_write_mem)
449 #define _bt_log_write_mem_aux _BT_LOG_DECOR(_bt_log_write_mem_aux)
450 #define _bt_log_stderr_spec _BT_LOG_DECOR(_bt_log_stderr_spec)
451#endif
452
453#if defined(__printflike)
995dc21f
PP
454 #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \
455 __printflike(str_index, first_to_check)
0a0f7d69
MJ
456#elif defined(__MINGW_PRINTF_FORMAT)
457 #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \
458 __attribute__((format(__MINGW_PRINTF_FORMAT, str_index, first_to_check)))
995dc21f
PP
459#elif defined(__GNUC__)
460 #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \
461 __attribute__((format(__printf__, str_index, first_to_check)))
beb0fb75 462#else
995dc21f 463 #define _BT_LOG_PRINTFLIKE(str_index, first_to_check)
beb0fb75
PP
464#endif
465
466#if (defined(_WIN32) || defined(_WIN64)) && !defined(__GNUC__)
467 #define _BT_LOG_FUNCTION __FUNCTION__
468#else
469 #define _BT_LOG_FUNCTION __func__
470#endif
471
472#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
473 #define _BT_LOG_INLINE __inline
474 #define _BT_LOG_IF(cond) \
475 __pragma(warning(push)) \
476 __pragma(warning(disable:4127)) \
477 if(cond) \
478 __pragma(warning(pop))
479 #define _BT_LOG_WHILE(cond) \
480 __pragma(warning(push)) \
481 __pragma(warning(disable:4127)) \
482 while(cond) \
483 __pragma(warning(pop))
484#else
485 #define _BT_LOG_INLINE inline
486 #define _BT_LOG_IF(cond) if(cond)
487 #define _BT_LOG_WHILE(cond) while(cond)
488#endif
489#define _BT_LOG_NEVER _BT_LOG_IF(0)
490#define _BT_LOG_ONCE _BT_LOG_WHILE(0)
491
492#ifdef __cplusplus
493extern "C" {
494#endif
495
496/* Set tag prefix. Prefix will be separated from the tag with dot ('.').
497 * Use 0 or empty string to disable (default). Common use is to set it to
498 * the process (or build target) name (e.g. to separate client and server
499 * processes). Function will NOT copy provided prefix string, but will store the
500 * pointer. Hence specified prefix string must remain valid. See
501 * BT_LOG_DEFINE_TAG_PREFIX for a way to set it before entering main() function.
502 * See BT_LOG_TAG for more information about tag and tag prefix.
503 */
504void bt_log_set_tag_prefix(const char *const prefix);
505
506/* Set number of bytes per log line in memory (ASCII-HEX) output. Example:
507 *
508 * I hello.MAIN 4c6f72656d20697073756d20646f6c6f Lorem ipsum dolo
509 * |<- w bytes ->| |<- w chars ->|
510 *
511 * See BT_LOGF_MEM and BT_LOGF_MEM_AUX for more details.
512 */
513void bt_log_set_mem_width(const unsigned w);
514
510400a9 515/* Set "output" log level. See BT_MINIMAL_LOG_LEVEL and BT_LOG_OUTPUT_LEVEL for more
beb0fb75
PP
516 * info about log levels.
517 */
518void bt_log_set_output_level(const int lvl);
519
520/* Put mask is a set of flags that define what fields will be added to each
521 * log message. Default value is BT_LOG_PUT_STD and other flags could be used to
522 * alter its behavior. See bt_log_set_output_v() for more details.
523 *
3f3b1761
PP
524 * Note about BT_LOG_PUT_SRC: it will be added only in debug builds
525 * (BT_DEBUG_MODE is defined).
beb0fb75
PP
526 */
527enum
528{
529 BT_LOG_PUT_CTX = 1 << 0, /* context (time, pid, tid, log level) */
530 BT_LOG_PUT_TAG = 1 << 1, /* tag (including tag prefix) */
531 BT_LOG_PUT_SRC = 1 << 2, /* source location (file, line, function) */
532 BT_LOG_PUT_MSG = 1 << 3, /* message text (formatted string) */
533 BT_LOG_PUT_STD = 0xffff, /* everything (default) */
534};
535
536typedef struct bt_log_message
537{
538 int lvl; /* Log level of the message */
539 const char *tag; /* Associated tag (without tag prefix) */
540 char *buf; /* Buffer start */
541 char *e; /* Buffer end (last position where EOL with 0 could be written) */
542 char *p; /* Buffer content end (append position) */
543 char *tag_b; /* Prefixed tag start */
544 char *tag_e; /* Prefixed tag end (if != tag_b, points to msg separator) */
545 char *msg_b; /* Message start (expanded format string) */
546}
547bt_log_message;
548
549/* Type of output callback function. It will be called for each log line allowed
550 * by both "current" and "output" log levels ("enabled" and "turned on").
551 * Callback function is allowed to modify content of the buffers pointed by the
552 * msg, but it's not allowed to modify any of msg fields. Buffer pointed by msg
553 * is UTF-8 encoded (no BOM mark).
554 */
555typedef void (*bt_log_output_cb)(const bt_log_message *msg, void *arg);
556
557/* Format options. For more details see bt_log_set_mem_width().
558 */
559typedef struct bt_log_format
560{
561 unsigned mem_width; /* Bytes per line in memory (ASCII-HEX) dump */
562}
563bt_log_format;
564
565/* Output facility.
566 */
567typedef struct bt_log_output
568{
569 unsigned mask; /* What to put into log line buffer (see BT_LOG_PUT_XXX) */
570 void *arg; /* User provided output callback argument */
571 bt_log_output_cb callback; /* Output callback function */
572}
573bt_log_output;
574
575/* Set output callback function.
576 *
577 * Mask allows to control what information will be added to the log line buffer
578 * before callback function is invoked. Default mask value is BT_LOG_PUT_STD.
579 */
580void bt_log_set_output_v(const unsigned mask, void *const arg,
581 const bt_log_output_cb callback);
582static _BT_LOG_INLINE void bt_log_set_output_p(const bt_log_output *const output)
583{
584 bt_log_set_output_v(output->mask, output->arg, output->callback);
585}
586
587/* Used with _AUX macros and allows to override global format and output
588 * facility. Use BT_LOG_GLOBAL_FORMAT and BT_LOG_GLOBAL_OUTPUT for values from
589 * global configuration. Example:
590 *
591 * static const bt_log_output module_output = {
592 * BT_LOG_PUT_STD, 0, custom_output_callback
593 * };
594 * static const bt_log_spec module_spec = {
595 * BT_LOG_GLOBAL_FORMAT, &module_output
596 * };
597 * BT_LOGI_AUX(&module_spec, "Position: %ix%i", x, y);
598 *
599 * See BT_LOGF_AUX and BT_LOGF_MEM_AUX for details.
600 */
601typedef struct bt_log_spec
602{
603 const bt_log_format *format;
604 const bt_log_output *output;
605}
606bt_log_spec;
607
608#ifdef __cplusplus
609}
610#endif
611
612/* Execute log statement if condition is true. Example:
613 *
614 * BT_LOG_IF(1 < 2, BT_LOGI("Log this"));
615 * BT_LOG_IF(1 > 2, BT_LOGI("Don't log this"));
616 *
617 * Keep in mind though, that if condition can't be evaluated at compile time,
618 * then it will be evaluated at run time. This will increase exectuable size
619 * and can have noticeable performance overhead. Try to limit conditions to
620 * expressions that can be evaluated at compile time.
621 */
622#define BT_LOG_IF(cond, f) do { _BT_LOG_IF((cond)) { f; } } _BT_LOG_ONCE
623
624/* Mark log statement as "secret". Log statements that are marked as secrets
625 * will NOT be executed when censoring is enabled (see BT_LOG_CENSORED).
626 * Example:
627 *
628 * BT_LOG_SECRET(BT_LOGI("Credit card: %s", credit_card));
629 * BT_LOG_SECRET(BT_LOGD_MEM(cipher, cipher_sz, "Cipher bytes:"));
630 */
631#define BT_LOG_SECRET(f) BT_LOG_IF(BT_LOG_SECRETS, f)
632
633/* Check "current" log level at compile time (ignoring "output" log level).
634 * Evaluates to true when specified log level is enabled. For example:
635 *
636 * #if BT_LOG_ENABLED_DEBUG
637 * const char *const g_enum_strings[] = {
638 * "enum_value_0", "enum_value_1", "enum_value_2"
639 * };
640 * #endif
641 * // ...
642 * #if BT_LOG_ENABLED_DEBUG
643 * BT_LOGD("enum value: %s", g_enum_strings[v]);
644 * #endif
645 *
510400a9 646 * See BT_MINIMAL_LOG_LEVEL for details.
beb0fb75 647 */
510400a9 648#define BT_LOG_ENABLED(lvl) ((lvl) >= _BT_MINIMAL_LOG_LEVEL)
ef267d12 649#define BT_LOG_ENABLED_TRACE BT_LOG_ENABLED(BT_LOG_TRACE)
beb0fb75
PP
650#define BT_LOG_ENABLED_DEBUG BT_LOG_ENABLED(BT_LOG_DEBUG)
651#define BT_LOG_ENABLED_INFO BT_LOG_ENABLED(BT_LOG_INFO)
770538dd 652#define BT_LOG_ENABLED_WARNING BT_LOG_ENABLED(BT_LOG_WARNING)
beb0fb75
PP
653#define BT_LOG_ENABLED_ERROR BT_LOG_ENABLED(BT_LOG_ERROR)
654#define BT_LOG_ENABLED_FATAL BT_LOG_ENABLED(BT_LOG_FATAL)
655
656/* Check "output" log level at run time (taking into account "current" log
657 * level as well). Evaluates to true when specified log level is turned on AND
658 * enabled. For example:
659 *
660 * if (BT_LOG_ON_DEBUG)
661 * {
662 * char hash[65];
663 * sha256(data_ptr, data_sz, hash);
664 * BT_LOGD("data: len=%u, sha256=%s", data_sz, hash);
665 * }
666 *
667 * See BT_LOG_OUTPUT_LEVEL for details.
668 */
ba32ead5
PP
669#define BT_LOG_ON_CUR_LVL(lvl, cur_lvl) \
670 (BT_LOG_ENABLED((lvl)) && (lvl) >= (cur_lvl))
beb0fb75
PP
671#define BT_LOG_ON(lvl) \
672 (BT_LOG_ENABLED((lvl)) && (lvl) >= _BT_LOG_OUTPUT_LEVEL)
ef267d12 673#define BT_LOG_ON_TRACE BT_LOG_ON(BT_LOG_TRACE)
beb0fb75
PP
674#define BT_LOG_ON_DEBUG BT_LOG_ON(BT_LOG_DEBUG)
675#define BT_LOG_ON_INFO BT_LOG_ON(BT_LOG_INFO)
770538dd 676#define BT_LOG_ON_WARNING BT_LOG_ON(BT_LOG_WARNING)
beb0fb75
PP
677#define BT_LOG_ON_ERROR BT_LOG_ON(BT_LOG_ERROR)
678#define BT_LOG_ON_FATAL BT_LOG_ON(BT_LOG_FATAL)
679
680#ifdef __cplusplus
681extern "C" {
682#endif
683
684extern const char *_bt_log_tag_prefix;
685extern bt_log_format _bt_log_global_format;
686extern bt_log_output _bt_log_global_output;
687extern int _bt_log_global_output_lvl;
688extern const bt_log_spec _bt_log_stderr_spec;
689
690BT_HIDDEN
691void _bt_log_write_d(
692 const char *const func, const char *const file, const unsigned line,
693 const int lvl, const char *const tag,
694 const char *const fmt, ...) _BT_LOG_PRINTFLIKE(6, 7);
695
696BT_HIDDEN
697void _bt_log_write_aux_d(
698 const char *const func, const char *const file, const unsigned line,
699 const bt_log_spec *const log, const int lvl, const char *const tag,
700 const char *const fmt, ...) _BT_LOG_PRINTFLIKE(7, 8);
701
702BT_HIDDEN
703void _bt_log_write(
704 const int lvl, const char *const tag,
705 const char *const fmt, ...) _BT_LOG_PRINTFLIKE(3, 4);
706
707BT_HIDDEN
708void _bt_log_write_aux(
709 const bt_log_spec *const log, const int lvl, const char *const tag,
710 const char *const fmt, ...) _BT_LOG_PRINTFLIKE(4, 5);
711
712BT_HIDDEN
713void _bt_log_write_mem_d(
714 const char *const func, const char *const file, const unsigned line,
715 const int lvl, const char *const tag,
716 const void *const d, const unsigned d_sz,
717 const char *const fmt, ...) _BT_LOG_PRINTFLIKE(8, 9);
718
719BT_HIDDEN
720void _bt_log_write_mem_aux_d(
721 const char *const func, const char *const file, const unsigned line,
722 const bt_log_spec *const log, const int lvl, const char *const tag,
723 const void *const d, const unsigned d_sz,
724 const char *const fmt, ...) _BT_LOG_PRINTFLIKE(9, 10);
725
726BT_HIDDEN
727void _bt_log_write_mem(
728 const int lvl, const char *const tag,
729 const void *const d, const unsigned d_sz,
730 const char *const fmt, ...) _BT_LOG_PRINTFLIKE(5, 6);
731
732BT_HIDDEN
733void _bt_log_write_mem_aux(
734 const bt_log_spec *const log, const int lvl, const char *const tag,
735 const void *const d, const unsigned d_sz,
736 const char *const fmt, ...) _BT_LOG_PRINTFLIKE(6, 7);
737
738#ifdef __cplusplus
739}
740#endif
741
742/* Message logging macros:
ef267d12 743 * - BT_LOGT("format string", args, ...)
beb0fb75
PP
744 * - BT_LOGD("format string", args, ...)
745 * - BT_LOGI("format string", args, ...)
746 * - BT_LOGW("format string", args, ...)
747 * - BT_LOGE("format string", args, ...)
748 * - BT_LOGF("format string", args, ...)
749 *
263c5cef 750 * Message and error string (errno) logging macros:
ef267d12 751 * - BT_LOGT_ERRNO("initial message", "format string", args, ...)
c4f13c31
PP
752 * - BT_LOGD_ERRNO("initial message", "format string", args, ...)
753 * - BT_LOGI_ERRNO("initial message", "format string", args, ...)
754 * - BT_LOGW_ERRNO("initial message", "format string", args, ...)
755 * - BT_LOGE_ERRNO("initial message", "format string", args, ...)
756 * - BT_LOGF_ERRNO("initial message", "format string", args, ...)
263c5cef 757 *
beb0fb75 758 * Memory logging macros:
ef267d12 759 * - BT_LOGT_MEM(data_ptr, data_sz, "format string", args, ...)
beb0fb75
PP
760 * - BT_LOGD_MEM(data_ptr, data_sz, "format string", args, ...)
761 * - BT_LOGI_MEM(data_ptr, data_sz, "format string", args, ...)
762 * - BT_LOGW_MEM(data_ptr, data_sz, "format string", args, ...)
763 * - BT_LOGE_MEM(data_ptr, data_sz, "format string", args, ...)
764 * - BT_LOGF_MEM(data_ptr, data_sz, "format string", args, ...)
765 *
766 * Auxiliary logging macros:
ef267d12 767 * - BT_LOGT_AUX(&log_instance, "format string", args, ...)
beb0fb75
PP
768 * - BT_LOGD_AUX(&log_instance, "format string", args, ...)
769 * - BT_LOGI_AUX(&log_instance, "format string", args, ...)
770 * - BT_LOGW_AUX(&log_instance, "format string", args, ...)
771 * - BT_LOGE_AUX(&log_instance, "format string", args, ...)
772 * - BT_LOGF_AUX(&log_instance, "format string", args, ...)
773 *
774 * Auxiliary memory logging macros:
ef267d12 775 * - BT_LOGT_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
beb0fb75
PP
776 * - BT_LOGD_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
777 * - BT_LOGI_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
778 * - BT_LOGW_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
779 * - BT_LOGE_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
780 * - BT_LOGF_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
781 *
782 * Preformatted string logging macros:
ef267d12 783 * - BT_LOGT_STR("preformatted string");
beb0fb75
PP
784 * - BT_LOGD_STR("preformatted string");
785 * - BT_LOGI_STR("preformatted string");
786 * - BT_LOGW_STR("preformatted string");
787 * - BT_LOGE_STR("preformatted string");
788 * - BT_LOGF_STR("preformatted string");
789 *
790 * Explicit log level and tag macros:
791 * - BT_LOG_WRITE(level, tag, "format string", args, ...)
792 * - BT_LOG_WRITE_MEM(level, tag, data_ptr, data_sz, "format string", args, ...)
793 * - BT_LOG_WRITE_AUX(&log_instance, level, tag, "format string", args, ...)
794 * - BT_LOG_WRITE_MEM_AUX(&log_instance, level, tag, data_ptr, data_sz,
795 * "format string", args, ...)
796 *
ba32ead5
PP
797 * Explicit log level, current log level, and tag:
798 * - BT_LOG_WRITE_CUR_LVL(level, cur_level, tag, "format string", args, ...)
799 *
beb0fb75
PP
800 * Format string follows printf() conventions. Both data_ptr and data_sz could
801 * be 0. Tag can be 0 as well. Most compilers will verify that type of arguments
802 * match format specifiers in format string.
803 *
804 * Library assuming UTF-8 encoding for all strings (char *), including format
805 * string itself.
806 */
807#if BT_LOG_SRCLOC_NONE == _BT_LOG_SRCLOC
808 #define BT_LOG_WRITE(lvl, tag, ...) \
809 do { \
810 if (BT_LOG_ON(lvl)) \
811 _bt_log_write(lvl, tag, __VA_ARGS__); \
812 } _BT_LOG_ONCE
ba32ead5
PP
813 #define BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, ...) \
814 do { \
815 if (BT_LOG_ON_CUR_LVL((lvl), (cur_lvl))) \
816 _bt_log_write(lvl, tag, __VA_ARGS__); \
817 } _BT_LOG_ONCE
beb0fb75
PP
818 #define BT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \
819 do { \
820 if (BT_LOG_ON(lvl)) \
821 _bt_log_write_mem(lvl, tag, d, d_sz, __VA_ARGS__); \
822 } _BT_LOG_ONCE
823 #define BT_LOG_WRITE_AUX(log, lvl, tag, ...) \
824 do { \
825 if (BT_LOG_ON(lvl)) \
826 _bt_log_write_aux(log, lvl, tag, __VA_ARGS__); \
827 } _BT_LOG_ONCE
828 #define BT_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \
829 do { \
830 if (BT_LOG_ON(lvl)) \
831 _bt_log_write_mem_aux(log, lvl, tag, d, d_sz, __VA_ARGS__); \
832 } _BT_LOG_ONCE
833#else
834 #define BT_LOG_WRITE(lvl, tag, ...) \
835 do { \
836 if (BT_LOG_ON(lvl)) \
837 _bt_log_write_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
838 lvl, tag, __VA_ARGS__); \
839 } _BT_LOG_ONCE
ba32ead5
PP
840 #define BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, ...) \
841 do { \
842 if (BT_LOG_ON_CUR_LVL((lvl), (cur_lvl))) \
843 _bt_log_write_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
844 lvl, tag, __VA_ARGS__); \
845 } _BT_LOG_ONCE
beb0fb75
PP
846 #define BT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \
847 do { \
848 if (BT_LOG_ON(lvl)) \
849 _bt_log_write_mem_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
850 lvl, tag, d, d_sz, __VA_ARGS__); \
851 } _BT_LOG_ONCE
852 #define BT_LOG_WRITE_AUX(log, lvl, tag, ...) \
853 do { \
854 if (BT_LOG_ON(lvl)) \
855 _bt_log_write_aux_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
856 log, lvl, tag, __VA_ARGS__); \
857 } _BT_LOG_ONCE
858 #define BT_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \
859 do { \
860 if (BT_LOG_ON(lvl)) \
861 _bt_log_write_mem_aux_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
862 log, lvl, tag, d, d_sz, __VA_ARGS__); \
863 } _BT_LOG_ONCE
864#endif
865
ba32ead5 866#define BT_LOG_WRITE_ERRNO_CUR_LVL(lvl, cur_lvl, tag, _msg, _fmt, args...) \
05509012
MJ
867 do { \
868 const char *error_str; \
869 error_str = g_strerror(errno); \
ba32ead5
PP
870 BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, _msg ": %s" _fmt, error_str, ## args); \
871 } _BT_LOG_ONCE
872
873#define BT_LOG_WRITE_ERRNO(lvl, tag, _msg, _fmt, args...) \
874 do { \
875 BT_LOG_WRITE_ERRNO_CUR_LVL(lvl, _BT_LOG_OUTPUT_LEVEL, tag, _msg, _fmt, ## args); \
05509012 876 } _BT_LOG_ONCE
263c5cef 877
beb0fb75
PP
878static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;}
879
880#define _BT_LOG_UNUSED(...) \
881 do { _BT_LOG_NEVER _bt_log_unused(0, __VA_ARGS__); } _BT_LOG_ONCE
882
ef267d12
PP
883#if BT_LOG_ENABLED_TRACE
884 #define BT_LOGT(...) \
885 BT_LOG_WRITE(BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__)
886 #define BT_LOGT_ERRNO(...) \
887 BT_LOG_WRITE_ERRNO(BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__)
888 #define BT_LOGT_AUX(log, ...) \
889 BT_LOG_WRITE_AUX(log, BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__)
890 #define BT_LOGT_MEM(d, d_sz, ...) \
891 BT_LOG_WRITE_MEM(BT_LOG_TRACE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
892 #define BT_LOGT_MEM_AUX(log, d, d_sz, ...) \
893 BT_LOG_WRITE_MEM(log, BT_LOG_TRACE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
beb0fb75 894#else
ef267d12
PP
895 #define BT_LOGT(...) _BT_LOG_UNUSED(__VA_ARGS__)
896 #define BT_LOGT_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
897 #define BT_LOGT_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
898 #define BT_LOGT_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
beb0fb75
PP
899#endif
900
901#if BT_LOG_ENABLED_DEBUG
902 #define BT_LOGD(...) \
903 BT_LOG_WRITE(BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__)
263c5cef
JG
904 #define BT_LOGD_ERRNO(...) \
905 BT_LOG_WRITE_ERRNO(BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__)
beb0fb75
PP
906 #define BT_LOGD_AUX(log, ...) \
907 BT_LOG_WRITE_AUX(log, BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__)
908 #define BT_LOGD_MEM(d, d_sz, ...) \
909 BT_LOG_WRITE_MEM(BT_LOG_DEBUG, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
910 #define BT_LOGD_MEM_AUX(log, d, d_sz, ...) \
911 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_DEBUG, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
912#else
913 #define BT_LOGD(...) _BT_LOG_UNUSED(__VA_ARGS__)
914 #define BT_LOGD_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
915 #define BT_LOGD_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
916 #define BT_LOGD_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
917#endif
918
919#if BT_LOG_ENABLED_INFO
920 #define BT_LOGI(...) \
921 BT_LOG_WRITE(BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__)
263c5cef
JG
922 #define BT_LOGI_ERRNO(...) \
923 BT_LOG_WRITE_ERRNO(BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__)
beb0fb75
PP
924 #define BT_LOGI_AUX(log, ...) \
925 BT_LOG_WRITE_AUX(log, BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__)
926 #define BT_LOGI_MEM(d, d_sz, ...) \
927 BT_LOG_WRITE_MEM(BT_LOG_INFO, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
928 #define BT_LOGI_MEM_AUX(log, d, d_sz, ...) \
929 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_INFO, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
930#else
931 #define BT_LOGI(...) _BT_LOG_UNUSED(__VA_ARGS__)
932 #define BT_LOGI_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
933 #define BT_LOGI_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
934 #define BT_LOGI_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
935#endif
936
770538dd 937#if BT_LOG_ENABLED_WARNING
beb0fb75 938 #define BT_LOGW(...) \
770538dd 939 BT_LOG_WRITE(BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__)
263c5cef 940 #define BT_LOGW_ERRNO(...) \
770538dd 941 BT_LOG_WRITE_ERRNO(BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__)
beb0fb75 942 #define BT_LOGW_AUX(log, ...) \
770538dd 943 BT_LOG_WRITE_AUX(log, BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__)
beb0fb75 944 #define BT_LOGW_MEM(d, d_sz, ...) \
770538dd 945 BT_LOG_WRITE_MEM(BT_LOG_WARNING, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
beb0fb75 946 #define BT_LOGW_MEM_AUX(log, d, d_sz, ...) \
770538dd 947 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_WARNING, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
beb0fb75
PP
948#else
949 #define BT_LOGW(...) _BT_LOG_UNUSED(__VA_ARGS__)
950 #define BT_LOGW_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
951 #define BT_LOGW_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
952 #define BT_LOGW_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
953#endif
954
955#if BT_LOG_ENABLED_ERROR
956 #define BT_LOGE(...) \
957 BT_LOG_WRITE(BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__)
263c5cef
JG
958 #define BT_LOGE_ERRNO(...) \
959 BT_LOG_WRITE_ERRNO(BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__)
beb0fb75
PP
960 #define BT_LOGE_AUX(log, ...) \
961 BT_LOG_WRITE_AUX(log, BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__)
962 #define BT_LOGE_MEM(d, d_sz, ...) \
963 BT_LOG_WRITE_MEM(BT_LOG_ERROR, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
964 #define BT_LOGE_MEM_AUX(log, d, d_sz, ...) \
965 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_ERROR, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
966#else
967 #define BT_LOGE(...) _BT_LOG_UNUSED(__VA_ARGS__)
968 #define BT_LOGE_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
969 #define BT_LOGE_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
970 #define BT_LOGE_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
971#endif
972
973#if BT_LOG_ENABLED_FATAL
974 #define BT_LOGF(...) \
975 BT_LOG_WRITE(BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__)
263c5cef
JG
976 #define BT_LOGF_ERRNO(...) \
977 BT_LOG_WRITE_ERRNO(BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__)
beb0fb75
PP
978 #define BT_LOGF_AUX(log, ...) \
979 BT_LOG_WRITE_AUX(log, BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__)
980 #define BT_LOGF_MEM(d, d_sz, ...) \
981 BT_LOG_WRITE_MEM(BT_LOG_FATAL, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
982 #define BT_LOGF_MEM_AUX(log, d, d_sz, ...) \
983 BT_LOG_WRITE_MEM_AUX(log, BT_LOG_FATAL, _BT_LOG_TAG, d, d_sz, __VA_ARGS__)
984#else
985 #define BT_LOGF(...) _BT_LOG_UNUSED(__VA_ARGS__)
986 #define BT_LOGF_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
987 #define BT_LOGF_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__)
988 #define BT_LOGF_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__)
989#endif
990
ef267d12 991#define BT_LOGT_STR(s) BT_LOGT("%s", (s))
beb0fb75
PP
992#define BT_LOGD_STR(s) BT_LOGD("%s", (s))
993#define BT_LOGI_STR(s) BT_LOGI("%s", (s))
994#define BT_LOGW_STR(s) BT_LOGW("%s", (s))
995#define BT_LOGE_STR(s) BT_LOGE("%s", (s))
996#define BT_LOGF_STR(s) BT_LOGF("%s", (s))
997
998#ifdef __cplusplus
999extern "C" {
1000#endif
1001
1002/* Output to standard error stream. Library uses it by default, though in few
1003 * cases it could be necessary to specify it explicitly. For example, when
1004 * bt_log library is compiled with BT_LOG_EXTERN_GLOBAL_OUTPUT, application must
1005 * define and initialize global output variable:
1006 *
1007 * BT_LOG_DEFINE_GLOBAL_OUTPUT = {BT_LOG_OUT_STDERR};
1008 *
1009 * Another example is when using custom output, stderr could be used as a
1010 * fallback when custom output facility failed to initialize:
1011 *
1012 * bt_log_set_output_v(BT_LOG_OUT_STDERR);
1013 */
1014enum { BT_LOG_OUT_STDERR_MASK = BT_LOG_PUT_STD };
1b83271b
PP
1015
1016BT_HIDDEN
beb0fb75
PP
1017void bt_log_out_stderr_callback(const bt_log_message *const msg, void *arg);
1018#define BT_LOG_OUT_STDERR BT_LOG_OUT_STDERR_MASK, 0, bt_log_out_stderr_callback
1019
1020/* Predefined spec for stderr. Uses global format options (BT_LOG_GLOBAL_FORMAT)
1021 * and BT_LOG_OUT_STDERR. Could be used to force output to stderr for a
1022 * particular message. Example:
1023 *
1024 * f = fopen("foo.log", "w");
1025 * if (!f)
1026 * BT_LOGE_AUX(BT_LOG_STDERR, "Failed to open log file");
1027 */
1028#define BT_LOG_STDERR (&_bt_log_stderr_spec)
1029
6b06582d
PP
1030/*
1031 * Returns the equivalent letter of the log level `level`.
1032 *
1033 * `level` must be a valid log level.
1034 */
373c938b 1035static inline
6b06582d 1036char bt_log_get_letter_from_level(int level)
373c938b 1037{
6b06582d
PP
1038 char letter;
1039
1040 switch (level) {
ef267d12
PP
1041 case BT_LOG_TRACE:
1042 letter = 'T';
6b06582d
PP
1043 break;
1044 case BT_LOG_DEBUG:
1045 letter = 'D';
1046 break;
1047 case BT_LOG_INFO:
1048 letter = 'I';
1049 break;
770538dd 1050 case BT_LOG_WARNING:
6b06582d
PP
1051 letter = 'W';
1052 break;
1053 case BT_LOG_ERROR:
1054 letter = 'E';
1055 break;
1056 case BT_LOG_FATAL:
1057 letter = 'F';
1058 break;
1059 case BT_LOG_NONE:
1060 letter = 'N';
1061 break;
1062 default:
1063 abort();
373c938b
PP
1064 }
1065
6b06582d
PP
1066 return letter;
1067}
1068
1069/*
1070 * Returns the log level for the string `str`, or -1 if `str` is not a
1071 * valid log level string.
1072 */
1073static inline
1074int bt_log_get_level_from_string(const char *str)
1075{
1076 int level = -1;
1077
1078 BT_ASSERT(str);
1079
ef267d12
PP
1080 if (strcmp(str, "TRACE") == 0 ||
1081 strcmp(str, "T") == 0) {
1082 level = BT_LOG_TRACE;
6b06582d
PP
1083 } else if (strcmp(str, "DEBUG") == 0 ||
1084 strcmp(str, "D") == 0) {
373c938b 1085 level = BT_LOG_DEBUG;
6b06582d
PP
1086 } else if (strcmp(str, "INFO") == 0 ||
1087 strcmp(str, "I") == 0) {
373c938b 1088 level = BT_LOG_INFO;
6b06582d
PP
1089 } else if (strcmp(str, "WARN") == 0 ||
1090 strcmp(str, "WARNING") == 0 ||
1091 strcmp(str, "W") == 0) {
770538dd 1092 level = BT_LOG_WARNING;
6b06582d
PP
1093 } else if (strcmp(str, "ERROR") == 0 ||
1094 strcmp(str, "E") == 0) {
373c938b 1095 level = BT_LOG_ERROR;
6b06582d
PP
1096 } else if (strcmp(str, "FATAL") == 0 ||
1097 strcmp(str, "F") == 0) {
373c938b 1098 level = BT_LOG_FATAL;
6b06582d
PP
1099 } else if (strcmp(str, "NONE") == 0 ||
1100 strcmp(str, "N") == 0) {
373c938b
PP
1101 level = BT_LOG_NONE;
1102 } else {
6b06582d
PP
1103 /* FIXME: Should we warn here? How? */
1104 }
1105
1106 return level;
1107}
1108
1109/*
1110 * Returns the log level for the letter `letter`, or -1 if `letter` is
1111 * not a valid log level string.
1112 */
1113static inline
1114int bt_log_get_level_from_letter(char letter)
1115{
1116 char str[] = {letter, '\0'};
1117
1118 return bt_log_get_level_from_string(str);
1119}
1120
1121static inline
1122int bt_log_get_level_from_env(const char *var)
1123{
1124 const char *varval = getenv(var);
1125 int level = BT_LOG_NONE;
1126
1127 if (!varval) {
1128 goto end;
1129 }
1130
1131 level = bt_log_get_level_from_string(varval);
1132 if (level < 0) {
1133 /* FIXME: Should we warn here? How? */
1134 level = BT_LOG_NONE;
373c938b
PP
1135 }
1136
1137end:
1138 return level;
1139}
1140
5d2d01c4
PP
1141#define BT_LOG_LEVEL_EXTERN_SYMBOL(_level_sym) \
1142 extern int _level_sym
1143
1144#define BT_LOG_INIT_LOG_LEVEL(_level_sym, _env_var) \
1145 BT_HIDDEN int _level_sym = BT_LOG_NONE; \
1146 static \
1147 void __attribute__((constructor)) _bt_log_level_ctor(void) \
1148 { \
1149 _level_sym = bt_log_get_level_from_env(_env_var); \
1150 }
1151
7151fb67
PP
1152#define BT_LOG_SUPPORTED
1153
beb0fb75
PP
1154#ifdef __cplusplus
1155}
1156#endif
1157
5d2d01c4 1158#endif /* BABELTRACE_LOGGING_INTERNAL_H */
This page took 0.099949 seconds and 4 git commands to generate.