347063ab20089e4c063b2fceb3a98e00f5f34787
[babeltrace.git] / src / cpp-common / bt2c / logging.hpp
1 /*
2 * SPDX-FileCopyrightText: 2023 Philippe Proulx <pproulx@efficios.com>
3 * SPDX-License-Identifier: MIT
4 */
5
6 #ifndef BABELTRACE_CPP_COMMON_BT2C_LOGGING_HPP
7 #define BABELTRACE_CPP_COMMON_BT2C_LOGGING_HPP
8
9 #include <cstring>
10 #include <iterator>
11 #include <string>
12 #include <utility>
13 #include <vector>
14
15 #include <glib.h>
16
17 #include <babeltrace2/babeltrace.h>
18
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 "cpp-common/vendor/wise-enum/wise_enum.h"
27 #include "logging/log-api.h"
28
29 #include "aliases.hpp"
30 #include "text-loc-str.hpp"
31
32 namespace bt2c {
33
34 /*
35 * A logger contains an actor (self component class, self component,
36 * self message iterator, or simple module name), a current logging
37 * level, a logging tag, and a current text location string format.
38 *
39 * It offers:
40 *
41 * log():
42 * Logs a normal message.
43 *
44 * logMem():
45 * Logs a message with a hexadecimal view of memory bytes.
46 *
47 * logErrno():
48 * Logs a message with the error message corresponding to the
49 * current value of `errno`.
50 *
51 * logTextLoc():
52 * Logs a message with a text location using the current text
53 * location string format.
54 *
55 * The initial text location string format is
56 * `TextLocStrFmt::LineColNosAndOffset`.
57 *
58 * Change the default text location string format with
59 * textLocStrFmt().
60 *
61 * Some methods have their logError*AndThrow() and logError*AndThrow()
62 * equivalents to append a cause to the error of the current thread
63 * using the correct actor, and then throw or rethrow.
64 *
65 * The logging methods above expect a format string and zero or more
66 * arguments to be formatted with fmt::format().
67 *
68 * Use the BT_CPPLOG*() macros to use `__FILE__`, `__func__`, `__LINE__`
69 * as the file name, function name, and line number.
70 */
71 class Logger final
72 {
73 public:
74 /* clang-format off */
75
76 /* Available log levels */
77 WISE_ENUM_CLASS_MEMBER(Level,
78 (Trace, BT_LOG_TRACE),
79 (Debug, BT_LOG_DEBUG),
80 (Info, BT_LOG_INFO),
81 (Warning, BT_LOG_WARNING),
82 (Error, BT_LOG_ERROR),
83 (Fatal, BT_LOG_FATAL),
84 (None, BT_LOG_NONE)
85 )
86
87 /* clang-format on */
88
89 /*
90 * Builds a logger from the self component class `selfCompCls` using
91 * the tag `tag` and the logging level of `privQueryExec`.
92 */
93 explicit Logger(const bt2::SelfComponentClass selfCompCls,
94 const bt2::PrivateQueryExecutor privQueryExec, std::string tag) noexcept :
95 _mSelfCompCls {selfCompCls},
96 _mLevel {static_cast<Level>(privQueryExec.loggingLevel())}, _mTag {std::move(tag)}
97 {
98 }
99
100 /*
101 * Builds a logger from the self component `selfComp` using the tag
102 * `tag`.
103 */
104 explicit Logger(const bt2::SelfComponent selfComp, std::string tag) noexcept :
105 _mSelfComp {selfComp}, _mLevel {static_cast<Level>(selfComp.loggingLevel())},
106 _mTag {std::move(tag)}
107 {
108 }
109
110 /*
111 * Builds a logger from the self source component `selfComp` using
112 * the tag `tag`.
113 */
114 explicit Logger(const bt2::SelfSourceComponent selfComp, std::string tag) noexcept :
115 Logger {
116 bt2::SelfComponent {bt_self_component_source_as_self_component(selfComp.libObjPtr())},
117 std::move(tag)}
118 {
119 }
120
121 /*
122 * Builds a logger from the self filter component `selfComp` using
123 * the tag `tag`.
124 */
125 explicit Logger(const bt2::SelfFilterComponent selfComp, std::string tag) noexcept :
126 Logger {
127 bt2::SelfComponent {bt_self_component_filter_as_self_component(selfComp.libObjPtr())},
128 std::move(tag)}
129 {
130 }
131
132 /*
133 * Builds a logger from the self sink component `selfComp` using the
134 * tag `tag`.
135 */
136 explicit Logger(const bt2::SelfSinkComponent selfComp, std::string tag) noexcept :
137 Logger {bt2::SelfComponent {bt_self_component_sink_as_self_component(selfComp.libObjPtr())},
138 std::move(tag)}
139 {
140 }
141
142 /*
143 * Builds a logger from the self message iterator `selfMsgIter`
144 * using the tag `tag`.
145 */
146 explicit Logger(const bt2::SelfMessageIterator selfMsgIter, std::string tag) noexcept :
147 _mSelfMsgIter {selfMsgIter},
148 _mLevel {static_cast<Level>(selfMsgIter.component().loggingLevel())}, _mTag {std::move(tag)}
149 {
150 }
151
152 /*
153 * Builds a logger from the module named `moduleName` using the tag
154 * `tag` and logging level `logLevel`.
155 */
156 explicit Logger(std::string moduleName, std::string tag, const Level logLevel) noexcept :
157 _mModuleName {std::move(moduleName)}, _mLevel {logLevel}, _mTag {std::move(tag)}
158 {
159 }
160
161 /*
162 * Builds a logger from another logger `other` using the new tag
163 * `newTag`.
164 */
165 explicit Logger(const Logger& other, std::string newTag) :
166 _mSelfCompCls {other._mSelfCompCls}, _mSelfComp {other._mSelfComp},
167 _mSelfMsgIter {other._mSelfMsgIter}, _mModuleName {other._mModuleName},
168 _mLevel {other._mLevel}, _mTag {std::move(newTag)}, _mTextLocStrFmt {other._mTextLocStrFmt}
169 {
170 }
171
172 /*
173 * Current logging level.
174 */
175 Level level() const noexcept
176 {
177 return _mLevel;
178 }
179
180 /*
181 * Whether or not this logger would log at the level `level`.
182 */
183 bool wouldLog(const Level level) const noexcept
184 {
185 return BT_LOG_ON_CUR_LVL(static_cast<int>(level), static_cast<int>(_mLevel));
186 }
187
188 /*
189 * Whether or not this logger would log at the trace level.
190 */
191 bool wouldLogT() const noexcept
192 {
193 return this->wouldLog(Level::Trace);
194 }
195
196 /*
197 * Whether or not this logger would log at the debug level.
198 */
199 bool wouldLogD() const noexcept
200 {
201 return this->wouldLog(Level::Debug);
202 }
203
204 /*
205 * Whether or not this logger would log at the info level.
206 */
207 bool wouldLogI() const noexcept
208 {
209 return this->wouldLog(Level::Info);
210 }
211
212 /*
213 * Whether or not this logger would log at the warning level.
214 */
215 bool wouldLogW() const noexcept
216 {
217 return this->wouldLog(Level::Warning);
218 }
219
220 /*
221 * Whether or not this logger would log at the error level.
222 */
223 bool wouldLogE() const noexcept
224 {
225 return this->wouldLog(Level::Error);
226 }
227
228 /*
229 * Whether or not this logger would log at the fatal level.
230 */
231 bool wouldLogF() const noexcept
232 {
233 return this->wouldLog(Level::Fatal);
234 }
235
236 /*
237 * Logging tag.
238 */
239 const std::string& tag() const noexcept
240 {
241 return _mTag;
242 }
243
244 /*
245 * Self component class actor, or `bt2s::nullopt` if none.
246 */
247 const bt2s::optional<bt2::SelfComponentClass>& selfCompCls() const noexcept
248 {
249 return _mSelfCompCls;
250 }
251
252 /*
253 * Self component actor, or `bt2s::nullopt` if none.
254 */
255 const bt2s::optional<bt2::SelfComponent>& selfComp() const noexcept
256 {
257 return _mSelfComp;
258 }
259
260 /*
261 * Self message iterator actor, or `bt2s::nullopt` if none.
262 */
263 const bt2s::optional<bt2::SelfMessageIterator>& selfMsgIter() const noexcept
264 {
265 return _mSelfMsgIter;
266 }
267
268 /*
269 * Name of module actor, or `bt2s::nullopt` if none.
270 */
271 const bt2s::optional<std::string>& moduleName() const noexcept
272 {
273 return _mModuleName;
274 }
275
276 /*
277 * Sets the text location string format to be used by logTextLoc(),
278 * logErrorTextLocAndThrow(), and logErrorTextLocAndRethrow() to
279 * `fmt`.
280 */
281 void textLocStrFmt(const TextLocStrFmt fmt) noexcept
282 {
283 _mTextLocStrFmt = fmt;
284 }
285
286 /*
287 * Text location string format used by logTextLoc(),
288 * logErrorTextLocAndThrow(), and logErrorTextLocAndRethrow().
289 */
290 TextLocStrFmt textLocStrFmt() const noexcept
291 {
292 return _mTextLocStrFmt;
293 }
294
295 void appendCauseStr(const char * const fileName, const int lineNo, const char * const initMsg,
296 const char * const msg) const noexcept
297 {
298 if (_mSelfMsgIter) {
299 bt_current_thread_error_append_cause_from_message_iterator(
300 _mSelfMsgIter->libObjPtr(), fileName, lineNo, "%s%s", initMsg, msg);
301 } else if (_mSelfComp) {
302 bt_current_thread_error_append_cause_from_component(_mSelfComp->libObjPtr(), fileName,
303 lineNo, "%s%s", initMsg, msg);
304 } else if (_mSelfCompCls) {
305 bt_current_thread_error_append_cause_from_component_class(
306 _mSelfCompCls->libObjPtr(), fileName, lineNo, "%s%s", initMsg, msg);
307 } else {
308 BT_ASSERT(_mModuleName);
309 bt_current_thread_error_append_cause_from_unknown(_mModuleName->data(), fileName,
310 lineNo, "%s%s", initMsg, msg);
311 }
312 }
313
314 private:
315 struct _StdLogWriter final
316 {
317 static void write(const char * const fileName, const char * const funcName,
318 const unsigned lineNo, const Level level, const char * const tag,
319 ConstBytes, const char * const initMsg, const char * const msg) noexcept
320 {
321 BT_ASSERT_DBG(initMsg && std::strcmp(initMsg, "") == 0);
322 bt_log_write(fileName, funcName, lineNo, static_cast<bt_log_level>(level), tag, msg);
323 }
324 };
325
326 public:
327 /*
328 * Logs using the level `LevelV`.
329 *
330 * This method forwards `fmt` and `args` to fmt::format() to create
331 * the log message.
332 *
333 * If `AppendCauseV` is true, this method also appends a cause to
334 * the error of the current thread using the same message.
335 */
336 template <Level LevelV, bool AppendCauseV, typename... ArgTs>
337 void log(const char * const fileName, const char * const funcName, const unsigned int lineNo,
338 fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
339 {
340 this->_log<_StdLogWriter, LevelV, AppendCauseV>(
341 fileName, funcName, lineNo, {}, "", std::move(fmt), std::forward<ArgTs>(args)...);
342 }
343
344 /*
345 * Like log() with the `Level::Error` level, but also throws a
346 * default-constructed instance of `ExcT`.
347 */
348 template <bool AppendCauseV, typename ExcT, typename... ArgTs>
349 [[noreturn]] void logErrorAndThrow(const char * const fileName, const char * const funcName,
350 const unsigned int lineNo, fmt::format_string<ArgTs...> fmt,
351 ArgTs&&...args) const
352 {
353 this->log<Level::Error, AppendCauseV>(fileName, funcName, lineNo, std::move(fmt),
354 std::forward<ArgTs>(args)...);
355 throw ExcT {};
356 }
357
358 /*
359 * Like log() with the `Level::Error` level, but also rethrows.
360 */
361 template <bool AppendCauseV, typename... ArgTs>
362 [[noreturn]] void logErrorAndRethrow(const char * const fileName, const char * const funcName,
363 const unsigned int lineNo,
364 fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
365 {
366 this->log<Level::Error, AppendCauseV>(fileName, funcName, lineNo, std::move(fmt),
367 std::forward<ArgTs>(args)...);
368 throw;
369 }
370
371 private:
372 struct _InitMsgLogWriter final
373 {
374 static void write(const char * const fileName, const char * const funcName,
375 const unsigned lineNo, const Level level, const char * const tag,
376 ConstBytes, const char * const initMsg, const char * const msg) noexcept
377 {
378 bt_log_write_printf(funcName, fileName, lineNo, static_cast<bt_log_level>(level), tag,
379 "%s%s", initMsg, msg);
380 }
381 };
382
383 public:
384 /*
385 * Logs the message of `errno` using the level `LevelV`.
386 *
387 * The log message starts with `initMsg`, is followed with the
388 * message for `errno`, and then with what fmt::format() creates
389 * given `fmt` and `args`.
390 *
391 * If `AppendCauseV` is true, this method also appends a cause to
392 * the error of the current thread using the same message.
393 */
394 template <Level LevelV, bool AppendCauseV, typename... ArgTs>
395 void logErrno(const char * const fileName, const char * const funcName,
396 const unsigned int lineNo, const char * const initMsg,
397 fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
398 {
399 this->_log<_InitMsgLogWriter, LevelV, AppendCauseV>(
400 fileName, funcName, lineNo, {}, this->_errnoIntroStr(initMsg).c_str(), std::move(fmt),
401 std::forward<ArgTs>(args)...);
402 }
403
404 /*
405 * Like logErrno() with the `Level::Error` level, but also throws a
406 * default-constructed instance of `ExcT`.
407 */
408 template <bool AppendCauseV, typename ExcT, typename... ArgTs>
409 [[noreturn]] void logErrorErrnoAndThrow(const char * const fileName,
410 const char * const funcName, const unsigned int lineNo,
411 const char * const initMsg,
412 fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
413 {
414 this->logErrno<Level::Error, AppendCauseV>(fileName, funcName, lineNo, initMsg,
415 std::move(fmt), std::forward<ArgTs>(args)...);
416 throw ExcT {};
417 }
418
419 /*
420 * Like logErrno() with the `Level::Error` level, but also rethrows.
421 */
422 template <bool AppendCauseV, typename... ArgTs>
423 [[noreturn]] void
424 logErrorErrnoAndRethrow(const char * const fileName, const char * const funcName,
425 const unsigned int lineNo, const char * const initMsg,
426 fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
427 {
428 this->logErrno<Level::Error, AppendCauseV>(fileName, funcName, lineNo, initMsg,
429 std::move(fmt), std::forward<ArgTs>(args)...);
430 throw;
431 }
432
433 /*
434 * Logs the text location of `textLoc` followed with a message using
435 * the level `LevelV`.
436 *
437 * The log message starts with the formatted text location and is
438 * followed with what fmt::format() creates given `fmt` and `args`.
439 *
440 * This method uses the current text location string format
441 * (see textLocStrFmt()) to format `textLoc`.
442 *
443 * If `AppendCauseV` is true, this method also appends a cause to
444 * the error of the current thread using the same message.
445 */
446 template <Level LevelV, bool AppendCauseV, typename... ArgTs>
447 void logTextLoc(const char * const fileName, const char * const funcName,
448 const unsigned int lineNo, const TextLoc& textLoc,
449 fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
450 {
451 this->_log<_InitMsgLogWriter, LevelV, AppendCauseV>(
452 fileName, funcName, lineNo, {}, this->_textLocPrefixStr(textLoc).c_str(), fmt,
453 std::forward<ArgTs>(args)...);
454 }
455
456 /*
457 * Like logTextLoc() with the `Level::Error` level, but also throws
458 * a default-constructed instance of `ExcT`.
459 */
460 template <bool AppendCauseV, typename ExcT, typename... ArgTs>
461 [[noreturn]] void
462 logErrorTextLocAndThrow(const char * const fileName, const char * const funcName,
463 const unsigned int lineNo, const TextLoc& textLoc,
464 fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
465 {
466 this->logTextLoc<Level::Error, AppendCauseV>(fileName, funcName, lineNo, textLoc, fmt,
467 std::forward<ArgTs>(args)...);
468 throw ExcT {};
469 }
470
471 /*
472 * Like logTextLoc() with the `Level::Error` level, but also
473 * rethrows.
474 */
475 template <bool AppendCauseV, typename... ArgTs>
476 [[noreturn]] void
477 logErrorTextLocAndRethrow(const char * const fileName, const char * const funcName,
478 const unsigned int lineNo, const TextLoc& textLoc,
479 fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
480 {
481 this->logTextLoc<Level::Error, AppendCauseV>(fileName, funcName, lineNo, textLoc, fmt,
482 std::forward<ArgTs>(args)...);
483 throw;
484 }
485
486 private:
487 struct _MemLogWriter final
488 {
489 static void write(const char * const fileName, const char * const funcName,
490 const unsigned lineNo, const Level level, const char * const tag,
491 const ConstBytes memData, const char *, const char * const msg) noexcept
492 {
493 bt_log_write_mem(funcName, fileName, lineNo, static_cast<bt_log_level>(level), tag,
494 memData.data(), memData.size(), msg);
495 }
496 };
497
498 public:
499 /*
500 * Logs memory data using the level `LevelV`.
501 *
502 * This method forwards `fmt` and `args` to fmt::format() to create
503 * the log message.
504 */
505 template <Level LevelV, typename... ArgTs>
506 void logMem(const char * const fileName, const char * const funcName, const unsigned int lineNo,
507 const ConstBytes memData, fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
508 {
509 this->_log<_MemLogWriter, LevelV, false>(fileName, funcName, lineNo, memData, "",
510 std::move(fmt), std::forward<ArgTs>(args)...);
511 }
512
513 private:
514 /*
515 * Formats a log message with fmt::format() given `fmt` and `args`,
516 * and then:
517 *
518 * 1. Calls LogWriterT::write() with its arguments to log using the
519 * level `LevelV`.
520 *
521 * 2. If `AppendCauseV` is true, this method also appends a cause to
522 * the error of the current thread using the concatenation of
523 * `initMsg` and `msg` as the message.
524 */
525 template <typename LogWriterT, Level LevelV, bool AppendCauseV, typename... ArgTs>
526 void _log(const char * const fileName, const char * const funcName, const unsigned int lineNo,
527 const ConstBytes memData, const char * const initMsg,
528 fmt::format_string<ArgTs...> fmt, ArgTs&&...args) const
529 {
530 const auto wouldLog = this->wouldLog(LevelV);
531
532 /* Only format arguments if logging or appending an error cause */
533 if (G_UNLIKELY(wouldLog || AppendCauseV)) {
534 /*
535 * Format arguments to our buffer (fmt::format_to() doesn't
536 * append a null character).
537 */
538 _mBuf.clear();
539 fmt::format_to(std::back_inserter(_mBuf), std::move(fmt), std::forward<ArgTs>(args)...);
540 _mBuf.push_back('\0');
541 }
542
543 /* Initial message is required */
544 BT_ASSERT(initMsg);
545
546 /* Log if needed */
547 if (wouldLog) {
548 LogWriterT::write(fileName, funcName, lineNo, LevelV, _mTag.data(), memData, initMsg,
549 _mBuf.data());
550 }
551
552 /* Append an error cause if needed */
553 if (AppendCauseV) {
554 this->appendCauseStr(fileName, lineNo, initMsg, _mBuf.data());
555 }
556 }
557
558 static std::string _errnoIntroStr(const char * const initMsg)
559 {
560 BT_ASSERT(errno != 0);
561 return fmt::format("{}: {}", initMsg, g_strerror(errno));
562 }
563
564 std::string _textLocPrefixStr(const TextLoc& loc) const
565 {
566 return fmt::format("[{}] ", textLocStr(loc, _mTextLocStrFmt));
567 }
568
569 /* Exactly one of the following four members has a value */
570 bt2s::optional<bt2::SelfComponentClass> _mSelfCompCls;
571 bt2s::optional<bt2::SelfComponent> _mSelfComp;
572 bt2s::optional<bt2::SelfMessageIterator> _mSelfMsgIter;
573 bt2s::optional<std::string> _mModuleName;
574
575 /* Current logging level */
576 Level _mLevel;
577
578 /* Logging tag */
579 std::string _mTag;
580
581 /* Current text location string format */
582 TextLocStrFmt _mTextLocStrFmt = TextLocStrFmt::LineColNosAndOffset;
583
584 /* Formatting buffer */
585 mutable std::vector<char> _mBuf;
586 };
587
588 /*
589 * Returns `s` if it's not `nullptr`, or the `(null)` string otherwise.
590 */
591 inline const char *maybeNull(const char * const s) noexcept
592 {
593 return s ? s : "(null)";
594 }
595
596 } /* namespace bt2c */
597
598 /* Internal: default logger name */
599 #define _BT_CPPLOG_DEF_LOGGER _mLogger
600
601 /*
602 * Calls log() on `_logger` to log using the level `_lvl`.
603 */
604 #define BT_CPPLOG_EX(_lvl, _logger, _fmt, ...) \
605 do { \
606 if (G_UNLIKELY((_logger).wouldLog(_lvl))) { \
607 (_logger).template log<(_lvl), false>(__FILE__, __func__, __LINE__, (_fmt), \
608 ##__VA_ARGS__); \
609 } \
610 } while (0)
611
612 /*
613 * BT_CPPLOG_EX() with specific logging levels.
614 */
615 #define BT_CPPLOGT_SPEC(_logger, _fmt, ...) \
616 BT_CPPLOG_EX(bt2c::Logger::Level::Trace, (_logger), (_fmt), ##__VA_ARGS__)
617 #define BT_CPPLOGD_SPEC(_logger, _fmt, ...) \
618 BT_CPPLOG_EX(bt2c::Logger::Level::Debug, (_logger), (_fmt), ##__VA_ARGS__)
619 #define BT_CPPLOGI_SPEC(_logger, _fmt, ...) \
620 BT_CPPLOG_EX(bt2c::Logger::Level::Info, (_logger), (_fmt), ##__VA_ARGS__)
621 #define BT_CPPLOGW_SPEC(_logger, _fmt, ...) \
622 BT_CPPLOG_EX(bt2c::Logger::Level::Warning, (_logger), (_fmt), ##__VA_ARGS__)
623 #define BT_CPPLOGE_SPEC(_logger, _fmt, ...) \
624 BT_CPPLOG_EX(bt2c::Logger::Level::Error, (_logger), (_fmt), ##__VA_ARGS__)
625 #define BT_CPPLOGF_SPEC(_logger, _fmt, ...) \
626 BT_CPPLOG_EX(bt2c::Logger::Level::Fatal, (_logger), (_fmt), ##__VA_ARGS__)
627
628 /*
629 * BT_CPPLOG_EX() with specific logging levels and using the default
630 * logger.
631 */
632 #define BT_CPPLOGT(_fmt, ...) BT_CPPLOGT_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
633 #define BT_CPPLOGD(_fmt, ...) BT_CPPLOGD_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
634 #define BT_CPPLOGI(_fmt, ...) BT_CPPLOGI_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
635 #define BT_CPPLOGW(_fmt, ...) BT_CPPLOGW_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
636 #define BT_CPPLOGE(_fmt, ...) BT_CPPLOGE_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
637 #define BT_CPPLOGF(_fmt, ...) BT_CPPLOGF_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
638
639 /*
640 * Calls logMem() on `_logger` to log using the level `_lvl`.
641 */
642 #define BT_CPPLOG_MEM_EX(_lvl, _logger, _memData, _fmt, ...) \
643 do { \
644 if (G_UNLIKELY((_logger).wouldLog(_lvl))) { \
645 (_logger).template logMem<(_lvl)>(__FILE__, __func__, __LINE__, (_memData), (_fmt), \
646 ##__VA_ARGS__); \
647 } \
648 } while (0)
649
650 /*
651 * BT_CPPLOG_MEM_EX() with specific logging levels.
652 */
653 #define BT_CPPLOGT_MEM_SPEC(_logger, _memData, _fmt, ...) \
654 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Trace, (_logger), (_memData), (_fmt), ##__VA_ARGS__)
655 #define BT_CPPLOGD_MEM_SPEC(_logger, _memData, _fmt, ...) \
656 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Debug, (_logger), (_memData), (_fmt), ##__VA_ARGS__)
657 #define BT_CPPLOGI_MEM_SPEC(_logger, _memData, _fmt, ...) \
658 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Info, (_logger), (_memData), (_fmt), ##__VA_ARGS__)
659 #define BT_CPPLOGW_MEM_SPEC(_logger, _memData, _fmt, ...) \
660 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Warning, (_logger), (_memData), (_fmt), ##__VA_ARGS__)
661 #define BT_CPPLOGE_MEM_SPEC(_logger, _memData, _fmt, ...) \
662 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Error, (_logger), (_memData), (_fmt), ##__VA_ARGS__)
663 #define BT_CPPLOGF_MEM_SPEC(_logger, _memData, _fmt, ...) \
664 BT_CPPLOG_MEM_EX(bt2c::Logger::Level::Fatal, (_logger), (_memData), (_fmt), ##__VA_ARGS__)
665
666 /*
667 * BT_CPPLOG_MEM_EX() with specific logging levels and using the default
668 * logger.
669 */
670 #define BT_CPPLOGT_MEM(_memData, _fmt, ...) \
671 BT_CPPLOGT_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_memData), (_fmt), ##__VA_ARGS__)
672 #define BT_CPPLOGD_MEM(_memData, _fmt, ...) \
673 BT_CPPLOGD_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_memData), (_fmt), ##__VA_ARGS__)
674 #define BT_CPPLOGI_MEM(_memData, _fmt, ...) \
675 BT_CPPLOGI_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_memData), (_fmt), ##__VA_ARGS__)
676 #define BT_CPPLOGW_MEM(_memData, _fmt, ...) \
677 BT_CPPLOGW_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_memData), (_fmt), ##__VA_ARGS__)
678 #define BT_CPPLOGE_MEM(_memData, _fmt, ...) \
679 BT_CPPLOGE_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_memData), (_fmt), ##__VA_ARGS__)
680 #define BT_CPPLOGF_MEM(_memData, _fmt, ...) \
681 BT_CPPLOGF_MEM_SPEC(_BT_CPPLOG_DEF_LOGGER, (_memData), (_fmt), ##__VA_ARGS__)
682
683 /*
684 * Calls logErrno() on `_logger` to log using the level `_lvl` and
685 * initial message `_initMsg`.
686 */
687 #define BT_CPPLOG_ERRNO_EX(_lvl, _logger, _initMsg, _fmt, ...) \
688 do { \
689 if (G_UNLIKELY((_logger).wouldLog(_lvl))) { \
690 (_logger).template logErrno<(_lvl), false>(__FILE__, __func__, __LINE__, (_initMsg), \
691 (_fmt), ##__VA_ARGS__); \
692 } \
693 } while (0)
694
695 /*
696 * BT_CPPLOG_ERRNO_EX() with specific logging levels.
697 */
698 #define BT_CPPLOGT_ERRNO_SPEC(_logger, _initMsg, _fmt, ...) \
699 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Trace, (_logger), (_initMsg), (_fmt), ##__VA_ARGS__)
700 #define BT_CPPLOGD_ERRNO_SPEC(_logger, _initMsg, _fmt, ...) \
701 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Debug, (_logger), (_initMsg), (_fmt), ##__VA_ARGS__)
702 #define BT_CPPLOGI_ERRNO_SPEC(_logger, _initMsg, _fmt, ...) \
703 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Info, (_logger), (_initMsg), (_fmt), ##__VA_ARGS__)
704 #define BT_CPPLOGW_ERRNO_SPEC(_logger, _initMsg, _fmt, ...) \
705 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Warning, (_logger), (_initMsg), (_fmt), ##__VA_ARGS__)
706 #define BT_CPPLOGE_ERRNO_SPEC(_logger, _initMsg, _fmt, ...) \
707 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Error, (_logger), (_initMsg), (_fmt), ##__VA_ARGS__)
708 #define BT_CPPLOGF_ERRNO_SPEC(_logger, _initMsg, _fmt, ...) \
709 BT_CPPLOG_ERRNO_EX(bt2c::Logger::Level::Fatal, (_logger), (_initMsg), (_fmt), ##__VA_ARGS__)
710
711 /*
712 * BT_CPPLOG_ERRNO_EX() with specific logging levels and using the
713 * default logger.
714 */
715 #define BT_CPPLOGT_ERRNO(_initMsg, _fmt, ...) \
716 BT_CPPLOGT_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_initMsg), (_fmt), ##__VA_ARGS__)
717 #define BT_CPPLOGD_ERRNO(_initMsg, _fmt, ...) \
718 BT_CPPLOGD_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_initMsg), (_fmt), ##__VA_ARGS__)
719 #define BT_CPPLOGI_ERRNO(_initMsg, _fmt, ...) \
720 BT_CPPLOGI_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_initMsg), (_fmt), ##__VA_ARGS__)
721 #define BT_CPPLOGW_ERRNO(_initMsg, _fmt, ...) \
722 BT_CPPLOGW_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_initMsg), (_fmt), ##__VA_ARGS__)
723 #define BT_CPPLOGE_ERRNO(_initMsg, _fmt, ...) \
724 BT_CPPLOGE_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_initMsg), (_fmt), ##__VA_ARGS__)
725 #define BT_CPPLOGF_ERRNO(_initMsg, _fmt, ...) \
726 BT_CPPLOGF_ERRNO_SPEC(_BT_CPPLOG_DEF_LOGGER, (_initMsg), (_fmt), ##__VA_ARGS__)
727
728 /*
729 * Calls logTextLoc() on `_logger` to log using the level `_lvl` and
730 * text location `_textLoc`.
731 */
732 #define BT_CPPLOG_TEXT_LOC_EX(_lvl, _logger, _textLoc, _fmt, ...) \
733 do { \
734 if (G_UNLIKELY((_logger).wouldLog(_lvl))) { \
735 (_logger).template logTextLoc<(_lvl), false>(__FILE__, __func__, __LINE__, (_textLoc), \
736 (_fmt), ##__VA_ARGS__); \
737 } \
738 } while (0)
739
740 /*
741 * BT_CPPLOG_TEXT_LOC_EX() with specific logging levels.
742 */
743 #define BT_CPPLOGT_TEXT_LOC_SPEC(_logger, _textLoc, _fmt, ...) \
744 BT_CPPLOG_TEXT_LOC_EX(bt2c::Logger::Level::Trace, (_logger), (_textLoc), (_fmt), ##__VA_ARGS__)
745 #define BT_CPPLOGD_TEXT_LOC_SPEC(_logger, _textLoc, _fmt, ...) \
746 BT_CPPLOG_TEXT_LOC_EX(bt2c::Logger::Level::Debug, (_logger), (_textLoc), (_fmt), ##__VA_ARGS__)
747 #define BT_CPPLOGI_TEXT_LOC_SPEC(_logger, _textLoc, _fmt, ...) \
748 BT_CPPLOG_TEXT_LOC_EX(bt2c::Logger::Level::Info, (_logger), (_textLoc), (_fmt), ##__VA_ARGS__)
749 #define BT_CPPLOGW_TEXT_LOC_SPEC(_logger, _textLoc, _fmt, ...) \
750 BT_CPPLOG_TEXT_LOC_EX(bt2c::Logger::Level::Warning, (_logger), (_textLoc), (_fmt), \
751 ##__VA_ARGS__)
752 #define BT_CPPLOGE_TEXT_LOC_SPEC(_logger, _textLoc, _fmt, ...) \
753 BT_CPPLOG_TEXT_LOC_EX(bt2c::Logger::Level::Error, (_logger), (_textLoc), (_fmt), ##__VA_ARGS__)
754 #define BT_CPPLOGF_TEXT_LOC_SPEC(_logger, _textLoc, _fmt, ...) \
755 BT_CPPLOG_TEXT_LOC_EX(bt2c::Logger::Level::Fatal, (_logger), (_textLoc), (_fmt), ##__VA_ARGS__)
756
757 /*
758 * BT_CPPLOG_TEXT_LOC_EX() with specific logging levels and using the
759 * default logger.
760 */
761 #define BT_CPPLOGT_TEXT_LOC(_textLoc, _fmt, ...) \
762 BT_CPPLOGT_TEXT_LOC_SPEC(_BT_CPPLOG_DEF_LOGGER, (_textLoc), (_fmt), ##__VA_ARGS__)
763 #define BT_CPPLOGD_TEXT_LOC(_textLoc, _fmt, ...) \
764 BT_CPPLOGD_TEXT_LOC_SPEC(_BT_CPPLOG_DEF_LOGGER, (_textLoc), (_fmt), ##__VA_ARGS__)
765 #define BT_CPPLOGI_TEXT_LOC(_textLoc, _fmt, ...) \
766 BT_CPPLOGI_TEXT_LOC_SPEC(_BT_CPPLOG_DEF_LOGGER, (_textLoc), (_fmt), ##__VA_ARGS__)
767 #define BT_CPPLOGW_TEXT_LOC(_textLoc, _fmt, ...) \
768 BT_CPPLOGW_TEXT_LOC_SPEC(_BT_CPPLOG_DEF_LOGGER, (_textLoc), (_fmt), ##__VA_ARGS__)
769 #define BT_CPPLOGE_TEXT_LOC(_textLoc, _fmt, ...) \
770 BT_CPPLOGE_TEXT_LOC_SPEC(_BT_CPPLOG_DEF_LOGGER, (_textLoc), (_fmt), ##__VA_ARGS__)
771 #define BT_CPPLOGF_TEXT_LOC(_textLoc, _fmt, ...) \
772 BT_CPPLOGF_TEXT_LOC_SPEC(_BT_CPPLOG_DEF_LOGGER, (_textLoc), (_fmt), ##__VA_ARGS__)
773
774 /*
775 * Calls log() on `_logger` with the `Error` level to log an error and
776 * append a cause to the error of the current thread.
777 */
778 #define BT_CPPLOGE_APPEND_CAUSE_SPEC(_logger, _fmt, ...) \
779 (_logger).template log<bt2c::Logger::Level::Error, true>(__FILE__, __func__, __LINE__, (_fmt), \
780 ##__VA_ARGS__)
781
782 /*
783 * BT_CPPLOGE_APPEND_CAUSE_SPEC() using the default logger.
784 */
785 #define BT_CPPLOGE_APPEND_CAUSE(_fmt, ...) \
786 BT_CPPLOGE_APPEND_CAUSE_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
787
788 /*
789 * Calls logErrorAndThrow() on `_logger` to log an error, append a cause
790 * to the error of the current thread, and throw an instance of
791 * `_excCls`.
792 */
793 #define BT_CPPLOGE_APPEND_CAUSE_AND_THROW_SPEC(_logger, _excCls, _fmt, ...) \
794 (_logger).template logErrorAndThrow<true, _excCls>(__FILE__, __func__, __LINE__, (_fmt), \
795 ##__VA_ARGS__)
796
797 /*
798 * BT_CPPLOGE_APPEND_CAUSE_AND_THROW_SPEC() using the default logger.
799 */
800 #define BT_CPPLOGE_APPEND_CAUSE_AND_THROW(_excCls, _fmt, ...) \
801 BT_CPPLOGE_APPEND_CAUSE_AND_THROW_SPEC(_BT_CPPLOG_DEF_LOGGER, _excCls, (_fmt), ##__VA_ARGS__)
802
803 /*
804 * Calls logErrorAndRethrow() on `_logger` to log an error, append a
805 * cause to the error of the current thread, and throw an instance of
806 * `_excCls`.
807 */
808 #define BT_CPPLOGE_APPEND_CAUSE_AND_RETHROW_SPEC(_logger, _fmt, ...) \
809 (_logger).template logErrorAndRethrow<true>(__FILE__, __func__, __LINE__, (_fmt), ##__VA_ARGS__)
810
811 /*
812 * BT_CPPLOGE_APPEND_CAUSE_AND_RETHROW_SPEC() using the default logger.
813 */
814 #define BT_CPPLOGE_APPEND_CAUSE_AND_RETHROW(_fmt, ...) \
815 BT_CPPLOGE_APPEND_CAUSE_AND_RETHROW_SPEC(_BT_CPPLOG_DEF_LOGGER, (_fmt), ##__VA_ARGS__)
816
817 /*
818 * Calls logErrno() on `_logger` with the `Level::Error` level to log an
819 * error and append a cause to the error of the current thread.
820 */
821 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE_SPEC(_logger, _initMsg, _fmt, ...) \
822 (_logger).template logErrno<bt2c::Logger::Level::Error, true>( \
823 __FILE__, __func__, __LINE__, (_initMsg), (_fmt), ##__VA_ARGS__)
824
825 /*
826 * BT_CPPLOGE_ERRNO_APPEND_CAUSE_SPEC() using the default logger.
827 */
828 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE(_initMsg, _fmt, ...) \
829 BT_CPPLOGE_ERRNO_APPEND_CAUSE_SPEC(_BT_CPPLOG_DEF_LOGGER, (_initMsg), (_fmt), ##__VA_ARGS__)
830
831 /*
832 * Calls logErrorErrnoAndThrow() on `_logger` to log an error, append a
833 * cause to the error of the current thread, and throw an instance of
834 * `_excCls`.
835 */
836 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_THROW_SPEC(_logger, _excCls, _initMsg, _fmt, ...) \
837 (_logger).template logErrorErrnoAndThrow<true, _excCls>(__FILE__, __func__, __LINE__, \
838 (_initMsg), (_fmt), ##__VA_ARGS__)
839
840 /*
841 * BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_THROW_SPEC() using the default
842 * logger.
843 */
844 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_THROW(_excCls, _initMsg, _fmt, ...) \
845 BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_THROW_SPEC(_BT_CPPLOG_DEF_LOGGER, _excCls, (_initMsg), \
846 (_fmt), ##__VA_ARGS__)
847
848 /*
849 * Calls logErrorErrnoAndRethrow() on `_logger` to log an error, append
850 * a cause to the error of the current thread, and throw an instance of
851 * `_excCls`.
852 */
853 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_RETHROW_SPEC(_logger, _initMsg, _fmt, ...) \
854 (_logger).template logErrorErrnoAndRethrow<true>(__FILE__, __func__, __LINE__, (_initMsg), \
855 (_fmt), ##__VA_ARGS__)
856
857 /*
858 * BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_RETHROW_SPEC() using the default
859 * logger.
860 */
861 #define BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_RETHROW(_initMsg, _fmt, ...) \
862 BT_CPPLOGE_ERRNO_APPEND_CAUSE_AND_RETHROW_SPEC(_BT_CPPLOG_DEF_LOGGER, (_initMsg), (_fmt), \
863 ##__VA_ARGS__)
864
865 /*
866 * Calls logTextLoc() on `_logger` with the `Level::Error` level to log
867 * an error and append a cause to the error of the current thread.
868 */
869 #define BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_SPEC(_logger, _textLoc, _fmt, ...) \
870 (_logger).template logTextLoc<bt2c::Logger::Level::Error, true>( \
871 __FILE__, __func__, __LINE__, (_textLoc), (_fmt), ##__VA_ARGS__)
872
873 /*
874 * BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_SPEC() using the default logger.
875 */
876 #define BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE(_textLoc, _fmt, ...) \
877 BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_SPEC(_BT_CPPLOG_DEF_LOGGER, (_textLoc), (_fmt), ##__VA_ARGS__)
878
879 /*
880 * Calls logErrorErrnoAndThrow() on `_logger` to log an error, append a
881 * cause to the error of the current thread, and throw an instance of
882 * `_excCls`.
883 */
884 #define BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_AND_THROW_SPEC(_logger, _excCls, _textLoc, _fmt, ...) \
885 (_logger).template logErrorTextLocAndThrow<true, _excCls>(__FILE__, __func__, __LINE__, \
886 (_textLoc), (_fmt), ##__VA_ARGS__)
887
888 /*
889 * BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_AND_THROW_SPEC() using the default
890 * logger.
891 */
892 #define BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_AND_THROW(_excCls, _textLoc, _fmt, ...) \
893 BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_AND_THROW_SPEC(_BT_CPPLOG_DEF_LOGGER, _excCls, (_textLoc), \
894 (_fmt), ##__VA_ARGS__)
895
896 /*
897 * Calls logErrorErrnoAndRethrow() on `_logger` to log an error, append
898 * a cause to the error of the current thread, and throw an instance of
899 * `_excCls`.
900 */
901 #define BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_AND_RETHROW_SPEC(_logger, _textLoc, _fmt, ...) \
902 (_logger).template logErrorTextLocAndRethrow<true>(__FILE__, __func__, __LINE__, (_textLoc), \
903 (_fmt), ##__VA_ARGS__)
904
905 /*
906 * BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_AND_RETHROW_SPEC() using the default
907 * logger.
908 */
909 #define BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_AND_RETHROW(_textLoc, _fmt, ...) \
910 BT_CPPLOGE_TEXT_LOC_APPEND_CAUSE_AND_RETHROW_SPEC(_BT_CPPLOG_DEF_LOGGER, (_textLoc), (_fmt), \
911 ##__VA_ARGS__)
912
913 #endif /* BABELTRACE_CPP_COMMON_BT2C_LOGGING_HPP */
This page took 0.06435 seconds and 5 git commands to generate.