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