@@ -37,15 +37,35 @@ extern const char * const DEFAULT_DEBUGLOGFILE;
3737
3838extern bool fLogIPs ;
3939
40+ // / Like std::source_location, but allowing to override the function name.
41+ class SourceLocation
42+ {
43+ public:
44+ // / The func argument must be constructed from the C++11 __func__ macro.
45+ // / Ref: https://en.cppreference.com/w/cpp/language/function.html#func
46+ // / Non-static string literals are not supported.
47+ SourceLocation (const char * func,
48+ std::source_location loc = std::source_location::current())
49+ : m_func{func}, m_loc{loc} {}
50+
51+ std::string_view file_name () const { return m_loc.file_name (); }
52+ std::uint_least32_t line () const { return m_loc.line (); }
53+ std::string_view function_name_short () const { return m_func; }
54+
55+ private:
56+ std::string_view m_func;
57+ std::source_location m_loc;
58+ };
59+
4060struct SourceLocationEqual {
41- bool operator ()(const std::source_location & lhs, const std::source_location & rhs) const noexcept
61+ bool operator ()(const SourceLocation & lhs, const SourceLocation & rhs) const noexcept
4262 {
4363 return lhs.line () == rhs.line () && std::string_view (lhs.file_name ()) == std::string_view (rhs.file_name ());
4464 }
4565};
4666
4767struct SourceLocationHasher {
48- size_t operator ()(const std::source_location & s) const noexcept
68+ size_t operator ()(const SourceLocation & s) const noexcept
4969 {
5070 // Use CSipHasher(0, 0) as a simple way to get uniform distribution.
5171 return size_t (CSipHasher (0 , 0 )
@@ -131,7 +151,7 @@ namespace BCLog {
131151 mutable StdMutex m_mutex;
132152
133153 // ! Stats for each source location that has attempted to log something.
134- std::unordered_map<std::source_location , Stats, SourceLocationHasher, SourceLocationEqual> m_source_locations GUARDED_BY (m_mutex);
154+ std::unordered_map<SourceLocation , Stats, SourceLocationHasher, SourceLocationEqual> m_source_locations GUARDED_BY (m_mutex);
135155 // ! Whether any log locations are suppressed. Cached view on m_source_locations for performance reasons.
136156 std::atomic<bool > m_suppression_active{false };
137157 LogRateLimiter (uint64_t max_bytes, std::chrono::seconds reset_window);
@@ -163,7 +183,7 @@ namespace BCLog {
163183 // ! Consumes `source_loc`'s available bytes corresponding to the size of the (formatted)
164184 // ! `str` and returns its status.
165185 [[nodiscard]] Status Consume (
166- const std::source_location & source_loc,
186+ const SourceLocation & source_loc,
167187 const std::string& str) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
168188 // ! Resets all usage to zero. Called periodically by the scheduler.
169189 void Reset () EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
@@ -178,7 +198,7 @@ namespace BCLog {
178198 SystemClock::time_point now;
179199 std::chrono::seconds mocktime;
180200 std::string str, threadname;
181- std::source_location source_loc;
201+ SourceLocation source_loc;
182202 LogFlags category;
183203 Level level;
184204 };
@@ -206,15 +226,15 @@ namespace BCLog {
206226 /* * Log categories bitfield. */
207227 std::atomic<CategoryMask> m_categories{BCLog::NONE};
208228
209- void FormatLogStrInPlace (std::string& str, LogFlags category, Level level, const std::source_location & source_loc, std::string_view threadname, SystemClock::time_point now, std::chrono::seconds mocktime) const ;
229+ void FormatLogStrInPlace (std::string& str, LogFlags category, Level level, const SourceLocation & source_loc, std::string_view threadname, SystemClock::time_point now, std::chrono::seconds mocktime) const ;
210230
211231 std::string LogTimestampStr (SystemClock::time_point now, std::chrono::seconds mocktime) const ;
212232
213233 /* * Slots that connect to the print signal */
214234 std::list<std::function<void (const std::string&)>> m_print_callbacks GUARDED_BY (m_cs) {};
215235
216236 /* * Send a string to the log output (internal) */
217- void LogPrintStr_ (std::string_view str, std::source_location && source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit)
237+ void LogPrintStr_ (std::string_view str, SourceLocation && source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit)
218238 EXCLUSIVE_LOCKS_REQUIRED(m_cs);
219239
220240 std::string GetLogPrefix (LogFlags category, Level level) const ;
@@ -233,7 +253,7 @@ namespace BCLog {
233253 std::atomic<bool > m_reopen_file{false };
234254
235255 /* * Send a string to the log output */
236- void LogPrintStr (std::string_view str, std::source_location && source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit)
256+ void LogPrintStr (std::string_view str, SourceLocation && source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit)
237257 EXCLUSIVE_LOCKS_REQUIRED(!m_cs);
238258
239259 /* * Returns whether logs will be written to any output */
@@ -347,7 +367,7 @@ static inline bool LogAcceptCategory(BCLog::LogFlags category, BCLog::Level leve
347367bool GetLogCategory (BCLog::LogFlags& flag, std::string_view str);
348368
349369template <typename ... Args>
350- inline void LogPrintFormatInternal (std::source_location && source_loc, BCLog::LogFlags flag, BCLog::Level level, bool should_ratelimit, util::ConstevalFormatString<sizeof ...(Args)> fmt, const Args&... args)
370+ inline void LogPrintFormatInternal (SourceLocation && source_loc, BCLog::LogFlags flag, BCLog::Level level, bool should_ratelimit, util::ConstevalFormatString<sizeof ...(Args)> fmt, const Args&... args)
351371{
352372 if (LogInstance ().Enabled ()) {
353373 std::string log_msg;
@@ -360,7 +380,9 @@ inline void LogPrintFormatInternal(std::source_location&& source_loc, BCLog::Log
360380 }
361381}
362382
363- #define LogPrintLevel_ (category, level, should_ratelimit, ...) LogPrintFormatInternal(std::source_location::current(), category, level, should_ratelimit, __VA_ARGS__)
383+ // Allow __func__ to be used in any context without warnings:
384+ // NOLINTNEXTLINE(bugprone-lambda-function-name)
385+ #define LogPrintLevel_ (category, level, should_ratelimit, ...) LogPrintFormatInternal(SourceLocation{__func__}, category, level, should_ratelimit, __VA_ARGS__)
364386
365387// Log unconditionally. Uses basic rate limiting to mitigate disk filling attacks.
366388// Be conservative when using functions that unconditionally log to debug.log!
0 commit comments