#include <string.h>
#include <babeltrace2/logging.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
* 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_TRACE BT_LOGGING_LEVEL_TRACE
#define BT_LOG_DEBUG BT_LOGGING_LEVEL_DEBUG
#define BT_LOG_INFO BT_LOGGING_LEVEL_INFO
#define BT_LOG_WARN BT_LOGGING_LEVEL_WARN
* And when necessary to override it with BT_LOG_LEVEL in .c/.cpp/.m files
* before including bt_log.h:
*
- * #define BT_LOG_LEVEL BT_LOG_VERBOSE
+ * #define BT_LOG_LEVEL BT_LOG_TRACE
* #include "logging.h"
*
* If both BT_LOG_DEF_LEVEL and BT_LOG_LEVEL are undefined, then
* See BT_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_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)
*
* See BT_LOG_OUTPUT_LEVEL for details.
*/
+#define BT_LOG_ON_CUR_LVL(lvl, cur_lvl) \
+ (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)
+#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)
#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, ...)
* - 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, ...)
* - 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, ...)
* - 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, ...)
* - 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, ...)
* - 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");
* - 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.
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)) \
_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)) \
} _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;}
#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_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
#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))
*/
#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
-int bt_log_get_level_from_env(const char *var)
+char bt_log_get_letter_from_level(int level)
{
- const char *varval = getenv(var);
- int level = BT_LOG_NONE;
-
- if (!varval) {
- goto end;
+ 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_WARN:
+ 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();
}
- if (strcmp(varval, "VERBOSE") == 0 ||
- strcmp(varval, "V") == 0) {
- level = BT_LOG_VERBOSE;
- } else if (strcmp(varval, "DEBUG") == 0 ||
- strcmp(varval, "D") == 0) {
+ 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(varval, "INFO") == 0 ||
- strcmp(varval, "I") == 0) {
+ } else if (strcmp(str, "INFO") == 0 ||
+ strcmp(str, "I") == 0) {
level = BT_LOG_INFO;
- } else if (strcmp(varval, "WARN") == 0 ||
- strcmp(varval, "WARNING") == 0 ||
- strcmp(varval, "W") == 0) {
+ } else if (strcmp(str, "WARN") == 0 ||
+ strcmp(str, "WARNING") == 0 ||
+ strcmp(str, "W") == 0) {
level = BT_LOG_WARN;
- } else if (strcmp(varval, "ERROR") == 0 ||
- strcmp(varval, "E") == 0) {
+ } else if (strcmp(str, "ERROR") == 0 ||
+ strcmp(str, "E") == 0) {
level = BT_LOG_ERROR;
- } else if (strcmp(varval, "FATAL") == 0 ||
- strcmp(varval, "F") == 0) {
+ } else if (strcmp(str, "FATAL") == 0 ||
+ strcmp(str, "F") == 0) {
level = BT_LOG_FATAL;
- } else if (strcmp(varval, "NONE") == 0 ||
- strcmp(varval, "N") == 0) {
+ } else if (strcmp(str, "NONE") == 0 ||
+ strcmp(str, "N") == 0) {
level = BT_LOG_NONE;
} else {
- /* Should we warn here? How? */
+ /* 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)
+{
+ const char *varval = getenv(var);
+ int level = BT_LOG_NONE;
+
+ if (!varval) {
+ goto end;
+ }
+
+ level = bt_log_get_level_from_string(varval);
+ if (level < 0) {
+ /* FIXME: Should we warn here? How? */
+ level = BT_LOG_NONE;
}
end:
_level_sym = bt_log_get_level_from_env(_env_var); \
}
+#define BT_LOG_SUPPORTED
+
#ifdef __cplusplus
}
#endif