Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
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// 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 <atomic>
17#include <cstdint>
18#include <source_location>
19#include <string>
20#include <string_view>
21
24{
25public:
30 const char* func,
31 std::source_location loc = std::source_location::current())
32 : m_func{func}, m_loc{loc} {}
33
34 std::string_view file_name() const { return m_loc.file_name(); }
35 std::uint_least32_t line() const { return m_loc.line(); }
36 std::string_view function_name_short() const { return m_func; }
37
38private:
39 std::string_view m_func;
40 std::source_location m_loc;
41};
42
43namespace util::log {
46
49 explicit NoRateLimitTag() = default;
50};
51inline constexpr NoRateLimitTag NO_RATE_LIMIT{};
52
53enum class Level {
54 Trace = 0, // High-volume or detailed logging for development/debugging
55 Debug, // Reasonably noisy logging, but still usable in production
56 Info, // Default
57 Warning,
58 Error,
59};
60
61struct Entry {
64 bool should_ratelimit{false};
65 SystemClock::time_point timestamp{SystemClock::now()};
66 std::chrono::seconds mocktime{GetMockTime()};
69 std::string message;
70};
71
74bool ShouldDebugLog(Category category);
75
78bool ShouldTraceLog(Category category);
79
81void Log(Entry entry);
82
85template <unsigned num_params>
87 consteval FormatString(const char* str) : util::ConstevalFormatString<num_params>{str}
88 {
89 if (std::string_view{str}.ends_with('\n')) throw "Format string must not end with a newline";
90 }
91};
92
93template <typename... Args>
94inline void LogPrintFormatInternal_(SourceLocation&& source_loc, BCLog::LogFlags flag, util::log::Level level, bool should_ratelimit, util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
95{
96 std::string log_msg;
97 try {
98 log_msg = tfm::format(fmt, args...);
100 log_msg = "Error \"" + std::string{fmterr.what()} + "\" while formatting log message: " + fmt.fmt;
101 }
103 .category = flag,
104 .level = level,
105 .should_ratelimit = should_ratelimit,
106 .source_loc = std::move(source_loc),
107 .message = std::move(log_msg)});
108}
109
110template <typename... Args>
111inline void LogPrintFormatInternal(SourceLocation&& source_loc, BCLog::LogFlags flag, util::log::Level level, util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
112{
113 return LogPrintFormatInternal_(std::move(source_loc), flag, level, /*should_ratelimit=*/true, fmt, args...);
114}
115
116template <typename... Args>
118{
119 return LogPrintFormatInternal_(std::move(source_loc), flag, level, /*should_ratelimit=*/false, fmt, args...);
120}
121} // namespace util::log
122
123namespace BCLog {
126} // namespace BCLog
127
128// Allow __func__ to be used in any context without warnings:
129// NOLINTNEXTLINE(bugprone-lambda-function-name)
130#define detail_LogWithSrcLoc(category, level, ...) util::log::LogPrintFormatInternal(SourceLocation{__func__}, category, level, __VA_ARGS__)
131
132// Log unconditionally. Uses basic rate limiting to mitigate disk filling attacks.
133// Be conservative when using functions that unconditionally log to debug.log!
134// It should not be the case that an inbound peer can fill up a user's storage
135// with debug.log entries.
136#define LogInfo(...) detail_LogWithSrcLoc(BCLog::LogFlags::ALL, util::log::Level::Info, __VA_ARGS__)
137#define LogWarning(...) detail_LogWithSrcLoc(BCLog::LogFlags::ALL, util::log::Level::Warning, __VA_ARGS__)
138#define LogError(...) detail_LogWithSrcLoc(BCLog::LogFlags::ALL, util::log::Level::Error, __VA_ARGS__)
139
140// Use a macro instead of a function for conditional logging to prevent
141// evaluating arguments when logging for the category is not enabled.
142
143// Log by prefixing the output with the passed category name and severity level. This logs conditionally if
144// the category is allowed. No rate limiting is applied, because users specifying -debug are assumed to be
145// developers or power users who are aware that -debug may cause excessive disk usage due to logging.
146#define detail_LogIfCategoryAndLevelEnabled(category, shouldlog, level, ...) \
147 do { \
148 if (shouldlog(category)) { \
149 detail_LogWithSrcLoc((category), (level), util::log::NO_RATE_LIMIT, __VA_ARGS__); \
150 } \
151 } while (0)
152
153// Log conditionally, prefixing the output with the passed category name.
154#define LogDebug(category, ...) detail_LogIfCategoryAndLevelEnabled(category, util::log::ShouldDebugLog, util::log::Level::Debug, __VA_ARGS__)
155#define LogTrace(category, ...) detail_LogIfCategoryAndLevelEnabled(category, util::log::ShouldTraceLog, util::log::Level::Trace, __VA_ARGS__)
156
157// Log unconditionally the first time this statement is hit, then conditionally afterwards
158#define LogWarnThenDebug(category, ...) \
159 do { \
160 static std::atomic<bool> _warned{false}; \
161 if (!_warned.exchange(true)) { \
162 LogWarning(__VA_ARGS__); \
163 } else { \
164 LogDebug(category, __VA_ARGS__); \
165 } \
166 } while (0)
167
168#endif // BITCOIN_UTIL_LOG_H
ArgsManager & args
Definition bitcoind.cpp:280
Like std::source_location, but allowing to override the function name.
Definition log.h:24
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:29
std::string_view function_name_short() const
Definition log.h:36
std::string_view m_func
Definition log.h:39
std::source_location m_loc
Definition log.h:40
std::string_view file_name() const
Definition log.h:34
std::uint_least32_t line() const
Definition log.h:35
void format(std::ostream &out, FormatStringCheck< sizeof...(Args)> fmt, const Args &... args)
Format list of arguments to the stream according to given format string.
void Log(Entry entry)
Send message to be logged.
Level
Definition log.h:53
bool ShouldDebugLog(Category)
Return whether messages with specified category should be debug logged.
bool ShouldTraceLog(Category)
Return whether messages with specified category should be trace logged.
uint64_t Category
Opaque to util::log; interpreted by consumers (e.g., BCLog::LogFlags).
Definition log.h:45
constexpr NoRateLimitTag NO_RATE_LIMIT
Definition log.h:51
void LogPrintFormatInternal_(SourceLocation &&source_loc, BCLog::LogFlags flag, util::log::Level level, bool should_ratelimit, util::ConstevalFormatString< sizeof...(Args)> fmt, const Args &... args)
Definition log.h:94
void LogPrintFormatInternal(SourceLocation &&source_loc, BCLog::LogFlags flag, util::log::Level level, util::ConstevalFormatString< sizeof...(Args)> fmt, const Args &... args)
Definition log.h:111
std::string ThreadGetInternalName()
Get the thread's internal (in-memory) name; used e.g.
A wrapper for a compile-time partially validated format string.
Definition string.h:96
Definition log.h:61
SourceLocation source_loc
Definition log.h:68
SystemClock::time_point timestamp
Definition log.h:65
bool should_ratelimit
Hint for consumers if this entry should be ratelimited.
Definition log.h:64
std::string thread_name
Definition log.h:67
Level level
Definition log.h:63
std::string message
Definition log.h:69
std::chrono::seconds mocktime
Definition log.h:66
Category category
Definition log.h:62
A format string for a log entry.
Definition log.h:86
consteval FormatString(const char *str)
Definition log.h:87
Structure and constant for tagging not to rate limit.
Definition log.h:48
std::chrono::seconds GetMockTime()
For testing.
Definition time.cpp:59
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82