From 3cd4c495b8c065ababc249f66d460c4a707d415a Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Fri, 21 Jun 2019 01:26:43 -0400 Subject: [PATCH] lib: add internal BT_LIB_LOG*_APPEND_CAUSE() macros The new BT_LIB_LOGE_APPEND_CAUSE() and BT_LIB_LOGF_APPEND_CAUSE() functions are like BT_LIB_LOGE() and BT_LIB_LOGF(), but they also call bt_current_thread_error_append_cause_from_unknown() with the formatted message to append a cause to the current thread's error object. I plan to use them in lieu of BT_LIB_LOGE() and BT_LIB_LOGF() where those are already used within the library to make support error reporting from the library with minimal changes. Signed-off-by: Philippe Proulx Change-Id: I6d7e3a5feac977f576c29c2451b5f0da8d42ae2b Reviewed-on: https://review.lttng.org/c/babeltrace/+/1617 Tested-by: jenkins Reviewed-by: Francis Deslauriers Reviewed-by: Simon Marchi --- CONTRIBUTING.adoc | 12 +++++++++++ src/lib/lib-logging.c | 46 ++++++++++++++++++++++++++++++++++++++----- src/lib/logging.h | 36 +++++++++++++++++++++++++++++++-- 3 files changed, 87 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index df4ae3cf..d9ddf815 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -583,6 +583,18 @@ of `+BT_LOG*()+`: `+BT_LIB_LOGF("format string", ...)+`:: Library fatal logging statement. +`+BT_LIB_LOGW_APPEND_CAUSE("format string", ...)+`:: + Library warning logging statement, and unconditional error cause + appending. + +`+BT_LIB_LOGE_APPEND_CAUSE("format string", ...)+`:: + Library error logging statement, and unconditional error cause + appending. + +`+BT_LIB_LOGF_APPEND_CAUSE("format string", ...)+`:: + Library fatal logging statement, and unconditional error cause + appending. + The macros above accept the typical `printf()` conversion specifiers with the following limitations: diff --git a/src/lib/lib-logging.c b/src/lib/lib-logging.c index 1c5338c5..66bfe9d3 100644 --- a/src/lib/lib-logging.c +++ b/src/lib/lib-logging.c @@ -20,11 +20,8 @@ * SOFTWARE. */ -/* - * This is just to satisfy the preprocessor check in "lib/logging.h": - * this file does not log anything. - */ -#define BT_LOG_TAG "" +#define BT_LOG_TAG "LIB/LIB-LOGGING" +#include "lib/logging.h" #include #include @@ -38,6 +35,7 @@ #include #include #include +#include #include "logging.h" #include "assert-pre.h" @@ -1488,3 +1486,41 @@ void bt_lib_log(const char *func, const char *file, unsigned line, va_end(args); _bt_log_write_d(func, file, line, lvl, tag, "%s", lib_logging_buf); } + +void bt_lib_maybe_log_and_append_cause(const char *func, const char *file, + unsigned line, int lvl, const char *tag, + const char *fmt, ...) +{ + va_list args; + bt_current_thread_error_append_cause_status status; + + BT_ASSERT(fmt); + va_start(args, fmt); + bt_common_custom_vsnprintf(lib_logging_buf, LIB_LOGGING_BUF_SIZE, '!', + handle_conversion_specifier_bt, NULL, fmt, &args); + va_end(args); + + /* Log conditionally, but always append the error cause */ + if (BT_LOG_ON(lvl)) { + _bt_log_write_d(func, file, line, lvl, tag, "%s", + lib_logging_buf); + } + + status = bt_current_thread_error_append_cause_from_unknown( + "Babeltrace library", file, line, "%s", lib_logging_buf); + if (status) { + /* + * Worst case: this error cause is not appended to the + * current thread's error. + * + * We can accept this as it's an almost impossible + * scenario and returning an error here would mean you + * need to check the return value of each + * BT_LIB_LOG*_APPEND_CAUSE() macro and that would be + * cumbersome. + */ + BT_LOGE("Cannot append error cause to current thread's " + "error object: status=%s", + bt_common_func_status_string(status)); + } +} diff --git a/src/lib/logging.h b/src/lib/logging.h index 560b422a..08c3ffb9 100644 --- a/src/lib/logging.h +++ b/src/lib/logging.h @@ -57,13 +57,45 @@ int bt_lib_log_level; /* * Log statement, specialized for the Babeltrace library. * - * Use one of the BT_LIB_LOGF*() macros above instead of calling this + * This function does NOT check that logging is enabled for level `lvl`: + * you must check it manually with BT_LOG_ON(). + * + * Use one of the BT_LIB_LOG*() macros above instead of calling this * function directly. */ - void bt_lib_log(const char *func, const char *file, unsigned line, int lvl, const char *tag, const char *fmt, ...); +#define BT_LIB_LOG_AND_APPEND(_lvl, _fmt, ...) \ + do { \ + bt_lib_maybe_log_and_append_cause( \ + _BT_LOG_SRCLOC_FUNCTION, __FILE__, \ + __LINE__, _lvl, _BT_LOG_TAG, \ + (_fmt), ##__VA_ARGS__); \ + } while (0) + +/* See `CONTRIBUTING.adoc` for usage */ +#define BT_LIB_LOGE_APPEND_CAUSE(_fmt, ...) \ + BT_LIB_LOG_AND_APPEND(BT_LOG_ERROR, _fmt, ##__VA_ARGS__) +#define BT_LIB_LOGW_APPEND_CAUSE(_fmt, ...) \ + BT_LIB_LOG_AND_APPEND(BT_LOG_WARN, _fmt, ##__VA_ARGS__) + +/* + * Like bt_lib_log(), but also appends a cause to the current thread's + * error object. + * + * Note that, unlike bt_lib_log(), this function does check that logging + * is enabled for level `lvl` before logging. This is to ensure that, + * even though logging is disabled, the function still appends an error + * cause, as the error reporting system does not rely on logging. + * + * Use one of the BT_LIB_LOG*_APPEND_CAUSE() macros above instead of + * calling this function directly. + */ +void bt_lib_maybe_log_and_append_cause(const char *func, const char *file, + unsigned line, int lvl, const char *tag, + const char *fmt, ...); + #define BT_LIB_LOG_SUPPORTED #endif /* BABELTRACE_LIB_LOGGING_INTERNAL_H */ -- 2.34.1