Bitcoin Core 31.99.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// 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
14#include <cstdint>
15#include <source_location>
16#include <string>
17#include <string_view>
18
21{
22public:
26 SourceLocation(const char* func,
27 std::source_location loc = std::source_location::current())
28 : m_func{func}, m_loc{loc} {}
29
30 std::string_view file_name() const { return m_loc.file_name(); }
31 std::uint_least32_t line() const { return m_loc.line(); }
32 std::string_view function_name_short() const { return m_func; }
33
34private:
35 std::string_view m_func;
36 std::source_location m_loc;
37};
38
39namespace util::log {
41using Category = uint64_t;
42
43enum class Level {
44 Trace = 0, // High-volume or detailed logging for development/debugging
45 Debug, // Reasonably noisy logging, but still usable in production
46 Info, // Default
47 Warning,
48 Error,
49};
50
51struct Entry {
54 bool should_ratelimit{false};
56 std::string message;
57};
58
61bool ShouldLog(Category category, Level level);
62
64void Log(Entry entry);
65} // namespace util::log
66
67namespace BCLog {
70} // namespace BCLog
71
72template <typename... Args>
73inline void LogPrintFormatInternal(SourceLocation&& source_loc, BCLog::LogFlags flag, BCLog::Level level, bool should_ratelimit, util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
74{
75 std::string log_msg;
76 try {
77 log_msg = tfm::format(fmt, args...);
78 } catch (tinyformat::format_error& fmterr) {
79 log_msg = "Error \"" + std::string{fmterr.what()} + "\" while formatting log message: " + fmt.fmt;
80 }
82 .category = flag,
83 .level = level,
84 .should_ratelimit = should_ratelimit,
85 .source_loc = std::move(source_loc),
86 .message = std::move(log_msg)});
87}
88
89// Allow __func__ to be used in any context without warnings:
90// NOLINTNEXTLINE(bugprone-lambda-function-name)
91#define LogPrintLevel_(category, level, should_ratelimit, ...) LogPrintFormatInternal(SourceLocation{__func__}, category, level, should_ratelimit, __VA_ARGS__)
92
93// Log unconditionally. Uses basic rate limiting to mitigate disk filling attacks.
94// Be conservative when using functions that unconditionally log to debug.log!
95// It should not be the case that an inbound peer can fill up a user's storage
96// with debug.log entries.
97#define LogInfo(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Info, /*should_ratelimit=*/true, __VA_ARGS__)
98#define LogWarning(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Warning, /*should_ratelimit=*/true, __VA_ARGS__)
99#define LogError(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Error, /*should_ratelimit=*/true, __VA_ARGS__)
100
101// Use a macro instead of a function for conditional logging to prevent
102// evaluating arguments when logging for the category is not enabled.
103
104// Log by prefixing the output with the passed category name and severity level. This logs conditionally if
105// the category is allowed. No rate limiting is applied, because users specifying -debug are assumed to be
106// developers or power users who are aware that -debug may cause excessive disk usage due to logging.
107#define detail_LogIfCategoryAndLevelEnabled(category, level, ...) \
108 do { \
109 if (util::log::ShouldLog((category), (level))) { \
110 bool rate_limit{level >= BCLog::Level::Info}; \
111 Assume(!rate_limit); /*Only called with the levels below*/ \
112 LogPrintLevel_(category, level, rate_limit, __VA_ARGS__); \
113 } \
114 } while (0)
115
116// Log conditionally, prefixing the output with the passed category name.
117#define LogDebug(category, ...) detail_LogIfCategoryAndLevelEnabled(category, BCLog::Level::Debug, __VA_ARGS__)
118#define LogTrace(category, ...) detail_LogIfCategoryAndLevelEnabled(category, BCLog::Level::Trace, __VA_ARGS__)
119
120#endif // BITCOIN_UTIL_LOG_H
ArgsManager & args
Definition: bitcoind.cpp:278
Like std::source_location, but allowing to override the function name.
Definition: log.h:21
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:26
std::string_view function_name_short() const
Definition: log.h:32
std::string_view m_func
Definition: log.h:35
std::source_location m_loc
Definition: log.h:36
std::string_view file_name() const
Definition: log.h:30
std::uint_least32_t line() const
Definition: log.h:31
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:73
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
Definition: log.h:39
void Log(Entry entry)
Send message to be logged.
Definition: logging.cpp:611
Level
Definition: log.h:43
uint64_t Category
Opaque to util::log; interpreted by consumers (e.g., BCLog::LogFlags).
Definition: log.h:41
bool ShouldLog(Category category, Level level)
Return whether messages with specified category and level should be logged.
Definition: logging.cpp:606
A wrapper for a compile-time partially validated format string.
Definition: string.h:94
Definition: log.h:51
SourceLocation source_loc
Definition: log.h:55
bool should_ratelimit
Hint for consumers if this entry should be ratelimited.
Definition: log.h:54
Level level
Definition: log.h:53
std::string message
Definition: log.h:56
Category category
Definition: log.h:52