Bitcoin Core  31.0.0
P2P Digital Currency
log.h
Go to the documentation of this file.
1 // Copyright (c) The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_UTIL_LOG_H
6 #define BITCOIN_UTIL_LOG_H
7 
8 #include <logging/categories.h> // IWYU pragma: export
9 #include <tinyformat.h>
10 #include <util/check.h>
11 
12 #include <cstdint>
13 #include <source_location>
14 #include <string>
15 #include <string_view>
16 
19 {
20 public:
24  SourceLocation(const char* func,
25  std::source_location loc = std::source_location::current())
26  : m_func{func}, m_loc{loc} {}
27 
28  std::string_view file_name() const { return m_loc.file_name(); }
29  std::uint_least32_t line() const { return m_loc.line(); }
30  std::string_view function_name_short() const { return m_func; }
31 
32 private:
33  std::string_view m_func;
34  std::source_location m_loc;
35 };
36 
37 namespace util::log {
39 using Category = uint64_t;
40 
41 enum class Level {
42  Trace = 0, // High-volume or detailed logging for development/debugging
43  Debug, // Reasonably noisy logging, but still usable in production
44  Info, // Default
45  Warning,
46  Error,
47 };
48 
49 struct Entry {
52  bool should_ratelimit{false};
54  std::string message;
55 };
56 
59 bool ShouldLog(Category category, Level level);
60 
62 void Log(Entry entry);
63 } // namespace util::log
64 
65 namespace BCLog {
68 } // namespace BCLog
69 
70 template <typename... Args>
71 inline void LogPrintFormatInternal(SourceLocation&& source_loc, BCLog::LogFlags flag, BCLog::Level level, bool should_ratelimit, util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
72 {
73  std::string log_msg;
74  try {
75  log_msg = tfm::format(fmt, args...);
76  } catch (tinyformat::format_error& fmterr) {
77  log_msg = "Error \"" + std::string{fmterr.what()} + "\" while formatting log message: " + fmt.fmt;
78  }
80  .category = flag,
81  .level = level,
82  .should_ratelimit = should_ratelimit,
83  .source_loc = std::move(source_loc),
84  .message = std::move(log_msg)});
85 }
86 
87 // Allow __func__ to be used in any context without warnings:
88 // NOLINTNEXTLINE(bugprone-lambda-function-name)
89 #define LogPrintLevel_(category, level, should_ratelimit, ...) LogPrintFormatInternal(SourceLocation{__func__}, category, level, should_ratelimit, __VA_ARGS__)
90 
91 // Log unconditionally. Uses basic rate limiting to mitigate disk filling attacks.
92 // Be conservative when using functions that unconditionally log to debug.log!
93 // It should not be the case that an inbound peer can fill up a user's storage
94 // with debug.log entries.
95 #define LogInfo(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Info, /*should_ratelimit=*/true, __VA_ARGS__)
96 #define LogWarning(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Warning, /*should_ratelimit=*/true, __VA_ARGS__)
97 #define LogError(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Error, /*should_ratelimit=*/true, __VA_ARGS__)
98 
99 // Use a macro instead of a function for conditional logging to prevent
100 // evaluating arguments when logging for the category is not enabled.
101 
102 // Log by prefixing the output with the passed category name and severity level. This logs conditionally if
103 // the category is allowed. No rate limiting is applied, because users specifying -debug are assumed to be
104 // developers or power users who are aware that -debug may cause excessive disk usage due to logging.
105 #define detail_LogIfCategoryAndLevelEnabled(category, level, ...) \
106  do { \
107  if (util::log::ShouldLog((category), (level))) { \
108  bool rate_limit{level >= BCLog::Level::Info}; \
109  Assume(!rate_limit); /*Only called with the levels below*/ \
110  LogPrintLevel_(category, level, rate_limit, __VA_ARGS__); \
111  } \
112  } while (0)
113 
114 // Log conditionally, prefixing the output with the passed category name.
115 #define LogDebug(category, ...) detail_LogIfCategoryAndLevelEnabled(category, BCLog::Level::Debug, __VA_ARGS__)
116 #define LogTrace(category, ...) detail_LogIfCategoryAndLevelEnabled(category, BCLog::Level::Trace, __VA_ARGS__)
117 
118 #endif // BITCOIN_UTIL_LOG_H
Definition: log.h:49
Level
Definition: log.h:41
Category category
Definition: log.h:50
std::string message
Definition: log.h:54
std::string_view function_name_short() const
Definition: log.h:30
LogFlags
Definition: categories.h:14
void format(std::ostream &out, FormatStringCheck< sizeof...(Args)> fmt, const Args &... args)
Format list of arguments to the stream according to given format string.
Definition: tinyformat.h:1079
bool should_ratelimit
Hint for consumers if this entry should be ratelimited.
Definition: log.h:52
void LogPrintFormatInternal(SourceLocation &&source_loc, BCLog::LogFlags flag, BCLog::Level level, bool should_ratelimit, util::ConstevalFormatString< sizeof...(Args)> fmt, const Args &... args)
Definition: log.h:71
std::string_view m_func
Definition: log.h:33
ArgsManager & args
Definition: bitcoind.cpp:277
std::string_view file_name() const
Definition: log.h:28
Definition: log.h:37
Level level
Definition: log.h:51
std::uint_least32_t line() const
Definition: log.h:29
A wrapper for a compile-time partially validated format string.
Definition: base.h:41
SourceLocation(const char *func, std::source_location loc=std::source_location::current())
The func argument must be constructed from the C++11 func macro.
Definition: log.h:24
void Log(Entry entry)
Send message to be logged.
Definition: logging.cpp:611
uint64_t Category
Opaque to util::log; interpreted by consumers (e.g., BCLog::LogFlags).
Definition: log.h:39
Like std::source_location, but allowing to override the function name.
Definition: log.h:18
bool ShouldLog(Category category, Level level)
Return whether messages with specified category and level should be logged.
Definition: logging.cpp:606
std::source_location m_loc
Definition: log.h:34
SourceLocation source_loc
Definition: log.h:53