X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=src%2Flogging%2Flog.h;h=89ac5fc7c54ca3e8fffb858fc1a816fec5762add;hb=ac19444e607847c47917c1cc1abfa09311e19e25;hp=42ae118b58c0a64bd354bcb43937eb263ad86c2b;hpb=91d8147391efdc4d42cc4e1c171a65c0372a008f;p=babeltrace.git diff --git a/src/logging/log.h b/src/logging/log.h index 42ae118b..89ac5fc7 100644 --- a/src/logging/log.h +++ b/src/logging/log.h @@ -1,7 +1,10 @@ /* + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2016 wonder-mice + * * This is zf_log.h, modified with Babeltrace prefixes. * See . - * See logging/LICENSE in the Babeltrace source tree. */ #pragma once @@ -13,8 +16,15 @@ #include #include #include -#include +#include + +/* Access private __BT_LOGGING_LEVEL_* macros. */ +#define __BT_IN_BABELTRACE_H +#include +#undef __BT_IN_BABELTRACE_H + #include "common/macros.h" +#include "common/assert.h" /* To detect incompatible changes you can define BT_LOG_VERSION_REQUIRED to be * the current value of BT_LOG_VERSION before including this file (or via @@ -39,7 +49,7 @@ * - BT_LOG_ERROR - happened something possible, but highly unexpected. The * process is able to recover and continue execution. * Example: out of memory (could also be FATAL if not handled properly). - * - BT_LOG_WARN - happened something that *usually* should not happen and + * - BT_LOG_WARNING - happened something that *usually* should not happen and * significantly changes application behavior for some period of time. * Example: configuration file not found, auth error. * - BT_LOG_INFO - happened significant life cycle event or major state @@ -47,27 +57,28 @@ * Example: app started, user logged in. * - BT_LOG_DEBUG - minimal set of events that could help to reconstruct the * execution path. Usually disabled in release builds. - * - BT_LOG_VERBOSE - all other events. Usually disabled in release builds. + * - BT_LOG_TRACE - all other events. Usually disabled in release builds. * * *Ideally*, log file of debugged, well tested, production ready application * should be empty or very small. Choosing a right log level is as important as * providing short and self descriptive log message. */ -#define BT_LOG_VERBOSE BT_LOGGING_LEVEL_VERBOSE -#define BT_LOG_DEBUG BT_LOGGING_LEVEL_DEBUG -#define BT_LOG_INFO BT_LOGGING_LEVEL_INFO -#define BT_LOG_WARN BT_LOGGING_LEVEL_WARN -#define BT_LOG_ERROR BT_LOGGING_LEVEL_ERROR -#define BT_LOG_FATAL BT_LOGGING_LEVEL_FATAL -#define BT_LOG_NONE BT_LOGGING_LEVEL_NONE +#define BT_LOG_TRACE __BT_LOGGING_LEVEL_TRACE +#define BT_LOG_DEBUG __BT_LOGGING_LEVEL_DEBUG +#define BT_LOG_INFO __BT_LOGGING_LEVEL_INFO +#define BT_LOG_WARNING __BT_LOGGING_LEVEL_WARNING +#define BT_LOG_ERROR __BT_LOGGING_LEVEL_ERROR +#define BT_LOG_FATAL __BT_LOGGING_LEVEL_FATAL +#define BT_LOG_NONE __BT_LOGGING_LEVEL_NONE /* "Current" log level is a compile time check and has no runtime overhead. Log - * level that is below current log level it said to be "disabled". Otherwise, - * it's "enabled". Log messages that are disabled has no runtime overhead - they - * are converted to no-op by preprocessor and then eliminated by compiler. - * Current log level is configured per compilation module (.c/.cpp/.m file) by - * defining BT_LOG_DEF_LEVEL or BT_LOG_LEVEL. BT_LOG_LEVEL has higer priority - * and when defined overrides value provided by BT_LOG_DEF_LEVEL. + * level that is below current log level it said to be "disabled". + * Otherwise, it's "enabled". Log messages that are disabled has no + * runtime overhead - they are converted to no-op by preprocessor and + * then eliminated by compiler. Current log level is configured per + * compilation module (.c/.cpp/.m file) by defining BT_LOG_DEF_LEVEL or + * BT_MINIMAL_LOG_LEVEL. BT_MINIMAL_LOG_LEVEL has higer priority and + * when defined overrides value provided by BT_LOG_DEF_LEVEL. * * Common practice is to define default current log level with BT_LOG_DEF_LEVEL * in build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire @@ -75,37 +86,38 @@ * * CC_ARGS := -DBT_LOG_DEF_LEVEL=BT_LOG_INFO * - * And when necessary to override it with BT_LOG_LEVEL in .c/.cpp/.m files + * And when necessary to override it with BT_MINIMAL_LOG_LEVEL in .c/.cpp/.m files * before including bt_log.h: * - * #define BT_LOG_LEVEL BT_LOG_VERBOSE + * #define BT_MINIMAL_LOG_LEVEL BT_LOG_TRACE * #include "logging.h" * - * If both BT_LOG_DEF_LEVEL and BT_LOG_LEVEL are undefined, then BT_LOG_INFO - * will be used for release builds (NDEBUG is defined) and BT_LOG_DEBUG - * otherwise (NDEBUG is not defined). + * If both BT_LOG_DEF_LEVEL and BT_MINIMAL_LOG_LEVEL are undefined, then + * BT_LOG_INFO will be used for release builds (BT_DEBUG_MODE is NOT + * defined) and BT_LOG_DEBUG otherwise (BT_DEBUG_MODE is defined). */ -#if defined(BT_LOG_LEVEL) - #define _BT_LOG_LEVEL BT_LOG_LEVEL +#if defined(BT_MINIMAL_LOG_LEVEL) + #define _BT_MINIMAL_LOG_LEVEL BT_MINIMAL_LOG_LEVEL #elif defined(BT_LOG_DEF_LEVEL) - #define _BT_LOG_LEVEL BT_LOG_DEF_LEVEL + #define _BT_MINIMAL_LOG_LEVEL BT_LOG_DEF_LEVEL #else - #ifdef NDEBUG - #define _BT_LOG_LEVEL BT_LOG_INFO + #ifdef BT_DEBUG_MODE + #define _BT_MINIMAL_LOG_LEVEL BT_LOG_DEBUG #else - #define _BT_LOG_LEVEL BT_LOG_DEBUG + #define _BT_MINIMAL_LOG_LEVEL BT_LOG_INFO #endif #endif /* "Output" log level is a runtime check. When log level is below output log - * level it said to be "turned off" (or just "off" for short). Otherwise it's - * "turned on" (or just "on"). Log levels that were "disabled" (see - * BT_LOG_LEVEL and BT_LOG_DEF_LEVEL) can't be "turned on", but "enabled" log - * levels could be "turned off". Only messages with log level which is - * "turned on" will reach output facility. All other messages will be ignored - * (and their arguments will not be evaluated). Output log level is a global - * property and configured per process using bt_log_set_output_level() function - * which can be called at any time. + * level it said to be "turned off" (or just "off" for short). Otherwise + * it's "turned on" (or just "on"). Log levels that were "disabled" (see + * BT_MINIMAL_LOG_LEVEL and BT_LOG_DEF_LEVEL) can't be "turned on", but + * "enabled" log levels could be "turned off". Only messages with log + * level which is "turned on" will reach output facility. All other + * messages will be ignored (and their arguments will not be evaluated). + * Output log level is a global property and configured per process + * using bt_log_set_output_level() function which can be called at any + * time. * * Though in some cases it could be useful to configure output log level per * compilation module or per library. There are two ways to achieve that: @@ -115,11 +127,13 @@ * BT_LOG_LIBRARY_PREFIX defined to library specific prefix. See * BT_LOG_LIBRARY_PREFIX for more details. * - * When defined, BT_LOG_OUTPUT_LEVEL must evaluate to integral value that - * corresponds to desired output log level. Use it only when compilation module - * is required to have output log level which is different from global output - * log level set by bt_log_set_output_level() function. For other cases, - * consider defining BT_LOG_LEVEL or using bt_log_set_output_level() function. + * When defined, BT_LOG_OUTPUT_LEVEL must evaluate to integral value + * that corresponds to desired output log level. Use it only when + * compilation module is required to have output log level which is + * different from global output log level set by + * bt_log_set_output_level() function. For other cases, consider + * defining BT_MINIMAL_LOG_LEVEL or using bt_log_set_output_level() + * function. * * Example: * @@ -133,13 +147,14 @@ * g_module_log_level = on? BT_LOG_DEBUG: BT_LOG_INFO; * } * - * Note on performance. This expression will be evaluated each time message is - * logged (except when message log level is "disabled" - see BT_LOG_LEVEL for - * details). Keep this expression as simple as possible, otherwise it will not - * only add runtime overhead, but also will increase size of call site (which - * will result in larger executable). The prefered way is to use integer - * variable (as in example above). If structure must be used, log_level field - * must be the first field in this structure: + * Note on performance. This expression will be evaluated each time + * message is logged (except when message log level is "disabled" - see + * BT_MINIMAL_LOG_LEVEL for details). Keep this expression as simple as + * possible, otherwise it will not only add runtime overhead, but also + * will increase size of call site (which will result in larger + * executable). The prefered way is to use integer variable (as in + * example above). If structure must be used, log_level field must be + * the first field in this structure: * * #define BT_LOG_OUTPUT_LEVEL (g_config.log_level) * #include "logging.h" @@ -157,12 +172,6 @@ */ #if defined(BT_LOG_OUTPUT_LEVEL) #define _BT_LOG_OUTPUT_LEVEL BT_LOG_OUTPUT_LEVEL -#else - /* - * We disallow this to make sure Babeltrace modules always - * have their own local log level. - */ - #error No log level symbol specified: please define BT_LOG_OUTPUT_LEVEL before including this header. #endif /* "Tag" is a compound string that could be associated with a log message. It @@ -225,38 +234,8 @@ #define BT_LOG_SRCLOC_SHORT 1 #define BT_LOG_SRCLOC_LONG 2 -/* Source location format is configured per compilation module (.c/.cpp/.m - * file) by defining BT_LOG_DEF_SRCLOC or BT_LOG_SRCLOC. BT_LOG_SRCLOC has - * higer priority and when defined overrides value provided by - * BT_LOG_DEF_SRCLOC. - * - * Common practice is to define default format with BT_LOG_DEF_SRCLOC in - * build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire - * project or target: - * - * CC_ARGS := -DBT_LOG_DEF_SRCLOC=BT_LOG_SRCLOC_LONG - * - * And when necessary to override it with BT_LOG_SRCLOC in .c/.cpp/.m files - * before including bt_log.h: - * - * #define BT_LOG_SRCLOC BT_LOG_SRCLOC_NONE - * #include "logging.h" - * - * If both BT_LOG_DEF_SRCLOC and BT_LOG_SRCLOC are undefined, then - * BT_LOG_SRCLOC_NONE will be used for release builds (NDEBUG is defined) and - * BT_LOG_SRCLOC_LONG otherwise (NDEBUG is not defined). - */ -#if defined(BT_LOG_SRCLOC) - #define _BT_LOG_SRCLOC BT_LOG_SRCLOC -#elif defined(BT_LOG_DEF_SRCLOC) - #define _BT_LOG_SRCLOC BT_LOG_DEF_SRCLOC -#else - #ifdef NDEBUG - #define _BT_LOG_SRCLOC BT_LOG_SRCLOC_NONE - #else - #define _BT_LOG_SRCLOC BT_LOG_SRCLOC_LONG - #endif -#endif +#define _BT_LOG_SRCLOC BT_LOG_SRCLOC_LONG + #if BT_LOG_SRCLOC_LONG == _BT_LOG_SRCLOC #define _BT_LOG_SRCLOC_FUNCTION _BT_LOG_FUNCTION #else @@ -291,18 +270,18 @@ * #include "logging.h" * * If both BT_LOG_DEF_CENSORING and BT_LOG_CENSORING are undefined, then - * BT_LOG_CENSORED will be used for release builds (NDEBUG is defined) and - * BT_LOG_UNCENSORED otherwise (NDEBUG is not defined). + * BT_LOG_CENSORED will be used for release builds (BT_DEBUG_MODE is NOT + * defined) and BT_LOG_UNCENSORED otherwise (BT_DEBUG_MODE is defined). */ #if defined(BT_LOG_CENSORING) #define _BT_LOG_CENSORING BT_LOG_CENSORING #elif defined(BT_LOG_DEF_CENSORING) #define _BT_LOG_CENSORING BT_LOG_DEF_CENSORING #else - #ifdef NDEBUG - #define _BT_LOG_CENSORING BT_LOG_CENSORED - #else + #ifdef BT_DEBUG_MODE #define _BT_LOG_CENSORING BT_LOG_UNCENSORED + #else + #define _BT_LOG_CENSORING BT_LOG_CENSORED #endif #endif @@ -355,10 +334,10 @@ * corresponding BT_LOG_DEFINE_XXX macro MUST be used exactly once somewhere. * Otherwise build will fail with link error (undefined symbol). */ -#define BT_LOG_DEFINE_TAG_PREFIX BT_HIDDEN const char *_bt_log_tag_prefix -#define BT_LOG_DEFINE_GLOBAL_FORMAT BT_HIDDEN bt_log_format _bt_log_global_format -#define BT_LOG_DEFINE_GLOBAL_OUTPUT BT_HIDDEN bt_log_output _bt_log_global_output -#define BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL BT_HIDDEN int _bt_log_global_output_lvl +#define BT_LOG_DEFINE_TAG_PREFIX const char *_bt_log_tag_prefix +#define BT_LOG_DEFINE_GLOBAL_FORMAT bt_log_format _bt_log_global_format +#define BT_LOG_DEFINE_GLOBAL_OUTPUT bt_log_output _bt_log_global_output +#define BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL int _bt_log_global_output_lvl /* Pointer to global format options. Direct modification is not allowed. Use * bt_log_set_mem_width() instead. Could be used to initialize bt_log_spec @@ -504,7 +483,7 @@ void bt_log_set_tag_prefix(const char *const prefix); */ void bt_log_set_mem_width(const unsigned w); -/* Set "output" log level. See BT_LOG_LEVEL and BT_LOG_OUTPUT_LEVEL for more +/* Set "output" log level. See BT_MINIMAL_LOG_LEVEL and BT_LOG_OUTPUT_LEVEL for more * info about log levels. */ void bt_log_set_output_level(const int lvl); @@ -513,8 +492,8 @@ void bt_log_set_output_level(const int lvl); * log message. Default value is BT_LOG_PUT_STD and other flags could be used to * alter its behavior. See bt_log_set_output_v() for more details. * - * Note about BT_LOG_PUT_SRC: it will be added only in debug builds (NDEBUG is - * not defined). + * Note about BT_LOG_PUT_SRC: it will be added only in debug builds + * (BT_DEBUG_MODE is defined). */ enum { @@ -635,13 +614,13 @@ bt_log_spec; * BT_LOGD("enum value: %s", g_enum_strings[v]); * #endif * - * See BT_LOG_LEVEL for details. + * See BT_MINIMAL_LOG_LEVEL for details. */ -#define BT_LOG_ENABLED(lvl) ((lvl) >= _BT_LOG_LEVEL) -#define BT_LOG_ENABLED_VERBOSE BT_LOG_ENABLED(BT_LOG_VERBOSE) +#define BT_LOG_ENABLED(lvl) ((lvl) >= _BT_MINIMAL_LOG_LEVEL) +#define BT_LOG_ENABLED_TRACE BT_LOG_ENABLED(BT_LOG_TRACE) #define BT_LOG_ENABLED_DEBUG BT_LOG_ENABLED(BT_LOG_DEBUG) #define BT_LOG_ENABLED_INFO BT_LOG_ENABLED(BT_LOG_INFO) -#define BT_LOG_ENABLED_WARN BT_LOG_ENABLED(BT_LOG_WARN) +#define BT_LOG_ENABLED_WARNING BT_LOG_ENABLED(BT_LOG_WARNING) #define BT_LOG_ENABLED_ERROR BT_LOG_ENABLED(BT_LOG_ERROR) #define BT_LOG_ENABLED_FATAL BT_LOG_ENABLED(BT_LOG_FATAL) @@ -658,12 +637,14 @@ bt_log_spec; * * See BT_LOG_OUTPUT_LEVEL for details. */ +#define BT_LOG_ON_CUR_LVL(lvl, cur_lvl) \ + G_UNLIKELY(BT_LOG_ENABLED((lvl)) && (lvl) >= (cur_lvl)) #define BT_LOG_ON(lvl) \ - (BT_LOG_ENABLED((lvl)) && (lvl) >= _BT_LOG_OUTPUT_LEVEL) -#define BT_LOG_ON_VERBOSE BT_LOG_ON(BT_LOG_VERBOSE) + G_UNLIKELY(BT_LOG_ENABLED((lvl)) && (lvl) >= _BT_LOG_OUTPUT_LEVEL) +#define BT_LOG_ON_TRACE BT_LOG_ON(BT_LOG_TRACE) #define BT_LOG_ON_DEBUG BT_LOG_ON(BT_LOG_DEBUG) #define BT_LOG_ON_INFO BT_LOG_ON(BT_LOG_INFO) -#define BT_LOG_ON_WARN BT_LOG_ON(BT_LOG_WARN) +#define BT_LOG_ON_WARNING BT_LOG_ON(BT_LOG_WARNING) #define BT_LOG_ON_ERROR BT_LOG_ON(BT_LOG_ERROR) #define BT_LOG_ON_FATAL BT_LOG_ON(BT_LOG_FATAL) @@ -677,49 +658,41 @@ extern bt_log_output _bt_log_global_output; extern int _bt_log_global_output_lvl; extern const bt_log_spec _bt_log_stderr_spec; -BT_HIDDEN void _bt_log_write_d( const char *const func, const char *const file, const unsigned line, const int lvl, const char *const tag, const char *const fmt, ...) _BT_LOG_PRINTFLIKE(6, 7); -BT_HIDDEN void _bt_log_write_aux_d( const char *const func, const char *const file, const unsigned line, const bt_log_spec *const log, const int lvl, const char *const tag, const char *const fmt, ...) _BT_LOG_PRINTFLIKE(7, 8); -BT_HIDDEN void _bt_log_write( const int lvl, const char *const tag, const char *const fmt, ...) _BT_LOG_PRINTFLIKE(3, 4); -BT_HIDDEN void _bt_log_write_aux( const bt_log_spec *const log, const int lvl, const char *const tag, const char *const fmt, ...) _BT_LOG_PRINTFLIKE(4, 5); -BT_HIDDEN void _bt_log_write_mem_d( const char *const func, const char *const file, const unsigned line, const int lvl, const char *const tag, const void *const d, const unsigned d_sz, const char *const fmt, ...) _BT_LOG_PRINTFLIKE(8, 9); -BT_HIDDEN void _bt_log_write_mem_aux_d( const char *const func, const char *const file, const unsigned line, const bt_log_spec *const log, const int lvl, const char *const tag, const void *const d, const unsigned d_sz, const char *const fmt, ...) _BT_LOG_PRINTFLIKE(9, 10); -BT_HIDDEN void _bt_log_write_mem( const int lvl, const char *const tag, const void *const d, const unsigned d_sz, const char *const fmt, ...) _BT_LOG_PRINTFLIKE(5, 6); -BT_HIDDEN void _bt_log_write_mem_aux( const bt_log_spec *const log, const int lvl, const char *const tag, const void *const d, const unsigned d_sz, @@ -730,7 +703,7 @@ void _bt_log_write_mem_aux( #endif /* Message logging macros: - * - BT_LOGV("format string", args, ...) + * - BT_LOGT("format string", args, ...) * - BT_LOGD("format string", args, ...) * - BT_LOGI("format string", args, ...) * - BT_LOGW("format string", args, ...) @@ -738,7 +711,7 @@ void _bt_log_write_mem_aux( * - BT_LOGF("format string", args, ...) * * Message and error string (errno) logging macros: - * - BT_LOGV_ERRNO("initial message", "format string", args, ...) + * - BT_LOGT_ERRNO("initial message", "format string", args, ...) * - BT_LOGD_ERRNO("initial message", "format string", args, ...) * - BT_LOGI_ERRNO("initial message", "format string", args, ...) * - BT_LOGW_ERRNO("initial message", "format string", args, ...) @@ -746,7 +719,7 @@ void _bt_log_write_mem_aux( * - BT_LOGF_ERRNO("initial message", "format string", args, ...) * * Memory logging macros: - * - BT_LOGV_MEM(data_ptr, data_sz, "format string", args, ...) + * - BT_LOGT_MEM(data_ptr, data_sz, "format string", args, ...) * - BT_LOGD_MEM(data_ptr, data_sz, "format string", args, ...) * - BT_LOGI_MEM(data_ptr, data_sz, "format string", args, ...) * - BT_LOGW_MEM(data_ptr, data_sz, "format string", args, ...) @@ -754,7 +727,7 @@ void _bt_log_write_mem_aux( * - BT_LOGF_MEM(data_ptr, data_sz, "format string", args, ...) * * Auxiliary logging macros: - * - BT_LOGV_AUX(&log_instance, "format string", args, ...) + * - BT_LOGT_AUX(&log_instance, "format string", args, ...) * - BT_LOGD_AUX(&log_instance, "format string", args, ...) * - BT_LOGI_AUX(&log_instance, "format string", args, ...) * - BT_LOGW_AUX(&log_instance, "format string", args, ...) @@ -762,7 +735,7 @@ void _bt_log_write_mem_aux( * - BT_LOGF_AUX(&log_instance, "format string", args, ...) * * Auxiliary memory logging macros: - * - BT_LOGV_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) + * - BT_LOGT_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) * - BT_LOGD_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) * - BT_LOGI_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) * - BT_LOGW_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) @@ -770,7 +743,7 @@ void _bt_log_write_mem_aux( * - BT_LOGF_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...) * * Preformatted string logging macros: - * - BT_LOGV_STR("preformatted string"); + * - BT_LOGT_STR("preformatted string"); * - BT_LOGD_STR("preformatted string"); * - BT_LOGI_STR("preformatted string"); * - BT_LOGW_STR("preformatted string"); @@ -784,6 +757,9 @@ void _bt_log_write_mem_aux( * - BT_LOG_WRITE_MEM_AUX(&log_instance, level, tag, data_ptr, data_sz, * "format string", args, ...) * + * Explicit log level, current log level, and tag: + * - BT_LOG_WRITE_CUR_LVL(level, cur_level, tag, "format string", args, ...) + * * Format string follows printf() conventions. Both data_ptr and data_sz could * be 0. Tag can be 0 as well. Most compilers will verify that type of arguments * match format specifiers in format string. @@ -797,6 +773,11 @@ void _bt_log_write_mem_aux( if (BT_LOG_ON(lvl)) \ _bt_log_write(lvl, tag, __VA_ARGS__); \ } _BT_LOG_ONCE + #define BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, ...) \ + do { \ + if (BT_LOG_ON_CUR_LVL((lvl), (cur_lvl))) \ + _bt_log_write(lvl, tag, __VA_ARGS__); \ + } _BT_LOG_ONCE #define BT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \ do { \ if (BT_LOG_ON(lvl)) \ @@ -819,6 +800,12 @@ void _bt_log_write_mem_aux( _bt_log_write_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \ lvl, tag, __VA_ARGS__); \ } _BT_LOG_ONCE + #define BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, ...) \ + do { \ + if (BT_LOG_ON_CUR_LVL((lvl), (cur_lvl))) \ + _bt_log_write_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \ + lvl, tag, __VA_ARGS__); \ + } _BT_LOG_ONCE #define BT_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \ do { \ if (BT_LOG_ON(lvl)) \ @@ -839,11 +826,16 @@ void _bt_log_write_mem_aux( } _BT_LOG_ONCE #endif -#define BT_LOG_WRITE_ERRNO(lvl, tag, _msg, _fmt, args...) \ +#define BT_LOG_WRITE_ERRNO_CUR_LVL(lvl, cur_lvl, tag, _msg, _fmt, args...) \ do { \ const char *error_str; \ error_str = g_strerror(errno); \ - BT_LOG_WRITE(lvl, tag, _msg ": %s" _fmt, error_str, ## args); \ + BT_LOG_WRITE_CUR_LVL(lvl, cur_lvl, tag, _msg ": %s" _fmt, error_str, ## args); \ + } _BT_LOG_ONCE + +#define BT_LOG_WRITE_ERRNO(lvl, tag, _msg, _fmt, args...) \ + do { \ + BT_LOG_WRITE_ERRNO_CUR_LVL(lvl, _BT_LOG_OUTPUT_LEVEL, tag, _msg, _fmt, ## args); \ } _BT_LOG_ONCE static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;} @@ -851,22 +843,23 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;} #define _BT_LOG_UNUSED(...) \ do { _BT_LOG_NEVER _bt_log_unused(0, __VA_ARGS__); } _BT_LOG_ONCE -#if BT_LOG_ENABLED_VERBOSE - #define BT_LOGV(...) \ - BT_LOG_WRITE(BT_LOG_VERBOSE, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGV_ERRNO(...) \ - BT_LOG_WRITE_ERRNO(BT_LOG_VERBOSE, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGV_AUX(log, ...) \ - BT_LOG_WRITE_AUX(log, BT_LOG_VERBOSE, _BT_LOG_TAG, __VA_ARGS__) - #define BT_LOGV_MEM(d, d_sz, ...) \ - BT_LOG_WRITE_MEM(BT_LOG_VERBOSE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) - #define BT_LOGV_MEM_AUX(log, d, d_sz, ...) \ - BT_LOG_WRITE_MEM(log, BT_LOG_VERBOSE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) +#if BT_LOG_ENABLED_TRACE + #define BT_LOGT(...) \ + BT_LOG_WRITE(BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__) + #define BT_LOGT_ERRNO(...) \ + BT_LOG_WRITE_ERRNO(BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__) + #define BT_LOGT_AUX(log, ...) \ + BT_LOG_WRITE_AUX(log, BT_LOG_TRACE, _BT_LOG_TAG, __VA_ARGS__) + #define BT_LOGT_MEM(d, d_sz, ...) \ + BT_LOG_WRITE_MEM(BT_LOG_TRACE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) + #define BT_LOGT_MEM_AUX(log, d, d_sz, ...) \ + BT_LOG_WRITE_MEM(log, BT_LOG_TRACE, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) #else - #define BT_LOGV(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGV_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGV_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) - #define BT_LOGV_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGT(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGT_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGT_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGT_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGT_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) #endif #if BT_LOG_ENABLED_DEBUG @@ -882,6 +875,7 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;} BT_LOG_WRITE_MEM_AUX(log, BT_LOG_DEBUG, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) #else #define BT_LOGD(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGD_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGD_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGD_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGD_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) @@ -900,24 +894,26 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;} BT_LOG_WRITE_MEM_AUX(log, BT_LOG_INFO, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) #else #define BT_LOGI(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGI_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGI_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGI_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGI_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) #endif -#if BT_LOG_ENABLED_WARN +#if BT_LOG_ENABLED_WARNING #define BT_LOGW(...) \ - BT_LOG_WRITE(BT_LOG_WARN, _BT_LOG_TAG, __VA_ARGS__) + BT_LOG_WRITE(BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__) #define BT_LOGW_ERRNO(...) \ - BT_LOG_WRITE_ERRNO(BT_LOG_WARN, _BT_LOG_TAG, __VA_ARGS__) + BT_LOG_WRITE_ERRNO(BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__) #define BT_LOGW_AUX(log, ...) \ - BT_LOG_WRITE_AUX(log, BT_LOG_WARN, _BT_LOG_TAG, __VA_ARGS__) + BT_LOG_WRITE_AUX(log, BT_LOG_WARNING, _BT_LOG_TAG, __VA_ARGS__) #define BT_LOGW_MEM(d, d_sz, ...) \ - BT_LOG_WRITE_MEM(BT_LOG_WARN, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) + BT_LOG_WRITE_MEM(BT_LOG_WARNING, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) #define BT_LOGW_MEM_AUX(log, d, d_sz, ...) \ - BT_LOG_WRITE_MEM_AUX(log, BT_LOG_WARN, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) + BT_LOG_WRITE_MEM_AUX(log, BT_LOG_WARNING, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) #else #define BT_LOGW(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGW_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGW_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGW_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGW_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) @@ -936,6 +932,7 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;} BT_LOG_WRITE_MEM_AUX(log, BT_LOG_ERROR, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) #else #define BT_LOGE(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGE_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGE_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGE_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGE_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) @@ -954,12 +951,13 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;} BT_LOG_WRITE_MEM_AUX(log, BT_LOG_FATAL, _BT_LOG_TAG, d, d_sz, __VA_ARGS__) #else #define BT_LOGF(...) _BT_LOG_UNUSED(__VA_ARGS__) + #define BT_LOGF_ERRNO(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGF_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGF_MEM(...) _BT_LOG_UNUSED(__VA_ARGS__) #define BT_LOGF_MEM_AUX(...) _BT_LOG_UNUSED(__VA_ARGS__) #endif -#define BT_LOGV_STR(s) BT_LOGV("%s", (s)) +#define BT_LOGT_STR(s) BT_LOGT("%s", (s)) #define BT_LOGD_STR(s) BT_LOGD("%s", (s)) #define BT_LOGI_STR(s) BT_LOGI("%s", (s)) #define BT_LOGW_STR(s) BT_LOGW("%s", (s)) @@ -984,7 +982,6 @@ extern "C" { */ enum { BT_LOG_OUT_STDERR_MASK = BT_LOG_PUT_STD }; -BT_HIDDEN void bt_log_out_stderr_callback(const bt_log_message *const msg, void *arg); #define BT_LOG_OUT_STDERR BT_LOG_OUT_STDERR_MASK, 0, bt_log_out_stderr_callback @@ -998,6 +995,97 @@ void bt_log_out_stderr_callback(const bt_log_message *const msg, void *arg); */ #define BT_LOG_STDERR (&_bt_log_stderr_spec) +/* + * Returns the equivalent letter of the log level `level`. + * + * `level` must be a valid log level. + */ +static inline +char bt_log_get_letter_from_level(int level) +{ + char letter; + + switch (level) { + case BT_LOG_TRACE: + letter = 'T'; + break; + case BT_LOG_DEBUG: + letter = 'D'; + break; + case BT_LOG_INFO: + letter = 'I'; + break; + case BT_LOG_WARNING: + letter = 'W'; + break; + case BT_LOG_ERROR: + letter = 'E'; + break; + case BT_LOG_FATAL: + letter = 'F'; + break; + case BT_LOG_NONE: + letter = 'N'; + break; + default: + abort(); + } + + return letter; +} + +/* + * Returns the log level for the string `str`, or -1 if `str` is not a + * valid log level string. + */ +static inline +int bt_log_get_level_from_string(const char *str) +{ + int level = -1; + + BT_ASSERT(str); + + if (strcmp(str, "TRACE") == 0 || + strcmp(str, "T") == 0) { + level = BT_LOG_TRACE; + } else if (strcmp(str, "DEBUG") == 0 || + strcmp(str, "D") == 0) { + level = BT_LOG_DEBUG; + } else if (strcmp(str, "INFO") == 0 || + strcmp(str, "I") == 0) { + level = BT_LOG_INFO; + } else if (strcmp(str, "WARN") == 0 || + strcmp(str, "WARNING") == 0 || + strcmp(str, "W") == 0) { + level = BT_LOG_WARNING; + } else if (strcmp(str, "ERROR") == 0 || + strcmp(str, "E") == 0) { + level = BT_LOG_ERROR; + } else if (strcmp(str, "FATAL") == 0 || + strcmp(str, "F") == 0) { + level = BT_LOG_FATAL; + } else if (strcmp(str, "NONE") == 0 || + strcmp(str, "N") == 0) { + level = BT_LOG_NONE; + } else { + /* FIXME: Should we warn here? How? */ + } + + return level; +} + +/* + * Returns the log level for the letter `letter`, or -1 if `letter` is + * not a valid log level string. + */ +static inline +int bt_log_get_level_from_letter(char letter) +{ + char str[] = {letter, '\0'}; + + return bt_log_get_level_from_string(str); +} + static inline int bt_log_get_level_from_env(const char *var) { @@ -1008,30 +1096,10 @@ int bt_log_get_level_from_env(const char *var) goto end; } - if (strcmp(varval, "VERBOSE") == 0 || - strcmp(varval, "V") == 0) { - level = BT_LOG_VERBOSE; - } else if (strcmp(varval, "DEBUG") == 0 || - strcmp(varval, "D") == 0) { - level = BT_LOG_DEBUG; - } else if (strcmp(varval, "INFO") == 0 || - strcmp(varval, "I") == 0) { - level = BT_LOG_INFO; - } else if (strcmp(varval, "WARN") == 0 || - strcmp(varval, "WARNING") == 0 || - strcmp(varval, "W") == 0) { - level = BT_LOG_WARN; - } else if (strcmp(varval, "ERROR") == 0 || - strcmp(varval, "E") == 0) { - level = BT_LOG_ERROR; - } else if (strcmp(varval, "FATAL") == 0 || - strcmp(varval, "F") == 0) { - level = BT_LOG_FATAL; - } else if (strcmp(varval, "NONE") == 0 || - strcmp(varval, "N") == 0) { + level = bt_log_get_level_from_string(varval); + if (level < 0) { + /* FIXME: Should we warn here? How? */ level = BT_LOG_NONE; - } else { - /* Should we warn here? How? */ } end: @@ -1042,13 +1110,15 @@ end: extern int _level_sym #define BT_LOG_INIT_LOG_LEVEL(_level_sym, _env_var) \ - BT_HIDDEN int _level_sym = BT_LOG_NONE; \ + int _level_sym = BT_LOG_NONE; \ static \ void __attribute__((constructor)) _bt_log_level_ctor(void) \ { \ _level_sym = bt_log_get_level_from_env(_env_var); \ } +#define BT_LOG_SUPPORTED + #ifdef __cplusplus } #endif