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