cpp-common: add `logging.hpp` (`bt2c::Logger` and BT_CPPLOG*() macros)
This new file contains the `bt2c::Logger` class of which an instance
contains:
* An actor: a self component class, a self component, a self message
iterator, or a named module.
* A current logging level.
* A logging tag.
The class offers the logNoThrow(), logMemNoThrow(), logErrnoNoThrow(),
logErrorAndThrow(), logErrorAndRethrow(), logErrorErrnoAndThrow(), and
logErrorErrnoAndRethrow() method templates to log using a given level,
optionally append a cause to the error of the current thread using the
correct actor, and optionally throw or rethrow.
The methods above expect a format string and zero or more arguments to
be formatted with fmt::format(). There are also versions with `Str` in
the name which accept a single string.
All the logging methods are `const` so that you may log with a
`const bt2c::Logger`: they don't change any user-visible state.
Then, the various BT_CPPLOG*() macros call one of the log*() methods on
a logger instance with the current file name, function name, and line
number, forwarding the other arguments to the method. Those macros are
unfortunately needed for the file/function/line information, similar to
SPDLOG_LOGGER_INFO() vs. the info() method.
The macros of which the name ends with `_SPEC` accept a specific logger;
the other ones use the fixed `_mLogger` logger, which will be the case
most of the time (logging from a user component or message iterator).
Example:
BT_CPPLOGE_APPEND_CAUSE_AND_THROW(Error,
"Failed to add {0} items to `{1}` (expecting {0}, not {2})",
expCount, containerName, count);
Internally, the logging methods fill `_mBuf` with fmt::format_to() and
pass the resulting string to some bt_log_write*() function. Argument
evaluation and formatting only happens if logging and/or error cause
appending will also happen.
Create a logger from another one with a different tag like this:
MyThing::MyThing(const bt2c::Logger& parentLogger, ...) :
_mLogger {parentLogger, "MY-THING"},
...
Make some code conditional to having some logging active for a given
level with the wouldLog*() methods (uses BT_LOG_ON_CUR_LVL()
internally):
if (_mLogger.wouldLogD()) {
// code which only exists to log
BT_CPPLOGD(...);
}
Note that this first version is not thread-safe (the underlying logging
framework is, but `_mBuf` isn't protected for a given logger).
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Iacb4c26e42c868f27e3a85b9fe163acac870624f
Reviewed-on: https://review.lttng.org/c/babeltrace/+/11388
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
CI-Build: Simon Marchi <simon.marchi@efficios.com>
This page took 0.026329 seconds and 4 git commands to generate.