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