16#include <unordered_map>
42 return fwrite(str.data(), 1, str.size(), fp);
49 assert(m_fileout ==
nullptr);
59 setbuf(m_fileout,
nullptr);
68 while (!m_msgs_before_open.empty()) {
69 const std::string &s = m_msgs_before_open.front();
75 fwrite(s.data(), 1, s.size(), stdout);
77 for (
const auto &cb : m_print_callbacks) {
81 m_msgs_before_open.pop_front();
93 if (m_fileout !=
nullptr) {
97 m_print_callbacks.clear();
128#ifdef DEBUG_LOCKCONTENTION
138static const std::unordered_map<BCLog::LogFlags, std::string>
141 [](
const std::map<std::string, BCLog::LogFlags> &in) {
142 std::unordered_map<BCLog::LogFlags, std::string> out;
143 for (
const auto &[k, v] : in) {
194 std::vector<LogCategory> ret;
198 .active = WillLogCategory(flag)});
211 std::string strStamped;
213 if (!m_log_timestamps) {
217 if (m_started_new_line) {
220 if (m_log_time_micros) {
221 strStamped.pop_back();
222 strStamped +=
strprintf(
".%06dZ", nTimeMicros % 1000000);
226 strStamped +=
" (mocktime: " +
229 strStamped +=
' ' + str;
247 for (
char ch_in : str) {
248 uint8_t ch = (uint8_t)ch_in;
249 if ((ch >= 32 || ch ==
'\n') && ch !=
'\x7f') {
260 const std::string &logging_function,
261 const std::string &source_file,
262 const int source_line,
269 m_started_new_line) {
286 str_prefixed.insert(0, s);
289 if (m_log_sourcelocations && m_started_new_line) {
290 str_prefixed.insert(0,
"[" +
RemovePrefix(source_file,
"./") +
":" +
292 logging_function +
"] ");
295 if (m_log_threadnames && m_started_new_line) {
299 str_prefixed = LogTimestampStr(str_prefixed);
301 m_started_new_line = !str.empty() && str[str.size() - 1] ==
'\n';
305 m_msgs_before_open.push_back(str_prefixed);
309 if (m_print_to_console) {
311 fwrite(str_prefixed.data(), 1, str_prefixed.size(), stdout);
314 for (
const auto &cb : m_print_callbacks) {
317 if (m_print_to_file) {
318 assert(m_fileout !=
nullptr);
322 m_reopen_file =
false;
326 setbuf(m_fileout,
nullptr);
328 m_fileout = new_fileout;
337 constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000;
339 assert(!m_file_path.empty());
347 log_size = fs::file_size(m_file_path);
348 }
catch (
const fs::filesystem_error &) {
353 if (file && log_size > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10)) {
355 std::vector<char> vch(RECENT_DEBUG_HISTORY_SIZE, 0);
356 if (fseek(file, -((
long)vch.size()), SEEK_END)) {
357 LogPrintf(
"Failed to shrink debug log file: fseek(...) failed\n");
361 int nBytes = fread(vch.data(), 1, vch.size(), file);
366 fwrite(vch.data(), 1, nBytes, file);
369 }
else if (file !=
nullptr) {
375 m_categories |= category;
383 EnableCategory(flag);
388 m_categories &= ~category;
396 DisableCategory(flag);
404 LogPrintf(
"Error trying to log using a category mask instead of an "
405 "explicit category.\n");
409 return (m_categories.load(std::memory_order_relaxed) & category) != 0;
bool WillLogCategory(LogFlags category) const
Return true if log accepts specified category.
std::string LogTimestampStr(const std::string &str)
void DisconnectTestLogger()
Only for testing.
bool DefaultShrinkDebugFile() const
Default for whether ShrinkDebugFile should be run.
void LogPrintStr(const std::string &str, const std::string &logging_function, const std::string &source_file, const int source_line, const BCLog::LogFlags category, const BCLog::Level level)
Send a string to the log output.
std::vector< LogCategory > LogCategoriesList() const
Returns a vector of the log categories in alphabetical order.
void DisableCategory(LogFlags category)
void EnableCategory(LogFlags category)
bool StartLogging()
Start logging (and flush all buffered messages)
std::string LogLevelToStr(BCLog::Level level)
std::string LogCategoryToStr(BCLog::LogFlags category)
static int FileWriteStr(const std::string &str, FILE *fp)
BCLog::Logger & LogInstance()
bool GetLogCategory(BCLog::LogFlags &flag, const std::string &str)
Return true if str parses as a log category and set the flag.
static const std::unordered_map< BCLog::LogFlags, std::string > LOG_CATEGORIES_BY_FLAG
const char *const DEFAULT_DEBUGLOGFILE
static const std::map< std::string, BCLog::LogFlags > LOG_CATEGORIES_BY_STR
static const bool DEFAULT_LOGIPS
std::string LogEscapeMessage(const std::string &str)
Belts and suspenders: make sure outgoing log messages don't contain potentially suspicious characters...
FILE * fopen(const fs::path &p, const char *mode)
const std::string & ThreadGetInternalName()
Get the thread's internal (in-memory) name; used e.g.
std::string RemovePrefix(std::string_view str, std::string_view prefix)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
int64_t GetTimeMicros()
Returns the system time (not mockable)
std::chrono::seconds GetMockTime()
For testing.
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
constexpr int64_t count_seconds(std::chrono::seconds t)