2 * SPDX-FileCopyrightText: 2023 Philippe Proulx <pproulx@efficios.com>
3 * SPDX-License-Identifier: MIT
6 #ifndef BABELTRACE_CPP_COMMON_BT2C_LOGGING_HPP
7 #define BABELTRACE_CPP_COMMON_BT2C_LOGGING_HPP
17 #include <babeltrace2/babeltrace.h>
19 #include "common/assert.h"
20 #include "cpp-common/bt2/private-query-executor.hpp"
21 #include "cpp-common/bt2/self-component-class.hpp"
22 #include "cpp-common/bt2/self-component-port.hpp"
23 #include "cpp-common/bt2/self-message-iterator.hpp"
24 #include "cpp-common/bt2s/optional.hpp"
25 #include "cpp-common/vendor/fmt/core.h"
26 #include "logging/log-api.h"
31 * A logger contains an actor (self component class, self component,
32 * self message iterator, or simple module name), a current logging
33 * level, and a logging tag.
35 * It offers the logNoThrow(), logMemNoThrow(), logErrnoNoThrow(),
36 * logErrorAndThrow(), logErrorAndRethrow(), logErrorErrnoAndThrow(),
37 * and logErrorErrnoAndRethrow() method templates to log using a given
38 * level, optionally append a cause to the error of the current thread
39 * using the correct actor, and optionally throw or rethrow.
41 * The methods above expect a format string and zero or more arguments
42 * to be formatted with fmt::format().
47 /* Available log levels */
53 Warning = BT_LOG_WARNING,
60 * Builds a logger from the self component class `selfCompCls` using
61 * the tag `tag` and the logging level of `privQueryExec`.
63 explicit Logger(const bt2::SelfComponentClass selfCompCls,
64 const bt2::PrivateQueryExecutor privQueryExec, std::string tag) noexcept :
65 _mSelfCompCls {selfCompCls},
66 _mLevel {static_cast<Level>(privQueryExec.loggingLevel())}, _mTag {std::move(tag)}
71 * Builds a logger from the self component `selfComp` using the tag
74 explicit Logger(const bt2::SelfComponent selfComp, std::string tag) noexcept :
75 _mSelfComp {selfComp}, _mLevel {static_cast<Level>(selfComp.loggingLevel())}, _mTag {
82 * Builds a logger from the self source component `selfComp` using
85 explicit Logger(const bt2::SelfSourceComponent selfComp, std::string tag) noexcept :
87 bt2::SelfComponent {bt_self_component_source_as_self_component(selfComp.libObjPtr())},
93 * Builds a logger from the self filter component `selfComp` using
96 explicit Logger(const bt2::SelfFilterComponent selfComp, std::string tag) noexcept :
98 bt2::SelfComponent {bt_self_component_filter_as_self_component(selfComp.libObjPtr())},
104 * Builds a logger from the self sink component `selfComp` using the
107 explicit Logger(const bt2::SelfSinkComponent selfComp, std::string tag) noexcept :
108 Logger {bt2::SelfComponent {bt_self_component_sink_as_self_component(selfComp.libObjPtr())},
114 * Builds a logger from the self message iterator `selfMsgIter`
115 * using the tag `tag`.
117 explicit Logger(const bt2::SelfMessageIterator selfMsgIter, std::string tag) noexcept :
118 _mSelfMsgIter {selfMsgIter},
119 _mLevel {static_cast<Level>(selfMsgIter.component().loggingLevel())}, _mTag {std::move(tag)}
124 * Builds a logger from the module named `moduleName` using the tag
125 * `tag` and logging level `logLevel`.
127 explicit Logger(std::string moduleName, std::string tag, const Level logLevel) noexcept :
128 _mModuleName {std::move(moduleName)}, _mLevel {logLevel}, _mTag {std::move(tag)}
133 * Builds a logger from another logger `other` using the new tag
136 explicit Logger(const Logger& other, std::string newTag) :
137 _mSelfCompCls {other._mSelfCompCls}, _mSelfComp {other._mSelfComp},
138 _mSelfMsgIter {other._mSelfMsgIter},
139 _mModuleName {other._mModuleName}, _mLevel {other._mLevel}, _mTag {std::move(newTag)}
144 * Current logging level.
146 Level level() const noexcept
152 * Current logging level converted to a `bt_log_level` value.
156 bt_log_level cLevel() const noexcept
158 return static_cast<bt_log_level>(_mLevel);
162 * Whether or not this logger would log at the level `level`.
164 bool wouldLog(const Level level) const noexcept
166 return BT_LOG_ON_CUR_LVL(static_cast<int>(level), static_cast<int>(_mLevel));
170 * Whether or not this logger would log at the trace level.
172 bool wouldLogT() const noexcept
174 return this->wouldLog(Level::Trace);
178 * Whether or not this logger would log at the debug level.
180 bool wouldLogD() const noexcept
182 return this->wouldLog(Level::Debug);
186 * Whether or not this logger would log at the info level.
188 bool wouldLogI() const noexcept
190 return this->wouldLog(Level::Info);
194 * Whether or not this logger would log at the warning level.
196 bool wouldLogW() const noexcept
198 return this->wouldLog(Level::Warning);
202 * Whether or not this logger would log at the error level.
204 bool wouldLogE() const noexcept
206 return this->wouldLog(Level::Error);
210 * Whether or not this logger would log at the fatal level.
212 bool wouldLogF() const noexcept
214 return this->wouldLog(Level::Fatal);
220 const std::string& tag() const noexcept
226 * Self component class actor, or `bt2s::nullopt` if none.
228 const bt2s::optional<bt2::SelfComponentClass>& selfCompCls() const noexcept
230 return _mSelfCompCls;
234 * Self component actor, or `bt2s::nullopt` if none.
236 const bt2s::optional<bt2::SelfComponent>& selfComp() const noexcept
242 * Self message iterator actor, or `bt2s::nullopt` if none.
244 const bt2s::optional<bt2::SelfMessageIterator>& selfMsgIter() const noexcept
246 return _mSelfMsgIter;
250 * Name of module actor, or `bt2s::nullopt` if none.
252 const bt2s::optional<std::string>& moduleName() const noexcept
258 struct _StdLogWriter final
260 static void write(const char * const fileName, const char * const funcName,
261 const unsigned lineNo, const Level level, const char * const tag,
262 const void *, unsigned int, const char * const initMsg,
263 const char * const msg) noexcept
265 BT_ASSERT_DBG(initMsg && std::strcmp(initMsg, "") == 0);
266 bt_log_write(fileName, funcName, lineNo, static_cast<bt_log_level>(level), tag, msg);
272 * Logs using the level `LevelV`.
274 * This method forwards `fmt` and `args` to fmt::format() to create
277 * If `AppendCauseV` is true, this method also appends a cause to
278 * the error of the current thread using the same message.
280 template <Level LevelV, bool AppendCauseV, typename... ArgTs>
281 void logNoThrow(const char * const fileName, const char * const funcName,
282 const unsigned int lineNo, const char * const fmt, ArgTs&&...args) const
284 this->_logNoThrow<_StdLogWriter, LevelV, AppendCauseV>(
285 fileName, funcName, lineNo, nullptr, 0, "", fmt, std::forward<ArgTs>(args)...);
289 * Logs `msg` using the level `LevelV`.
291 * If `AppendCauseV` is true, this method also appends a cause to
292 * the error of the current thread using the same message.
294 template <Level LevelV, bool AppendCauseV>
295 void logStrNoThrow(const char * const fileName, const char * const funcName,
296 const unsigned int lineNo, const char * const msg) const
298 this->_logStrNoThrow<_StdLogWriter, LevelV, AppendCauseV>(fileName, funcName, lineNo,
299 nullptr, 0, "", msg);
303 * Like logAndNoThrow() with the `Level::Error` level, but also
304 * throws a default-constructed instance of `ExcT`.
306 template <bool AppendCauseV, typename ExcT, typename... ArgTs>
307 [[noreturn]] void logErrorAndThrow(const char * const fileName, const char * const funcName,
308 const unsigned int lineNo, const char * const fmt,
309 ArgTs&&...args) const
311 this->logNoThrow<Level::Error, AppendCauseV>(fileName, funcName, lineNo, fmt,
312 std::forward<ArgTs>(args)...);
317 * Like logStrAndNoThrow() with the `Level::Error` level, but also
318 * throws a default-constructed instance of `ExcT`.
320 template <bool AppendCauseV, typename ExcT>
321 [[noreturn]] void logErrorStrAndThrow(const char * const fileName, const char * const funcName,
322 const unsigned int lineNo, const char * const msg) const
324 this->logStrNoThrow<Level::Error, AppendCauseV>(fileName, funcName, lineNo, msg);
329 * Like logAndNoThrow() with the `Level::Error` level, but also
332 template <bool AppendCauseV, typename... ArgTs>
333 [[noreturn]] void logErrorAndRethrow(const char * const fileName, const char * const funcName,
334 const unsigned int lineNo, const char * const fmt,
335 ArgTs&&...args) const
337 this->logNoThrow<Level::Error, AppendCauseV>(fileName, funcName, lineNo, fmt,
338 std::forward<ArgTs>(args)...);
343 * Like logStrAndNoThrow() with the `Level::Error` level, but also
346 template <bool AppendCauseV>
347 [[noreturn]] void logErrorStrAndRethrow(const char * const fileName,
348 const char * const funcName, const unsigned int lineNo,
349 const char * const msg) const
351 this->logStrNoThrow<Level::Error, AppendCauseV>(fileName, funcName, lineNo, msg);
356 struct _InitMsgLogWriter final
358 static void write(const char * const fileName, const char * const funcName,
359 const unsigned lineNo, const Level level, const char * const tag,
360 const void *, unsigned int, const char * const initMsg,
361 const char * const msg) noexcept
363 bt_log_write_printf(funcName, fileName, lineNo, static_cast<bt_log_level>(level), tag,
364 "%s%s", initMsg, msg);
370 * Logs the message of `errno` using the level `LevelV`.
372 * The log message starts with `initMsg`, is followed with the
373 * message for `errno`, and then with what fmt::format() creates
374 * given `fmt` and `args`.
376 * If `AppendCauseV` is true, this method also appends a cause to
377 * the error of the current thread using the same message.
379 template <Level LevelV, bool AppendCauseV, typename... ArgTs>
380 void logErrnoNoThrow(const char * const fileName, const char * const funcName,
381 const unsigned int lineNo, const char * const initMsg,
382 const char * const fmt, ArgTs&&...args) const
384 this->_logNoThrow<_InitMsgLogWriter, LevelV, AppendCauseV>(
385 fileName, funcName, lineNo, nullptr, 0, this->_errnoIntroStr(initMsg).c_str(), fmt,
386 std::forward<ArgTs>(args)...);
390 * Logs the message of `errno` using the level `LevelV`.
392 * The log message starts with `initMsg`, is followed with the
393 * message for `errno`, and then with `msg`.
395 * If `AppendCauseV` is true, this method also appends a cause to
396 * the error of the current thread using the same message.
398 template <Level LevelV, bool AppendCauseV>
399 void logErrnoStrNoThrow(const char * const fileName, const char * const funcName,
400 const unsigned int lineNo, const char * const initMsg,
401 const char * const msg) const
403 this->_logStrNoThrow<_InitMsgLogWriter, LevelV, AppendCauseV>(
404 fileName, funcName, lineNo, nullptr, 0, this->_errnoIntroStr(initMsg).c_str(), msg);
408 * Like logErrnoNoThrow() with the `Level::Error` level, but also
409 * throws a default-constructed instance of `ExcT`.
411 template <bool AppendCauseV, typename ExcT, typename... ArgTs>
412 [[noreturn]] void logErrorErrnoAndThrow(const char * const fileName,
413 const char * const funcName, const unsigned int lineNo,
414 const char * const initMsg, const char * const fmt,
415 ArgTs&&...args) const
417 this->logErrnoNoThrow<Level::Error, AppendCauseV>(fileName, funcName, lineNo, initMsg, fmt,
418 std::forward<ArgTs>(args)...);
423 * Like logErrnoStrNoThrow() with the `Level::Error` level, but also
424 * throws a default-constructed instance of `ExcT`.
426 template <bool AppendCauseV, typename ExcT>
428 logErrorErrnoStrAndThrow(const char * const fileName, const char * const funcName,
429 const unsigned int lineNo, const char * const initMsg,
430 const char * const msg) const
432 this->logErrnoStrNoThrow<Level::Error, AppendCauseV>(fileName, funcName, lineNo, initMsg,
438 * Like logErrnoNoThrow() with the `Level::Error` level, but also
441 template <bool AppendCauseV, typename... ArgTs>
442 [[noreturn]] void logErrorErrnoAndRethrow(const char * const fileName,
443 const char * const funcName,
444 const unsigned int lineNo, const char * const initMsg,
445 const char * const fmt, ArgTs&&...args) const
447 this->logErrnoNoThrow<Level::Error, AppendCauseV>(fileName, funcName, lineNo, initMsg, fmt,
448 std::forward<ArgTs>(args)...);
453 * Like logErrnoStrNoThrow() with the `Level::Error` level, but also
456 template <bool AppendCauseV>
458 logErrorErrnoStrAndRethrow(const char * const fileName, const char * const funcName,
459 const unsigned int lineNo, const char * const initMsg,
460 const char * const msg) const
462 this->logErrnoStrNoThrow<Level::Error, AppendCauseV>(fileName, funcName, lineNo, initMsg,
468 struct _MemLogWriter final
470 static void write(const char * const fileName, const char * const funcName,
471 const unsigned lineNo, const Level level, const char * const tag,
472 const void * const memData, const unsigned int memLen, const char *,
473 const char * const msg) noexcept
475 bt_log_write_mem(funcName, fileName, lineNo, static_cast<bt_log_level>(level), tag,
476 memData, memLen, msg);
482 * Logs memory data using the level `LevelV`.
484 * This method forwards `fmt` and `args` to fmt::format() to create
487 template <Level LevelV, typename... ArgTs>
488 void logMemNoThrow(const char * const fileName, const char * const funcName,
489 const unsigned int lineNo, const void * const memData,
490 const unsigned int memLen, const char * const fmt, ArgTs&&...args) const
492 this->_logNoThrow<_MemLogWriter, LevelV, false>(fileName, funcName, lineNo, memData, memLen,
493 "", fmt, std::forward<ArgTs>(args)...);
497 * Logs memory data using the level `LevelV`, starting with the
500 template <Level LevelV>
501 void logMemStrNoThrow(const char * const fileName, const char * const funcName,
502 const unsigned int lineNo, const void * const memData,
503 const unsigned int memLen, const char * const msg) const
505 this->_logStrNoThrow<_MemLogWriter, LevelV, false>(fileName, funcName, lineNo, memData,
511 * Formats a log message with fmt::format() given `fmt` and `args`,
512 * and then forwards everything to _logStrNoThrow().
514 template <typename LogWriterT, Level LevelV, bool AppendCauseV, typename... ArgTs>
515 void _logNoThrow(const char * const fileName, const char * const funcName,
516 const unsigned int lineNo, const void * const memData,
517 const std::size_t memLen, const char * const initMsg, const char * const fmt,
518 ArgTs&&...args) const
520 /* Only format arguments if logging or appending an error cause */
521 if (G_UNLIKELY(this->wouldLog(LevelV) || AppendCauseV)) {
523 * Format arguments to our buffer (fmt::format_to() doesn't
524 * append a null character).
527 fmt::format_to(std::back_inserter(_mBuf), fmt, std::forward<ArgTs>(args)...);
528 _mBuf.push_back('\0');
531 this->_logStrNoThrow<LogWriterT, LevelV, AppendCauseV>(fileName, funcName, lineNo, memData,
532 memLen, initMsg, _mBuf.data());
536 * Calls LogWriterT::write() with its arguments to log using the
539 * If `AppendCauseV` is true, this method also appends a cause to
540 * the error of the current thread using the concatenation of
541 * `initMsg` and `msg` as the message.
543 template <typename LogWriterT, Level LevelV, bool AppendCauseV>
544 void _logStrNoThrow(const char * const fileName, const char * const funcName,
545 const unsigned int lineNo, const void * const memData,
546 const std::size_t memLen, const char * const initMsg,
547 const char * const msg) const
549 /* Initial message and main message are required */
554 if (this->wouldLog(LevelV)) {
555 LogWriterT::write(fileName, funcName, lineNo, LevelV, _mTag.data(), memData, memLen,
559 /* Append an error cause if needed */
562 bt_current_thread_error_append_cause_from_message_iterator(
563 _mSelfMsgIter->libObjPtr(), fileName, lineNo, "%s%s", initMsg, msg);
564 } else if (_mSelfComp) {
565 bt_current_thread_error_append_cause_from_component(
566 _mSelfComp->libObjPtr(), fileName, lineNo, "%s%s", initMsg, msg);
567 } else if (_mSelfCompCls) {
568 bt_current_thread_error_append_cause_from_component_class(
569 _mSelfCompCls->libObjPtr(), fileName, lineNo, "%s%s", initMsg, msg);
571 BT_ASSERT(_mModuleName);
572 bt_current_thread_error_append_cause_from_unknown(_mModuleName->data(), fileName,
573 lineNo, "%s%s", initMsg, msg);
578 static std::string _errnoIntroStr(const char * const initMsg)
580 BT_ASSERT(errno != 0);
581 return fmt::format("{}: {}", initMsg, g_strerror(errno));
584 /* Exactly one of the following four members has a value */
585 bt2s::optional<bt2::SelfComponentClass> _mSelfCompCls;
586 bt2s::optional<bt2::SelfComponent> _mSelfComp;
587 bt2s::optional<bt2::SelfMessageIterator> _mSelfMsgIter;
588 bt2s::optional<std::string> _mModuleName;
590 /* Current logging level */
596 /* Formatting buffer */
597 mutable std::vector<char> _mBuf;
600 } /* namespace bt2c */
602 /* Internal: default logger name */
603 #define _BT_CPPLOG_DEF_LOGGER _mLogger
606 * Calls logNoThrow() on `_logger` to log using the level `_lvl` without
607 * appending nor throwing.
609 #define BT_CPPLOG_EX(_lvl, _logger, _fmt, ...) \
611 if (G_UNLIKELY((_logger).wouldLog(_lvl))) { \
612 (_logger).logNoThrow<(_lvl), false>(__FILE__, __func__, __LINE__, (_fmt), \
618 * BT_CPPLOG_EX() with specific logging levels.
620 #define BT_CPPLOGT_SPEC(_logger, _fmt, ...) \
621 BT_CPPLOG_EX(bt2c::Logger::Level::Trace, (_logger), (_fmt), ##__VA_ARGS__)
622 #define BT_CPPLOGD_SPEC(_logger, _fmt, ...) \
623 BT_CPPLOG_EX(bt2c::Logger::Level::Debug, (_logger), (_fmt), ##__VA_ARGS__)
624 #define BT_CPPLOGI_SPEC(_logger, _fmt, ...) \
625 BT_CPPLOG_EX(bt2c::Logger::Level::Info, (_logger), (_fmt), ##__VA_ARGS__)
626 #define BT_CPPLOGW_SPEC(_logger, _fmt, ...) \
627 BT_CPPLOG_EX(bt2c::Logger::Level::Warning, (_logger), (_fmt), ##__VA_ARGS__)
628 #define BT_CPPLOGE_SPEC(_logger, _fmt, ...) \
629 BT_CPPLOG_EX(bt2c::Logger::Level::Error, (_logger), (_fmt), ##__VA_ARGS__)
630 #define BT_CPPLOGF_SPEC(_logger, _fmt, ...) \
631 BT_CPPLOG_EX(bt2c::Logger::Level::Fatal, (_logger), (_fmt), ##__VA_ARGS__)
634 * BT_CPPLOG_EX() with specific logging levels and using the default
637 #define BT_CPPLOGT(_fmt, ...) BT_CPPLOGT_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
638 #define BT_CPPLOGD(_fmt, ...) BT_CPPLOGD_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
639 #define BT_CPPLOGI(_fmt, ...) BT_CPPLOGI_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
640 #define BT_CPPLOGW(_fmt, ...) BT_CPPLOGW_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
641 #define BT_CPPLOGE(_fmt, ...) BT_CPPLOGE_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
642 #define BT_CPPLOGF(_fmt, ...) BT_CPPLOGF_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
645 * Calls logStrNoThrow() on `_logger` to log using the level `_lvl`
646 * without appending nor throwing.
648 #define BT_CPPLOG_STR_EX(_lvl, _logger, _msg) \
649 (_logger).logStrNoThrow<(_lvl), false>(__FILE__, __func__, __LINE__, (_msg))
652 * BT_CPPLOG_STR_EX() with specific logging levels.
654 #define BT_CPPLOGT_STR_SPEC(_logger, _msg) \
655 BT_CPPLOG_STR_EX(bt2c::Logger::Level::Trace, (_logger), (_msg))
656 #define BT_CPPLOGD_STR_SPEC(_logger, _msg) \
657 BT_CPPLOG_STR_EX(bt2c::Logger::Level::Debug, (_logger), (_msg))
658 #define BT_CPPLOGI_STR_SPEC(_logger, _msg) \
659 BT_CPPLOG_STR_EX(bt2c::Logger::Level::Info, (_logger), (_msg))
660 #define BT_CPPLOGW_STR_SPEC(_logger, _msg) \
661 BT_CPPLOG_STR_EX(bt2c::Logger::Level::Warning, (_logger), (_msg))
662 #define BT_CPPLOGE_STR_SPEC(_logger, _msg) \
663 BT_CPPLOG_STR_EX(bt2c::Logger::Level::Error, (_logger), (_msg))
664 #define BT_CPPLOGF_STR_SPEC(_logger, _msg) \
665 BT_CPPLOG_STR_EX(bt2c::Logger::Level::Fatal, (_logger), (_msg))
668 * BT_CPPLOG_STR_EX() with specific logging levels and using the default
671 #define BT_CPPLOGT_STR(_msg) BT_CPPLOGT_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_msg))
672 #define BT_CPPLOGD_STR(_msg) BT_CPPLOGD_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_msg))
673 #define BT_CPPLOGI_STR(_msg) BT_CPPLOGI_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_msg))
674 #define BT_CPPLOGW_STR(_msg) BT_CPPLOGW_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_msg))
675 #define BT_CPPLOGE_STR(_msg) BT_CPPLOGE_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_msg))
676 #define BT_CPPLOGF_STR(_msg) BT_CPPLOGF_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_msg))
679 * Calls logMemNoThrow() on `_logger` to log using the level `_lvl`
680 * without appending nor throwing.
682 #define BT_CPPLOG_MEM_EX(_lvl, _logger, _mem_data, _mem_len, _fmt, ...) \
684 if (G_UNLIKELY((_logger).wouldLog(_lvl))) { \
685 (_logger).logMemNoThrow<(_lvl)>(__FILE__, __func__, __LINE__, (_mem_data), (_mem_len), \
686 (_fmt), ##__VA_ARGS__); \
691 * BT_CPPLOG_MEM_EX() with specific logging levels.
693 #define BT_CPPLOGT_MEM_SPEC(_logger, _mem_data, _mem_len, _fmt, ...) \
694 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Trace, (_logger), (_mem_data), (_mem_len), (_fmt), \
696 #define BT_CPPLOGD_MEM_SPEC(_logger, _mem_data, _mem_len, _fmt, ...) \
697 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Debug, (_logger), (_mem_data), (_mem_len), (_fmt), \
699 #define BT_CPPLOGI_MEM_SPEC(_logger, _mem_data, _mem_len, _fmt, ...) \
700 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Info, (_logger), (_mem_data), (_mem_len), (_fmt), \
702 #define BT_CPPLOGW_MEM_SPEC(_logger, _mem_data, _mem_len, _fmt, ...) \
703 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Warning, (_logger), (_mem_data), (_mem_len), (_fmt), \
705 #define BT_CPPLOGE_MEM_SPEC(_logger, _mem_data, _mem_len, _fmt, ...) \
706 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Error, (_logger), (_mem_data), (_mem_len), (_fmt), \
708 #define BT_CPPLOGF_MEM_SPEC(_logger, _mem_data, _mem_len, _fmt, ...) \
709 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Fatal, (_logger), (_mem_data), (_mem_len), (_fmt), \
713 * BT_CPPLOG_MEM_EX() with specific logging levels and using the default
716 #define BT_CPPLOGT_MEM(_mem_data, _mem_len, _fmt, ...) \
717 BT_CPPLOGT_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__)
718 #define BT_CPPLOGD_MEM(_mem_data, _mem_len, _fmt, ...) \
719 BT_CPPLOGD_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__)
720 #define BT_CPPLOGI_MEM(_mem_data, _mem_len, _fmt, ...) \
721 BT_CPPLOGI_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__)
722 #define BT_CPPLOGW_MEM(_mem_data, _mem_len, _fmt, ...) \
723 BT_CPPLOGW_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__)
724 #define BT_CPPLOGE_MEM(_mem_data, _mem_len, _fmt, ...) \
725 BT_CPPLOGE_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__)
726 #define BT_CPPLOGF_MEM(_mem_data, _mem_len, _fmt, ...) \
727 BT_CPPLOGF_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_fmt), ##__VA_ARGS__)
730 * Calls logMemStrNoThrow() on `_logger` to log using the level `_lvl`
731 * without appending nor throwing.
733 #define BT_CPPLOG_MEM_STR_EX(_lvl, _logger, _mem_data, _mem_len, _msg) \
734 (_logger).logMemStrNoThrow<(_lvl)>(__FILE__, __func__, __LINE__, (_mem_data), (_mem_len), \
738 * BT_CPPLOG_MEM_STR_EX() with specific logging levels.
740 #define BT_CPPLOGT_MEM_STR_SPEC(_logger, _mem_data, _mem_len, _msg) \
741 BT_CPPLOG_MEM_STR_EX(bt2c::Logger::Level::TRACE, (_logger), (_mem_data), (_mem_len), (_msg))
742 #define BT_CPPLOGD_MEM_STR_SPEC(_logger, _mem_data, _mem_len, _msg) \
743 BT_CPPLOG_MEM_STR_EX(bt2c::Logger::Level::DEBUG, (_logger), (_mem_data), (_mem_len), (_msg))
744 #define BT_CPPLOGI_MEM_STR_SPEC(_logger, _mem_data, _mem_len, _msg) \
745 BT_CPPLOG_MEM_STR_EX(bt2c::Logger::Level::INFO, (_logger), (_mem_data), (_mem_len), (_msg))
746 #define BT_CPPLOGW_MEM_STR_SPEC(_logger, _mem_data, _mem_len, _msg) \
747 BT_CPPLOG_MEM_STR_EX(bt2c::Logger::Level::WARNING, (_logger), (_mem_data), (_mem_len), (_msg))
748 #define BT_CPPLOGE_MEM_STR_SPEC(_logger, _mem_data, _mem_len, _msg) \
749 BT_CPPLOG_MEM_STR_EX(bt2c::Logger::Level::Error, (_logger), (_mem_data), (_mem_len), (_msg))
750 #define BT_CPPLOGF_MEM_STR_SPEC(_logger, _mem_data, _mem_len, _msg) \
751 BT_CPPLOG_MEM_STR_EX(bt2c::Logger::Level::FATAL, (_logger), (_mem_data), (_mem_len), (_msg))
754 * BT_CPPLOG_MEM_STR_EX() with specific logging levels and using the
757 #define BT_CPPLOGT_MEM_STR(_mem_data, _mem_len, _msg) \
758 BT_CPPLOGT_MEM_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_msg))
759 #define BT_CPPLOGD_MEM_STR(_mem_data, _mem_len, _msg) \
760 BT_CPPLOGD_MEM_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_msg))
761 #define BT_CPPLOGI_MEM_STR(_mem_data, _mem_len, _msg) \
762 BT_CPPLOGI_MEM_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_msg))
763 #define BT_CPPLOGW_MEM_STR(_mem_data, _mem_len, _msg) \
764 BT_CPPLOGW_MEM_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_msg))
765 #define BT_CPPLOGE_MEM_STR(_mem_data, _mem_len, _msg) \
766 BT_CPPLOGE_MEM_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_msg))
767 #define BT_CPPLOGF_MEM_STR(_mem_data, _mem_len, _msg) \
768 BT_CPPLOGF_MEM_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_mem_data), (_mem_len), (_msg))
771 * Calls logErrnoNoThrow() on `_logger` to log using the level `_lvl`
772 * and initial message `_init_msg` without appending nor throwing.
774 #define BT_CPPLOG_ERRNO_EX(_lvl, _logger, _init_msg, _fmt, ...) \
776 if (G_UNLIKELY((_logger).wouldLog(_lvl))) { \
777 (_logger).logErrnoNoThrow<(_lvl), false>(__FILE__, __func__, __LINE__, (_init_msg), \
778 (_fmt), ##__VA_ARGS__); \
783 * BT_CPPLOG_ERRNO_EX() with specific logging levels.
785 #define BT_CPPLOGT_ERRNO_SPEC(_logger, _init_msg, _fmt, ...) \
786 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Trace, (_logger), (_init_msg), (_fmt), ##__VA_ARGS__)
787 #define BT_CPPLOGD_ERRNO_SPEC(_logger, _init_msg, _fmt, ...) \
788 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Debug, (_logger), (_init_msg), (_fmt), ##__VA_ARGS__)
789 #define BT_CPPLOGI_ERRNO_SPEC(_logger, _init_msg, _fmt, ...) \
790 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Info, (_logger), (_init_msg), (_fmt), ##__VA_ARGS__)
791 #define BT_CPPLOGW_ERRNO_SPEC(_logger, _init_msg, _fmt, ...) \
792 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Warning, (_logger), (_init_msg), (_fmt), ##__VA_ARGS__)
793 #define BT_CPPLOGE_ERRNO_SPEC(_logger, _init_msg, _fmt, ...) \
794 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Error, (_logger), (_init_msg), (_fmt), ##__VA_ARGS__)
795 #define BT_CPPLOGF_ERRNO_SPEC(_logger, _init_msg, _fmt, ...) \
796 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Fatal, (_logger), (_init_msg), (_fmt), ##__VA_ARGS__)
799 * BT_CPPLOG_ERRNO_EX() with specific logging levels and using the
802 #define BT_CPPLOGT_ERRNO(_init_msg, _fmt, ...) \
803 BT_CPPLOGT_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_fmt), ##__VA_ARGS__)
804 #define BT_CPPLOGD_ERRNO(_init_msg, _fmt, ...) \
805 BT_CPPLOGD_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_fmt), ##__VA_ARGS__)
806 #define BT_CPPLOGI_ERRNO(_init_msg, _fmt, ...) \
807 BT_CPPLOGI_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_fmt), ##__VA_ARGS__)
808 #define BT_CPPLOGW_ERRNO(_init_msg, _fmt, ...) \
809 BT_CPPLOGW_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_fmt), ##__VA_ARGS__)
810 #define BT_CPPLOGE_ERRNO(_init_msg, _fmt, ...) \
811 BT_CPPLOGE_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_fmt), ##__VA_ARGS__)
812 #define BT_CPPLOGF_ERRNO(_init_msg, _fmt, ...) \
813 BT_CPPLOGF_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_fmt), ##__VA_ARGS__)
816 * Calls logErrnoStrNoThrow() on `_logger` to log using the level `_lvl`
817 * and initial message `_init_msg` without appending nor throwing.
819 #define BT_CPPLOG_ERRNO_STR_EX(_lvl, _logger, _init_msg, _msg) \
820 (_logger).logErrnoStrNoThrow<(_lvl), false>(__FILE__, __func__, __LINE__, (_init_msg), (_msg))
823 * BT_CPPLOG_ERRNO_STR_EX() with specific logging levels.
825 #define BT_CPPLOGT_ERRNO_STR_SPEC(_logger, _init_msg, _msg) \
826 BT_CPPLOG_ERRNO_STR_EX(bt2c::Logger::Level::Trace, (_logger), (_init_msg), (_msg))
827 #define BT_CPPLOGD_ERRNO_STR_SPEC(_logger, _init_msg, _msg) \
828 BT_CPPLOG_ERRNO_STR_EX(bt2c::Logger::Level::Debug, (_logger), (_init_msg), (_msg))
829 #define BT_CPPLOGI_ERRNO_STR_SPEC(_logger, _init_msg, _msg) \
830 BT_CPPLOG_ERRNO_STR_EX(bt2c::Logger::Level::Info, (_logger), (_init_msg), (_msg))
831 #define BT_CPPLOGW_ERRNO_STR_SPEC(_logger, _init_msg, _msg) \
832 BT_CPPLOG_ERRNO_STR_EX(bt2c::Logger::Level::Warning, (_logger), (_init_msg), (_msg))
833 #define BT_CPPLOGE_ERRNO_STR_SPEC(_logger, _init_msg, _msg) \
834 BT_CPPLOG_ERRNO_STR_EX(bt2c::Logger::Level::Error, (_logger), (_init_msg), (_msg))
835 #define BT_CPPLOGF_ERRNO_STR_SPEC(_logger, _init_msg, _msg) \
836 BT_CPPLOG_ERRNO_STR_EX(bt2c::Logger::Level::Fatal, (_logger), (_init_msg), (_msg))
839 * BT_CPPLOG_ERRNO_STR_EX() with specific logging levels and using the
842 #define BT_CPPLOGT_ERRNO_STR(_init_msg, _msg) \
843 BT_CPPLOGT_ERRNO_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_msg))
844 #define BT_CPPLOGD_ERRNO_STR(_init_msg, _msg) \
845 BT_CPPLOGD_ERRNO_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_msg))
846 #define BT_CPPLOGI_ERRNO_STR(_init_msg, _msg) \
847 BT_CPPLOGI_ERRNO_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_msg))
848 #define BT_CPPLOGW_ERRNO_STR(_init_msg, _msg) \
849 BT_CPPLOGW_ERRNO_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_msg))
850 #define BT_CPPLOGE_ERRNO_STR(_init_msg, _msg) \
851 BT_CPPLOGE_ERRNO_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_msg))
852 #define BT_CPPLOGF_ERRNO_STR(_init_msg, _msg) \
853 BT_CPPLOGF_ERRNO_STR_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_msg))
856 * Calls logErrorAndThrow() on `_logger` to log an error, append a cause
857 * to the error of the current thread, and throw an instance of
860 #define BT_CPPLOGE_APPEND_CAUSE_AND_THROW_SPEC(_logger, _exc_cls, _fmt, ...) \
861 (_logger).logErrorAndThrow<true, _exc_cls>(__FILE__, __func__, __LINE__, (_fmt), ##__VA_ARGS__)
864 * BT_CPPLOGE_APPEND_CAUSE_AND_THROW_SPEC() using the default logger.
866 #define BT_CPPLOGE_APPEND_CAUSE_AND_THROW(_exc_cls, _fmt, ...) \
867 BT_CPPLOGE_APPEND_CAUSE_AND_THROW_SPEC(_BT_CPPLOG_DEF_LOGGER, _exc_cls, (_fmt), ##__VA_ARGS__)
870 * Calls logErrorStrAndThrow() on `_logger` to log an error, append a
871 * cause to the error of the current thread, and throw an instance of
874 #define BT_CPPLOGE_STR_APPEND_CAUSE_AND_THROW_SPEC(_logger, _exc_cls, _msg) \
875 (_logger).logErrorStrAndThrow<true, _exc_cls>(__FILE__, __func__, __LINE__, (_msg))
878 * BT_CPPLOGE_STR_APPEND_CAUSE_AND_THROW_SPEC() using the default
881 #define BT_CPPLOGE_STR_APPEND_CAUSE_AND_THROW(_exc_cls, _msg) \
882 BT_CPPLOGE_STR_APPEND_CAUSE_AND_THROW_SPEC(_BT_CPPLOG_DEF_LOGGER, _exc_cls, (_msg))
885 * Calls logErrorAndRethrow() on `_logger` to log an error, append a
886 * cause to the error of the current thread, and throw an instance of
889 #define BT_CPPLOGE_APPEND_CAUSE_AND_RETHROW_SPEC(_logger, _fmt, ...) \
890 (_logger).logErrorAndRethrow<true>(__FILE__, __func__, __LINE__, (_fmt), ##__VA_ARGS__)
893 * BT_CPPLOGE_APPEND_CAUSE_AND_RETHROW_SPEC() using the default logger.
895 #define BT_CPPLOGE_APPEND_CAUSE_AND_RETHROW(_fmt, ...) \
896 BT_CPPLOGE_APPEND_CAUSE_AND_RETHROW_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
899 * Calls logErrorStrAndRethrow() on `_logger` to log an error, append a
900 * cause to the error of the current thread, and throw an instance of
903 #define BT_CPPLOGE_STR_APPEND_CAUSE_AND_RETHROW_SPEC(_logger, _msg) \
904 (_logger).logErrorStrAndRethrow<true>(__FILE__, __func__, __LINE__, (_msg))
907 * BT_CPPLOGE_STR_APPEND_CAUSE_AND_RETHROW_SPEC() using the default
910 #define BT_CPPLOGE_STR_APPEND_CAUSE_AND_RETHROW(_msg) \
911 BT_CPPLOGE_STR_APPEND_CAUSE_AND_RETHROW_SPEC(_BT_CPPLOG_DEF_LOGGER, (_msg))
914 * Calls logErrorErrnoAndThrow() on `_logger` to log an error, append a
915 * cause to the error of the current thread, and throw an instance of
918 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_THROW_SPEC(_logger, _exc_cls, _init_msg, _fmt, ...) \
919 (_logger).logErrorErrnoAndThrow<true, _exc_cls>(__FILE__, __func__, __LINE__, (_init_msg), \
920 (_fmt), ##__VA_ARGS__)
923 * BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_THROW_SPEC() using the default
926 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_THROW(_exc_cls, _init_msg, _fmt, ...) \
927 BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_THROW_SPEC(_BT_CPPLOG_DEF_LOGGER, _exc_cls, (_init_msg), \
928 (_fmt), ##__VA_ARGS__)
931 * Calls logErrorErrnoStrAndThrow() on `_logger` to log an error, append
932 * a cause to the error of the current thread, and throw an instance of
935 #define BT_CPPLOGE_ERRNO_STR_APPEND_CAUSE_AND_THROW_SPEC(_logger, _exc_cls, _init_msg, _msg) \
936 (_logger).logErrorErrnoStrAndThrow<true, _exc_cls>(__FILE__, __func__, __LINE__, (_init_msg), \
940 * BT_CPPLOGE_ERRNO_STR_APPEND_CAUSE_AND_THROW_SPEC() using the default
943 #define BT_CPPLOGE_ERRNO_STR_APPEND_CAUSE_AND_THROW(_exc_cls, _init_msg, _msg) \
944 BT_CPPLOGE_ERRNO_STR_APPEND_CAUSE_AND_THROW_SPEC(_BT_CPPLOG_DEF_LOGGER, _exc_cls, (_init_msg), \
948 * Calls logErrorErrnoAndRethrow() on `_logger` to log an error, append
949 * a cause to the error of the current thread, and throw an instance of
952 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_RETHROW_SPEC(_logger, _init_msg, _fmt, ...) \
953 (_logger).logErrorErrnoAndRethrow<true>(__FILE__, __func__, __LINE__, (_init_msg), (_fmt), \
957 * BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_RETHROW_SPEC() using the default
960 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_RETHROW(_init_msg, _fmt, ...) \
961 BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_RETHROW_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_fmt), \
965 * Calls logErrorErrnoStrAndRethrow() on `_logger` to log an error,
966 * append a cause to the error of the current thread, and throw an
967 * instance of `_exc_cls`.
969 #define BT_CPPLOGE_ERRNO_STR_APPEND_CAUSE_AND_RETHROW_SPEC(_logger, _init_msg, _msg) \
970 (_logger).logErrorErrnoStrAndRethrow<true>(__FILE__, __func__, __LINE__, (_init_msg), (_msg))
973 * BT_CPPLOGE_ERRNO_STR_APPEND_CAUSE_AND_RETHROW_SPEC() using the
976 #define BT_CPPLOGE_ERRNO_STR_APPEND_CAUSE_AND_RETHROW(_init_msg, _msg) \
977 BT_CPPLOGE_ERRNO_STR_APPEND_CAUSE_AND_RETHROW_SPEC(_BT_CPPLOG_DEF_LOGGER, (_init_msg), (_msg))
979 #endif /* BABELTRACE_CPP_COMMON_BT2C_LOGGING_HPP */