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