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 : : #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 : :
17 : : /// Like std::source_location, but allowing to override the function name.
18 : : class SourceLocation
19 : : {
20 : : public:
21 : : /// The func argument must be constructed from the C++11 __func__ macro.
22 : : /// Ref: https://en.cppreference.com/w/cpp/language/function.html#func
23 : : /// Non-static string literals are not supported.
24 : 5015509 : SourceLocation(const char* func,
25 : : std::source_location loc = std::source_location::current())
26 [ + - ][ + - : 5015509 : : m_func{func}, m_loc{loc} {}
+ - # # #
# ][ - - -
- - - - -
- - - - -
- - - - -
- - - - +
- + - + -
+ - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - + - -
- - - - -
- - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + -
- - + - +
- - - -
- ][ + - +
- + - + -
- - - - +
- + - + -
- - - - -
- - - + -
+ - + - #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
[ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ][ - - -
- - - - -
- - - - -
- - - + -
+ - - - -
- + - - -
- - - - -
- + - + -
+ - # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ][ - - -
- + - + -
+ - # # #
# ][ - - -
- - - - -
- - - - +
- - - - -
- - - - +
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - + - -
- - - - -
- - - - -
- - - ][ +
- + - - -
- - - - +
- - - ][ #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ][ # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ][ - - -
- - - - -
- - - - -
- - - - -
+ - + - -
- + - - -
+ - + - +
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - ]
[ - - + -
- - + - ]
[ - - - -
- - - - -
- - - - -
- - - - -
- + - + -
- - - - -
- - - - -
+ - - - -
- - - - -
- - - - +
- - - - -
- - - - -
- + - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - ][ #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ][ - - -
- + - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- + - - -
+ - + - +
- + - - -
- - - - -
- + - + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - - - -
- + - + -
+ - - - -
- + - - -
- - - - -
- - - - -
+ - + - -
- - - - -
- - + - -
- - - - -
+ - - - -
- - - + -
- - + - +
- + - + -
+ - - - -
- - - + -
+ - + - -
- - - - -
- - - - -
- ][ - - +
- + - ][ -
- + - - -
- - - - -
- - - +
- ][ + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - + - -
- - - - -
- - - - -
- ][ + - -
- + - - -
- - + - +
- + - - -
- - - - -
- + - + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - ][ - -
- - + - +
- + - - -
+ - - - -
- + - + -
+ - + - -
- + - - -
- - ][ + -
+ - - - +
- + - + -
+ - + - +
- # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ][ -
- + - + -
+ - - - -
- + - - -
- - + - +
- - - -
- ]
27 : :
28 [ + - ]: 2591212 : std::string_view file_name() const { return m_loc.file_name(); }
29 [ - - - - : 2591212 : std::uint_least32_t line() const { return m_loc.line(); }
- - - - -
- - - -
- ]
30 [ - - - - : 2591212 : 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 {
38 : : /** Opaque to util::log; interpreted by consumers (e.g., BCLog::LogFlags). */
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 : 5015509 : struct Entry {
50 : : Category category;
51 : : Level level;
52 : : bool should_ratelimit{false}; //!< Hint for consumers if this entry should be ratelimited
53 : : SourceLocation source_loc;
54 : : std::string message;
55 : : };
56 : :
57 : : /** Return whether messages with specified category and level should be logged. Applications using
58 : : * the logging library need to provide this. */
59 : : bool ShouldLog(Category category, Level level);
60 : :
61 : : /** Send message to be logged. Applications using the logging library need to provide this. */
62 : : void Log(Entry entry);
63 : : } // namespace util::log
64 : :
65 : : namespace BCLog {
66 : : //! Alias for compatibility. Prefer util::log::Level over BCLog::Level in new code.
67 : : using Level = util::log::Level;
68 : : } // namespace BCLog
69 : :
70 : : template <typename... Args>
71 [ + - ]: 5015509 : 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 [ + - ]: 5015509 : std::string log_msg;
74 : : try {
75 [ + - ]: 5015509 : log_msg = tfm::format(fmt, args...);
76 [ - - ]: 0 : } catch (tinyformat::format_error& fmterr) {
77 [ - - - - : 0 : log_msg = "Error \"" + std::string{fmterr.what()} + "\" while formatting log message: " + fmt.fmt;
- - ]
78 : : }
79 [ + - ]: 10031018 : util::log::Log(util::log::Entry{
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 : 10031018 : }
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
|