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