Branch data Line data Source code
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 : : // This header works in tandem with `logging/categories.h`
9 : : // to expose the complete logging interface.
10 : : #include <logging/categories.h> // IWYU pragma: export
11 : : #include <tinyformat.h>
12 : : #include <util/check.h>
13 : : #include <util/threadnames.h>
14 : : #include <util/time.h>
15 : :
16 : : #include <cstdint>
17 : : #include <source_location>
18 : : #include <string>
19 : : #include <string_view>
20 : :
21 : : /// Like std::source_location, but allowing to override the function name.
22 : : class SourceLocation
23 : : {
24 : : public:
25 : : /// The func argument must be constructed from the C++11 __func__ macro.
26 : : /// Ref: https://en.cppreference.com/w/cpp/language/function.html#func
27 : : /// Non-static string literals are not supported.
28 : 5692694 : explicit SourceLocation(
29 : : const char* func,
30 : : std::source_location loc = std::source_location::current())
31 [ + - ][ - - : 5692694 : : m_func{func}, m_loc{loc} {}
+ - - - -
- - - - -
+ - + - ]
[ - - - -
- - - - -
- - - - -
- - - - -
- - - + -
+ - + - +
- + - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- + - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - ]
[ + - + -
+ - - - +
- + - - -
- - + - +
- # # # #
# # ][ + -
+ - + - +
- + - + -
- - # # #
# # # #
# ][ - - -
- - - - -
- - - - +
- - - - -
- - - - +
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - + - -
- - - - -
- - - - -
- - - # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ][ # # #
# # # # #
# # # # ]
[ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ][ # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ][ - - +
- + - + -
- - - - +
- - - - -
+ - + - -
- - - #
# ][ # # #
# # # # #
# # # # #
# # # # #
# # # # ]
[ - - - -
+ - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - - - +
- + - + -
+ - - - -
- - - - -
+ - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - +
- - - - -
+ - + - +
- - - - -
+ - - - -
- - - - -
- - - - +
- + - - -
- - - - -
- + - - -
- - - - +
- - - - -
+ - - - +
- + - + -
+ - + - -
- - - - -
+ - + - +
- - - - -
- - - - -
- - - ][ -
- + - - -
+ - ][ # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ][ - - -
- - - - -
- - - - -
- - - - -
- - + - +
- + - - -
- - - - -
- - - - -
- - - - -
- + - - -
- - - - -
- - - - -
+ - - - -
- - - - -
- - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - ]
[ - - - -
- - - - -
- - - - -
- - - - +
- - - - -
- - - - +
- + - + -
- - - - -
- + - + -
+ - - - -
- - - - -
- - - - -
- - - - -
- - - - ]
[ - - + -
+ - ][ + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + -
- - - - -
- - - - -
- - ]
[ + - + - ]
[ - - - -
+ - + - +
- - - + -
- - + - -
- - - + -
+ - + - +
- - - + -
- - + - -
- - - ][ +
- - - - -
- - - - +
- + - + -
- - - - -
- - - + -
+ - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - + - ]
[ + - + -
- - + - +
- + - + -
+ - + - ]
[ - - - -
- - - - -
- - - - -
- - + - +
- - - - -
+ - - - -
- - - - -
+ - + - +
- ]
32 : :
33 [ + - ]: 3364179 : std::string_view file_name() const { return m_loc.file_name(); }
34 [ - - - - : 3364179 : std::uint_least32_t line() const { return m_loc.line(); }
+ - - - -
- - - -
- ]
35 [ - - - - : 3364179 : std::string_view function_name_short() const { return m_func; }
+ - ]
36 : :
37 : : private:
38 : : std::string_view m_func;
39 : : std::source_location m_loc;
40 : : };
41 : :
42 : : namespace util::log {
43 : : /** Opaque to util::log; interpreted by consumers (e.g., BCLog::LogFlags). */
44 : : using Category = uint64_t;
45 : :
46 : : //! Structure and constant for tagging not to rate limit.
47 : : struct NoRateLimitTag {
48 : : explicit NoRateLimitTag() = default;
49 : : };
50 : : inline constexpr NoRateLimitTag NO_RATE_LIMIT{};
51 : :
52 : : enum class Level {
53 : : Trace = 0, // High-volume or detailed logging for development/debugging
54 : : Debug, // Reasonably noisy logging, but still usable in production
55 : : Info, // Default
56 : : Warning,
57 : : Error,
58 : : };
59 : :
60 [ - - ]: 12460088 : struct Entry {
61 : : Category category;
62 : : Level level;
63 : : bool should_ratelimit{false}; //!< Hint for consumers if this entry should be ratelimited
64 : : SystemClock::time_point timestamp{SystemClock::now()};
65 : : std::chrono::seconds mocktime{GetMockTime()};
66 : : std::string thread_name{util::ThreadGetInternalName()};
67 : : SourceLocation source_loc;
68 : : std::string message;
69 : : };
70 : :
71 : : /// Return whether messages with specified category should be debug logged.
72 : : /// Applications using the logging library need to provide this.
73 : : bool ShouldDebugLog(Category category);
74 : :
75 : : /// Return whether messages with specified category should be trace logged.
76 : : /// Applications using the logging library need to provide this.
77 : : bool ShouldTraceLog(Category category);
78 : :
79 : : /** Send message to be logged. Applications using the logging library need to provide this. */
80 : : void Log(Entry entry);
81 : :
82 : : template <typename... Args>
83 [ + - ]: 5692694 : inline void LogPrintFormatInternal_(SourceLocation&& source_loc, BCLog::LogFlags flag, util::log::Level level, bool should_ratelimit, util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
84 : : {
85 [ + - ]: 5692694 : std::string log_msg;
86 : : try {
87 [ + - ]: 5692694 : log_msg = tfm::format(fmt, args...);
88 [ - - ]: 0 : } catch (tinyformat::format_error& fmterr) {
89 [ - - - - : 0 : log_msg = "Error \"" + std::string{fmterr.what()} + "\" while formatting log message: " + fmt.fmt;
- - ]
90 : : }
91 [ + - + - ]: 17078082 : util::log::Log(util::log::Entry{
92 : : .category = flag,
93 : : .level = level,
94 : : .should_ratelimit = should_ratelimit,
95 : : .source_loc = std::move(source_loc),
96 : : .message = std::move(log_msg)});
97 [ + - ]: 17078082 : }
98 : :
99 : : template <typename... Args>
100 : 2269172 : inline void LogPrintFormatInternal(SourceLocation&& source_loc, BCLog::LogFlags flag, util::log::Level level, util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
101 : : {
102 [ + - ][ + - : 2269172 : return LogPrintFormatInternal_(std::move(source_loc), flag, level, /*should_ratelimit=*/true, fmt, args...);
+ - + - -
- - - + -
- - - - ]
[ - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + -
+ - + - ]
[ - - - -
- - - - +
- + - + -
+ - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - +
- - - - -
- - - - -
- - - ][ +
- + - - -
- - - - +
- - - # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ][ - - -
- - - - -
- - - - +
- - - - -
- - - - +
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + -
- - - - -
- - - - -
- - ][ # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ][ -
- - - - -
- - + - -
- - - + -
+ - - - -
- # # # #
# # ][ - -
+ - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - - - +
- + - + -
+ - - - -
- - - - -
+ - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - +
- - - - -
+ - - - -
- - - + -
- - - - -
- - - - -
- - + - -
- + - - -
- - - - +
- + - + -
- - - - ]
[ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ][ - - +
- + - + -
- - + - +
- + - + -
+ - + - +
- - - - -
- - # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ][ #
# # # # #
# # ][ - -
- - - - ]
[ + - - -
- - - - +
- - - - -
- - + - +
- + - - -
+ - + - +
- + - - -
- - - - -
- ][ + - +
- # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ][ - -
+ - + - +
- + - + -
- - + - +
- + - + -
+ - + - ]
[ # # # #
# # # # #
# # # ][ +
- - - - -
- - + - +
- + - - -
- - + - +
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - ][ + -
+ - - - +
- + - + -
+ - + - +
- ]
103 : : }
104 : :
105 : : template <typename... Args>
106 : 3423522 : inline void LogPrintFormatInternal(SourceLocation&& source_loc, BCLog::LogFlags flag, util::log::Level level, util::log::NoRateLimitTag, util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
107 : : {
108 [ - - + - ]: 3423522 : return LogPrintFormatInternal_(std::move(source_loc), flag, level, /*should_ratelimit=*/false, fmt, args...);
[ + - # # ]
[ - - + -
- - # # ]
[ - - - -
- - - - -
- - - + -
+ - - - -
- + - - -
- - - - +
- - - - -
+ - - - +
- + - + -
+ - + - -
- - - - -
- - # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ][ #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ][ # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ][ - - -
- - - - -
- - - - -
- - - + -
- - - - +
- - - - -
- - - - -
- - - -
- ][ # # #
# # # # #
# # # # #
# # # ][ #
# # # # #
# # # # #
# ][ # # #
# # # # #
# # # # #
# ][ - - -
- + - - -
- - ][ # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
[ + - + -
+ - - - +
- + - - -
- - + - +
- ][ - - -
- + - + -
# # # # #
# # # #
# ][ # # #
# # # # #
# # # # #
# # # # #
# # ]
109 : : }
110 : : } // namespace util::log
111 : :
112 : : namespace BCLog {
113 : : //! Alias for compatibility. Prefer util::log::Level over BCLog::Level in new code.
114 : : using Level = util::log::Level;
115 : : } // namespace BCLog
116 : :
117 : : // Allow __func__ to be used in any context without warnings:
118 : : // NOLINTNEXTLINE(bugprone-lambda-function-name)
119 : : #define detail_LogWithSrcLoc(category, level, ...) util::log::LogPrintFormatInternal(SourceLocation{__func__}, category, level, __VA_ARGS__)
120 : :
121 : : // Log unconditionally. Uses basic rate limiting to mitigate disk filling attacks.
122 : : // Be conservative when using functions that unconditionally log to debug.log!
123 : : // It should not be the case that an inbound peer can fill up a user's storage
124 : : // with debug.log entries.
125 : : #define LogInfo(...) detail_LogWithSrcLoc(BCLog::LogFlags::ALL, util::log::Level::Info, __VA_ARGS__)
126 : : #define LogWarning(...) detail_LogWithSrcLoc(BCLog::LogFlags::ALL, util::log::Level::Warning, __VA_ARGS__)
127 : : #define LogError(...) detail_LogWithSrcLoc(BCLog::LogFlags::ALL, util::log::Level::Error, __VA_ARGS__)
128 : :
129 : : // Use a macro instead of a function for conditional logging to prevent
130 : : // evaluating arguments when logging for the category is not enabled.
131 : :
132 : : // Log by prefixing the output with the passed category name and severity level. This logs conditionally if
133 : : // the category is allowed. No rate limiting is applied, because users specifying -debug are assumed to be
134 : : // developers or power users who are aware that -debug may cause excessive disk usage due to logging.
135 : : #define detail_LogIfCategoryAndLevelEnabled(category, shouldlog, level, ...) \
136 : : do { \
137 : : if (shouldlog(category)) { \
138 : : detail_LogWithSrcLoc((category), (level), util::log::NO_RATE_LIMIT, __VA_ARGS__); \
139 : : } \
140 : : } while (0)
141 : :
142 : : // Log conditionally, prefixing the output with the passed category name.
143 : : #define LogDebug(category, ...) detail_LogIfCategoryAndLevelEnabled(category, util::log::ShouldDebugLog, util::log::Level::Debug, __VA_ARGS__)
144 : : #define LogTrace(category, ...) detail_LogIfCategoryAndLevelEnabled(category, util::log::ShouldTraceLog, util::log::Level::Trace, __VA_ARGS__)
145 : :
146 : : #endif // BITCOIN_UTIL_LOG_H
|