Bitcoin Core 30.99.0
P2P Digital Currency
logging.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-present The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <logging.h>
7#include <memusage.h>
8#include <util/check.h>
9#include <util/fs.h>
10#include <util/string.h>
11#include <util/threadnames.h>
12#include <util/time.h>
13
14#include <array>
15#include <cstring>
16#include <map>
17#include <optional>
18#include <utility>
19
20using util::Join;
22
23const char * const DEFAULT_DEBUGLOGFILE = "debug.log";
25
27{
43 static BCLog::Logger* g_logger{new BCLog::Logger()};
44 return *g_logger;
45}
46
48
49static int FileWriteStr(std::string_view str, FILE *fp)
50{
51 return fwrite(str.data(), 1, str.size(), fp);
52}
53
55{
56 StdLockGuard scoped_lock(m_cs);
57
58 assert(m_buffering);
59 assert(m_fileout == nullptr);
60
61 if (m_print_to_file) {
62 assert(!m_file_path.empty());
63 m_fileout = fsbridge::fopen(m_file_path, "a");
64 if (!m_fileout) {
65 return false;
66 }
67
68 setbuf(m_fileout, nullptr); // unbuffered
69
70 // Add newlines to the logfile to distinguish this execution from the
71 // last one.
72 FileWriteStr("\n\n\n\n\n", m_fileout);
73 }
74
75 // dump buffered messages from before we opened the log
76 m_buffering = false;
77 if (m_buffer_lines_discarded > 0) {
78 LogPrintStr_(strprintf("Early logging buffer overflowed, %d log lines discarded.\n", m_buffer_lines_discarded), SourceLocation{__func__}, BCLog::ALL, Level::Info, /*should_ratelimit=*/false);
79 }
80 while (!m_msgs_before_open.empty()) {
81 const auto& buflog = m_msgs_before_open.front();
82 std::string s{buflog.str};
83 FormatLogStrInPlace(s, buflog.category, buflog.level, buflog.source_loc, buflog.threadname, buflog.now, buflog.mocktime);
84 m_msgs_before_open.pop_front();
85
86 if (m_print_to_file) FileWriteStr(s, m_fileout);
87 if (m_print_to_console) fwrite(s.data(), 1, s.size(), stdout);
88 for (const auto& cb : m_print_callbacks) {
89 cb(s);
90 }
91 }
92 m_cur_buffer_memusage = 0;
93 if (m_print_to_console) fflush(stdout);
94
95 return true;
96}
97
99{
100 StdLockGuard scoped_lock(m_cs);
101 m_buffering = true;
102 if (m_fileout != nullptr) fclose(m_fileout);
103 m_fileout = nullptr;
104 m_print_callbacks.clear();
105 m_max_buffer_memusage = DEFAULT_MAX_LOG_BUFFER;
106 m_cur_buffer_memusage = 0;
107 m_buffer_lines_discarded = 0;
108 m_msgs_before_open.clear();
109}
110
112{
113 {
114 StdLockGuard scoped_lock(m_cs);
115 assert(m_buffering);
116 assert(m_print_callbacks.empty());
117 }
118 m_print_to_file = false;
119 m_print_to_console = false;
120 StartLogging();
121}
122
124{
125 m_categories |= flag;
126}
127
128bool BCLog::Logger::EnableCategory(std::string_view str)
129{
130 BCLog::LogFlags flag;
131 if (!GetLogCategory(flag, str)) return false;
132 EnableCategory(flag);
133 return true;
134}
135
137{
138 m_categories &= ~flag;
139}
140
141bool BCLog::Logger::DisableCategory(std::string_view str)
142{
143 BCLog::LogFlags flag;
144 if (!GetLogCategory(flag, str)) return false;
145 DisableCategory(flag);
146 return true;
147}
148
150{
151 return (m_categories.load(std::memory_order_relaxed) & category) != 0;
152}
153
155{
156 // Log messages at Info, Warning and Error level unconditionally, so that
157 // important troubleshooting information doesn't get lost.
158 if (level >= BCLog::Level::Info) return true;
159
160 if (!WillLogCategory(category)) return false;
161
162 StdLockGuard scoped_lock(m_cs);
163 const auto it{m_category_log_levels.find(category)};
164 return level >= (it == m_category_log_levels.end() ? LogLevel() : it->second);
165}
166
168{
169 return m_categories == BCLog::NONE;
170}
171
172static const std::map<std::string, BCLog::LogFlags, std::less<>> LOG_CATEGORIES_BY_STR{
173 {"net", BCLog::NET},
174 {"tor", BCLog::TOR},
175 {"mempool", BCLog::MEMPOOL},
176 {"http", BCLog::HTTP},
177 {"bench", BCLog::BENCH},
178 {"zmq", BCLog::ZMQ},
179 {"walletdb", BCLog::WALLETDB},
180 {"rpc", BCLog::RPC},
181 {"estimatefee", BCLog::ESTIMATEFEE},
182 {"addrman", BCLog::ADDRMAN},
183 {"selectcoins", BCLog::SELECTCOINS},
184 {"reindex", BCLog::REINDEX},
185 {"cmpctblock", BCLog::CMPCTBLOCK},
186 {"rand", BCLog::RAND},
187 {"prune", BCLog::PRUNE},
188 {"proxy", BCLog::PROXY},
189 {"mempoolrej", BCLog::MEMPOOLREJ},
190 {"libevent", BCLog::LIBEVENT},
191 {"coindb", BCLog::COINDB},
192 {"qt", BCLog::QT},
193 {"leveldb", BCLog::LEVELDB},
194 {"validation", BCLog::VALIDATION},
195 {"i2p", BCLog::I2P},
196 {"ipc", BCLog::IPC},
197#ifdef DEBUG_LOCKCONTENTION
198 {"lock", BCLog::LOCK},
199#endif
200 {"blockstorage", BCLog::BLOCKSTORAGE},
201 {"txreconciliation", BCLog::TXRECONCILIATION},
202 {"scan", BCLog::SCAN},
203 {"txpackages", BCLog::TXPACKAGES},
204 {"kernel", BCLog::KERNEL},
205 {"privatebroadcast", BCLog::PRIVBROADCAST},
206};
207
208static const std::unordered_map<BCLog::LogFlags, std::string> LOG_CATEGORIES_BY_FLAG{
209 // Swap keys and values from LOG_CATEGORIES_BY_STR.
210 [](const auto& in) {
211 std::unordered_map<BCLog::LogFlags, std::string> out;
212 for (const auto& [k, v] : in) {
213 const bool inserted{out.emplace(v, k).second};
214 assert(inserted);
215 }
216 return out;
218};
219
220bool GetLogCategory(BCLog::LogFlags& flag, std::string_view str)
221{
222 if (str.empty() || str == "1" || str == "all") {
223 flag = BCLog::ALL;
224 return true;
225 }
226 auto it = LOG_CATEGORIES_BY_STR.find(str);
227 if (it != LOG_CATEGORIES_BY_STR.end()) {
228 flag = it->second;
229 return true;
230 }
231 return false;
232}
233
235{
236 switch (level) {
238 return "trace";
240 return "debug";
242 return "info";
244 return "warning";
246 return "error";
247 }
248 assert(false);
249}
250
251static std::string LogCategoryToStr(BCLog::LogFlags category)
252{
253 if (category == BCLog::ALL) {
254 return "all";
255 }
256 auto it = LOG_CATEGORIES_BY_FLAG.find(category);
257 assert(it != LOG_CATEGORIES_BY_FLAG.end());
258 return it->second;
259}
260
261static std::optional<BCLog::Level> GetLogLevel(std::string_view level_str)
262{
263 if (level_str == "trace") {
264 return BCLog::Level::Trace;
265 } else if (level_str == "debug") {
266 return BCLog::Level::Debug;
267 } else if (level_str == "info") {
268 return BCLog::Level::Info;
269 } else if (level_str == "warning") {
271 } else if (level_str == "error") {
272 return BCLog::Level::Error;
273 } else {
274 return std::nullopt;
275 }
276}
277
278std::vector<LogCategory> BCLog::Logger::LogCategoriesList() const
279{
280 std::vector<LogCategory> ret;
281 ret.reserve(LOG_CATEGORIES_BY_STR.size());
282 for (const auto& [category, flag] : LOG_CATEGORIES_BY_STR) {
283 ret.push_back(LogCategory{.category = category, .active = WillLogCategory(flag)});
284 }
285 return ret;
286}
287
289static constexpr std::array<BCLog::Level, 3> LogLevelsList()
290{
292}
293
295{
296 const auto& levels = LogLevelsList();
297 return Join(std::vector<BCLog::Level>{levels.begin(), levels.end()}, ", ", [](BCLog::Level level) { return LogLevelToStr(level); });
298}
299
300std::string BCLog::Logger::LogTimestampStr(SystemClock::time_point now, std::chrono::seconds mocktime) const
301{
302 std::string strStamped;
303
304 if (!m_log_timestamps)
305 return strStamped;
306
307 const auto now_seconds{std::chrono::time_point_cast<std::chrono::seconds>(now)};
308 strStamped = FormatISO8601DateTime(TicksSinceEpoch<std::chrono::seconds>(now_seconds));
309 if (m_log_time_micros && !strStamped.empty()) {
310 strStamped.pop_back();
311 strStamped += strprintf(".%06dZ", Ticks<std::chrono::microseconds>(now - now_seconds));
312 }
313 if (mocktime > 0s) {
314 strStamped += " (mocktime: " + FormatISO8601DateTime(count_seconds(mocktime)) + ")";
315 }
316 strStamped += ' ';
317
318 return strStamped;
319}
320
321namespace BCLog {
329 std::string LogEscapeMessage(std::string_view str) {
330 std::string ret;
331 for (char ch_in : str) {
332 uint8_t ch = (uint8_t)ch_in;
333 if ((ch >= 32 || ch == '\n') && ch != '\x7f') {
334 ret += ch_in;
335 } else {
336 ret += strprintf("\\x%02x", ch);
337 }
338 }
339 return ret;
340 }
341} // namespace BCLog
342
344{
345 if (category == LogFlags::NONE) category = LogFlags::ALL;
346
347 const bool has_category{m_always_print_category_level || category != LogFlags::ALL};
348
349 // If there is no category, Info is implied
350 if (!has_category && level == Level::Info) return {};
351
352 std::string s{"["};
353 if (has_category) {
354 s += LogCategoryToStr(category);
355 }
356
357 if (m_always_print_category_level || !has_category || level != Level::Debug) {
358 // If there is a category, Debug is implied, so don't add the level
359
360 // Only add separator if we have a category
361 if (has_category) s += ":";
362 s += Logger::LogLevelToStr(level);
363 }
364
365 s += "] ";
366 return s;
367}
368
369static size_t MemUsage(const BCLog::Logger::BufferedLog& buflog)
370{
371 return memusage::DynamicUsage(buflog.str) +
374}
375
376BCLog::LogRateLimiter::LogRateLimiter(uint64_t max_bytes, std::chrono::seconds reset_window)
377 : m_max_bytes{max_bytes}, m_reset_window{reset_window} {}
378
379std::shared_ptr<BCLog::LogRateLimiter> BCLog::LogRateLimiter::Create(
380 SchedulerFunction&& scheduler_func, uint64_t max_bytes, std::chrono::seconds reset_window)
381{
382 auto limiter{std::shared_ptr<LogRateLimiter>(new LogRateLimiter(max_bytes, reset_window))};
383 std::weak_ptr<LogRateLimiter> weak_limiter{limiter};
384 auto reset = [weak_limiter] {
385 if (auto shared_limiter{weak_limiter.lock()}) shared_limiter->Reset();
386 };
387 scheduler_func(reset, limiter->m_reset_window);
388 return limiter;
389}
390
392 const SourceLocation& source_loc,
393 const std::string& str)
394{
395 StdLockGuard scoped_lock(m_mutex);
396 auto& stats{m_source_locations.try_emplace(source_loc, m_max_bytes).first->second};
397 Status status{stats.m_dropped_bytes > 0 ? Status::STILL_SUPPRESSED : Status::UNSUPPRESSED};
398
399 if (!stats.Consume(str.size()) && status == Status::UNSUPPRESSED) {
400 status = Status::NEWLY_SUPPRESSED;
401 m_suppression_active = true;
402 }
403
404 return status;
405}
406
407void BCLog::Logger::FormatLogStrInPlace(std::string& str, BCLog::LogFlags category, BCLog::Level level, const SourceLocation& source_loc, std::string_view threadname, SystemClock::time_point now, std::chrono::seconds mocktime) const
408{
409 if (!str.ends_with('\n')) str.push_back('\n');
410
411 str.insert(0, GetLogPrefix(category, level));
412
413 if (m_log_sourcelocations) {
414 str.insert(0, strprintf("[%s:%d] [%s] ", RemovePrefixView(source_loc.file_name(), "./"), source_loc.line(), source_loc.function_name_short()));
415 }
416
417 if (m_log_threadnames) {
418 str.insert(0, strprintf("[%s] ", (threadname.empty() ? "unknown" : threadname)));
419 }
420
421 str.insert(0, LogTimestampStr(now, mocktime));
422}
423
424void BCLog::Logger::LogPrintStr(std::string_view str, SourceLocation&& source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit)
425{
426 StdLockGuard scoped_lock(m_cs);
427 return LogPrintStr_(str, std::move(source_loc), category, level, should_ratelimit);
428}
429
430// NOLINTNEXTLINE(misc-no-recursion)
431void BCLog::Logger::LogPrintStr_(std::string_view str, SourceLocation&& source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit)
432{
433 std::string str_prefixed = LogEscapeMessage(str);
434
435 if (m_buffering) {
436 {
437 BufferedLog buf{
438 .now = SystemClock::now(),
439 .mocktime = GetMockTime(),
440 .str = str_prefixed,
441 .threadname = util::ThreadGetInternalName(),
442 .source_loc = std::move(source_loc),
443 .category = category,
444 .level = level,
445 };
446 m_cur_buffer_memusage += MemUsage(buf);
447 m_msgs_before_open.push_back(std::move(buf));
448 }
449
450 while (m_cur_buffer_memusage > m_max_buffer_memusage) {
451 if (m_msgs_before_open.empty()) {
452 m_cur_buffer_memusage = 0;
453 break;
454 }
455 m_cur_buffer_memusage -= MemUsage(m_msgs_before_open.front());
456 m_msgs_before_open.pop_front();
457 ++m_buffer_lines_discarded;
458 }
459
460 return;
461 }
462
463 FormatLogStrInPlace(str_prefixed, category, level, source_loc, util::ThreadGetInternalName(), SystemClock::now(), GetMockTime());
464 bool ratelimit{false};
465 if (should_ratelimit && m_limiter) {
466 auto status{m_limiter->Consume(source_loc, str_prefixed)};
468 // NOLINTNEXTLINE(misc-no-recursion)
469 LogPrintStr_(strprintf(
470 "Excessive logging detected from %s:%d (%s): >%d bytes logged during "
471 "the last time window of %is. Suppressing logging to disk from this "
472 "source location until time window resets. Console logging "
473 "unaffected. Last log entry.",
474 source_loc.file_name(), source_loc.line(), source_loc.function_name_short(),
475 m_limiter->m_max_bytes,
476 Ticks<std::chrono::seconds>(m_limiter->m_reset_window)),
477 SourceLocation{__func__}, LogFlags::ALL, Level::Warning, /*should_ratelimit=*/false); // with should_ratelimit=false, this cannot lead to infinite recursion
478 } else if (status == LogRateLimiter::Status::STILL_SUPPRESSED) {
479 ratelimit = true;
480 }
481 }
482
483 // To avoid confusion caused by dropped log messages when debugging an issue,
484 // we prefix log lines with "[*]" when there are any suppressed source locations.
485 if (m_limiter && m_limiter->SuppressionsActive()) {
486 str_prefixed.insert(0, "[*] ");
487 }
488
489 if (m_print_to_console) {
490 // print to console
491 fwrite(str_prefixed.data(), 1, str_prefixed.size(), stdout);
492 fflush(stdout);
493 }
494 for (const auto& cb : m_print_callbacks) {
495 cb(str_prefixed);
496 }
497 if (m_print_to_file && !ratelimit) {
498 assert(m_fileout != nullptr);
499
500 // reopen the log file, if requested
501 if (m_reopen_file) {
502 m_reopen_file = false;
503 FILE* new_fileout = fsbridge::fopen(m_file_path, "a");
504 if (new_fileout) {
505 setbuf(new_fileout, nullptr); // unbuffered
506 fclose(m_fileout);
507 m_fileout = new_fileout;
508 }
509 }
510 FileWriteStr(str_prefixed, m_fileout);
511 }
512}
513
515{
516 // Amount of debug.log to save at end when shrinking (must fit in memory)
517 constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000;
518
519 assert(!m_file_path.empty());
520
521 // Scroll debug.log if it's getting too big
522 FILE* file = fsbridge::fopen(m_file_path, "r");
523
524 // Special files (e.g. device nodes) may not have a size.
525 size_t log_size = 0;
526 try {
527 log_size = fs::file_size(m_file_path);
528 } catch (const fs::filesystem_error&) {}
529
530 // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE
531 // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes
532 if (file && log_size > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10))
533 {
534 // Restart the file with some of the end
535 std::vector<char> vch(RECENT_DEBUG_HISTORY_SIZE, 0);
536 if (fseek(file, -((long)vch.size()), SEEK_END)) {
537 LogWarning("Failed to shrink debug log file: fseek(...) failed");
538 fclose(file);
539 return;
540 }
541 int nBytes = fread(vch.data(), 1, vch.size(), file);
542 fclose(file);
543
544 file = fsbridge::fopen(m_file_path, "w");
545 if (file)
546 {
547 fwrite(vch.data(), 1, nBytes, file);
548 fclose(file);
549 }
550 }
551 else if (file != nullptr)
552 fclose(file);
553}
554
556{
557 decltype(m_source_locations) source_locations;
558 {
559 StdLockGuard scoped_lock(m_mutex);
560 source_locations.swap(m_source_locations);
561 m_suppression_active = false;
562 }
563 for (const auto& [source_loc, stats] : source_locations) {
564 if (stats.m_dropped_bytes == 0) continue;
566 LogFlags::ALL, Level::Warning, /*should_ratelimit=*/false,
567 "Restarting logging from %s:%d (%s): %d bytes were dropped during the last %ss.",
568 source_loc.file_name(), source_loc.line(), source_loc.function_name_short(),
569 stats.m_dropped_bytes, Ticks<std::chrono::seconds>(m_reset_window));
570 }
571}
572
574{
575 if (bytes > m_available_bytes) {
576 m_dropped_bytes += bytes;
577 m_available_bytes = 0;
578 return false;
579 }
580
581 m_available_bytes -= bytes;
582 return true;
583}
584
585bool BCLog::Logger::SetLogLevel(std::string_view level_str)
586{
587 const auto level = GetLogLevel(level_str);
588 if (!level.has_value() || level.value() > MAX_USER_SETABLE_SEVERITY_LEVEL) return false;
589 m_log_level = level.value();
590 return true;
591}
592
593bool BCLog::Logger::SetCategoryLogLevel(std::string_view category_str, std::string_view level_str)
594{
595 BCLog::LogFlags flag;
596 if (!GetLogCategory(flag, category_str)) return false;
597
598 const auto level = GetLogLevel(level_str);
599 if (!level.has_value() || level.value() > MAX_USER_SETABLE_SEVERITY_LEVEL) return false;
600
601 StdLockGuard scoped_lock(m_cs);
602 m_category_log_levels[flag] = level.value();
603 return true;
604}
int ret
Fixed window rate limiter for logging.
Definition: logging.h:137
static std::shared_ptr< LogRateLimiter > Create(SchedulerFunction &&scheduler_func, uint64_t max_bytes, std::chrono::seconds reset_window)
Definition: logging.cpp:379
std::function< void(std::function< void()>, std::chrono::milliseconds)> SchedulerFunction
Definition: logging.h:161
LogRateLimiter(uint64_t max_bytes, std::chrono::seconds reset_window)
Definition: logging.cpp:376
Status Consume(const SourceLocation &source_loc, const std::string &str) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Consumes source_loc's available bytes corresponding to the size of the (formatted) str and returns it...
Definition: logging.cpp:391
Status
Suppression status of a source log location.
Definition: logging.h:179
void Reset() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Resets all usage to zero. Called periodically by the scheduler.
Definition: logging.cpp:555
static std::string LogLevelToStr(BCLog::Level level)
Returns the string representation of a log level.
Definition: logging.cpp:234
bool WillLogCategory(LogFlags category) const
Definition: logging.cpp:149
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
Definition: logging.cpp:407
void LogPrintStr_(std::string_view str, SourceLocation &&source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit) EXCLUSIVE_LOCKS_REQUIRED(m_cs)
Send a string to the log output (internal)
Definition: logging.cpp:431
std::string LogTimestampStr(SystemClock::time_point now, std::chrono::seconds mocktime) const
Definition: logging.cpp:300
bool DefaultShrinkDebugFile() const
Definition: logging.cpp:167
void SetCategoryLogLevel(const std::unordered_map< LogFlags, Level > &levels) EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Definition: logging.h:314
void SetLogLevel(Level level)
Definition: logging.h:327
bool WillLogCategoryLevel(LogFlags category, Level level) const EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Definition: logging.cpp:154
fs::path m_file_path
Definition: logging.h:253
void DisableLogging() EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Disable logging This offers a slight speedup and slightly smaller memory usage compared to leaving th...
Definition: logging.cpp:111
std::vector< LogCategory > LogCategoriesList() const
Returns a vector of the log categories in alphabetical order.
Definition: logging.cpp:278
bool StartLogging() EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Start logging (and flush all buffered messages)
Definition: logging.cpp:54
void EnableCategory(LogFlags flag)
Definition: logging.cpp:123
std::string GetLogPrefix(LogFlags category, Level level) const
Definition: logging.cpp:343
void DisconnectTestLogger() EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Only for testing.
Definition: logging.cpp:98
std::string LogLevelsString() const
Returns a string with all user-selectable log levels.
Definition: logging.cpp:294
void ShrinkDebugFile()
Definition: logging.cpp:514
bool m_print_to_file
Definition: logging.h:245
bool m_print_to_console
Definition: logging.h:244
void LogPrintStr(std::string_view str, SourceLocation &&source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit) EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Send a string to the log output.
Definition: logging.cpp:424
StdMutex m_cs
Definition: logging.h:208
void DisableCategory(LogFlags flag)
Definition: logging.cpp:136
Like std::source_location, but allowing to override the function name.
Definition: logging.h:42
std::string_view function_name_short() const
Definition: logging.h:53
std::string_view file_name() const
Definition: logging.h:51
std::uint_least32_t line() const
Definition: logging.h:52
static constexpr std::array< BCLog::Level, 3 > LogLevelsList()
Log severity levels that can be selected by the user.
Definition: logging.cpp:289
static int FileWriteStr(std::string_view str, FILE *fp)
Definition: logging.cpp:49
static std::string LogCategoryToStr(BCLog::LogFlags category)
Definition: logging.cpp:251
bool GetLogCategory(BCLog::LogFlags &flag, std::string_view str)
Return true if str parses as a log category and set the flag.
Definition: logging.cpp:220
static size_t MemUsage(const BCLog::Logger::BufferedLog &buflog)
Definition: logging.cpp:369
static const std::map< std::string, BCLog::LogFlags, std::less<> > LOG_CATEGORIES_BY_STR
Definition: logging.cpp:172
BCLog::Logger & LogInstance()
Definition: logging.cpp:26
bool fLogIPs
Definition: logging.cpp:47
static const std::unordered_map< BCLog::LogFlags, std::string > LOG_CATEGORIES_BY_FLAG
Definition: logging.cpp:208
const char *const DEFAULT_DEBUGLOGFILE
Definition: logging.cpp:23
static std::optional< BCLog::Level > GetLogLevel(std::string_view level_str)
Definition: logging.cpp:261
constexpr auto MAX_USER_SETABLE_SEVERITY_LEVEL
Definition: logging.cpp:24
#define LogPrintLevel_(category, level, should_ratelimit,...)
Definition: logging.h:386
#define LogWarning(...)
Definition: logging.h:393
static const bool DEFAULT_LOGIPS
Definition: logging.h:31
Level
Definition: logging.h:122
std::string LogEscapeMessage(std::string_view str)
Belts and suspenders: make sure outgoing log messages don't contain potentially suspicious characters...
Definition: logging.cpp:329
constexpr size_t DEFAULT_MAX_LOG_BUFFER
Definition: logging.h:130
LogFlags
Definition: logging.h:85
@ ESTIMATEFEE
Definition: logging.h:95
@ TXRECONCILIATION
Definition: logging.h:115
@ RAND
Definition: logging.h:100
@ BLOCKSTORAGE
Definition: logging.h:114
@ COINDB
Definition: logging.h:105
@ REINDEX
Definition: logging.h:98
@ TXPACKAGES
Definition: logging.h:117
@ WALLETDB
Definition: logging.h:93
@ PRIVBROADCAST
Definition: logging.h:119
@ SCAN
Definition: logging.h:116
@ ADDRMAN
Definition: logging.h:96
@ ALL
Definition: logging.h:120
@ RPC
Definition: logging.h:94
@ HTTP
Definition: logging.h:90
@ LEVELDB
Definition: logging.h:107
@ NONE
Definition: logging.h:86
@ VALIDATION
Definition: logging.h:108
@ MEMPOOLREJ
Definition: logging.h:103
@ PRUNE
Definition: logging.h:101
@ TOR
Definition: logging.h:88
@ LIBEVENT
Definition: logging.h:104
@ CMPCTBLOCK
Definition: logging.h:99
@ PROXY
Definition: logging.h:102
@ ZMQ
Definition: logging.h:92
@ IPC
Definition: logging.h:110
@ MEMPOOL
Definition: logging.h:89
@ SELECTCOINS
Definition: logging.h:97
@ I2P
Definition: logging.h:109
@ BENCH
Definition: logging.h:91
@ NET
Definition: logging.h:87
@ KERNEL
Definition: logging.h:118
@ QT
Definition: logging.h:106
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:25
bool StartLogging(const ArgsManager &args)
Definition: common.cpp:104
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:31
static size_t MallocUsage(size_t alloc)
Compute the total memory used by allocating alloc bytes.
Definition: memusage.h:52
std::string ThreadGetInternalName()
Get the thread's internal (in-memory) name; used e.g.
Definition: threadnames.cpp:45
std::string_view RemovePrefixView(std::string_view str, std::string_view prefix)
Definition: string.h:182
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
Definition: string.h:205
bool Consume(uint64_t bytes)
Updates internal accounting and returns true if enough available_bytes were remaining.
Definition: logging.cpp:573
std::string threadname
Definition: logging.h:201
SystemClock::time_point now
Definition: logging.h:199
std::string category
Definition: logging.h:79
#define LOCK(cs)
Definition: sync.h:259
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
std::chrono::seconds GetMockTime()
For testing.
Definition: time.cpp:52
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Definition: time.cpp:83
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition: time.h:82
assert(!tx.IsCoinBase())