Changeset View
Changeset View
Standalone View
Standalone View
src/logging.cpp
Show All 32 Lines | BCLog::Logger &LogInstance() { | ||||
static BCLog::Logger *g_logger{new BCLog::Logger()}; | static BCLog::Logger *g_logger{new BCLog::Logger()}; | ||||
return *g_logger; | return *g_logger; | ||||
} | } | ||||
static int FileWriteStr(const std::string &str, FILE *fp) { | static int FileWriteStr(const std::string &str, FILE *fp) { | ||||
return fwrite(str.data(), 1, str.size(), fp); | return fwrite(str.data(), 1, str.size(), fp); | ||||
} | } | ||||
bool BCLog::Logger::OpenDebugLog() { | bool BCLog::Logger::StartLogging() { | ||||
std::lock_guard<std::mutex> scoped_lock(m_file_mutex); | std::lock_guard<std::mutex> scoped_lock(m_cs); | ||||
assert(m_buffering); | |||||
assert(m_fileout == nullptr); | assert(m_fileout == nullptr); | ||||
assert(!m_file_path.empty()); | |||||
if (m_print_to_file) { | |||||
assert(!m_file_path.empty()); | |||||
m_fileout = fsbridge::fopen(m_file_path, "a"); | m_fileout = fsbridge::fopen(m_file_path, "a"); | ||||
if (!m_fileout) { | if (!m_fileout) { | ||||
return false; | return false; | ||||
} | } | ||||
// Unbuffered. | // Unbuffered. | ||||
setbuf(m_fileout, nullptr); | setbuf(m_fileout, nullptr); | ||||
// Add newlines to the logfile to distinguish this execution from the | |||||
// last one. | |||||
FileWriteStr("\n\n\n\n\n", m_fileout); | |||||
} | |||||
// Dump buffered messages from before we opened the log. | // Dump buffered messages from before we opened the log. | ||||
m_buffering = false; | |||||
while (!m_msgs_before_open.empty()) { | while (!m_msgs_before_open.empty()) { | ||||
FileWriteStr(m_msgs_before_open.front(), m_fileout); | const std::string &s = m_msgs_before_open.front(); | ||||
if (m_print_to_file) { | |||||
FileWriteStr(s, m_fileout); | |||||
} | |||||
if (m_print_to_console) { | |||||
fwrite(s.data(), 1, s.size(), stdout); | |||||
} | |||||
m_msgs_before_open.pop_front(); | m_msgs_before_open.pop_front(); | ||||
} | } | ||||
if (m_print_to_console) { | |||||
fflush(stdout); | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
struct CLogCategoryDesc { | struct CLogCategoryDesc { | ||||
BCLog::LogFlags flag; | BCLog::LogFlags flag; | ||||
std::string category; | std::string category; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | std::string BCLog::Logger::LogTimestampStr(const std::string &str) { | ||||
} else { | } else { | ||||
strStamped = str; | strStamped = str; | ||||
} | } | ||||
return strStamped; | return strStamped; | ||||
} | } | ||||
void BCLog::Logger::LogPrintStr(const std::string &str) { | void BCLog::Logger::LogPrintStr(const std::string &str) { | ||||
std::lock_guard<std::mutex> scoped_lock(m_cs); | |||||
std::string str_prefixed = str; | std::string str_prefixed = str; | ||||
if (m_log_threadnames && m_started_new_line) { | if (m_log_threadnames && m_started_new_line) { | ||||
str_prefixed.insert(0, "[" + util::ThreadGetInternalName() + "] "); | str_prefixed.insert(0, "[" + util::ThreadGetInternalName() + "] "); | ||||
} | } | ||||
str_prefixed = LogTimestampStr(str_prefixed); | str_prefixed = LogTimestampStr(str_prefixed); | ||||
m_started_new_line = !str.empty() && str[str.size() - 1] == '\n'; | m_started_new_line = !str.empty() && str[str.size() - 1] == '\n'; | ||||
if (m_buffering) { | |||||
// buffer if we haven't started logging yet | |||||
m_msgs_before_open.push_back(str_prefixed); | |||||
return; | |||||
} | |||||
if (m_print_to_console) { | if (m_print_to_console) { | ||||
// Print to console. | // Print to console. | ||||
fwrite(str_prefixed.data(), 1, str_prefixed.size(), stdout); | fwrite(str_prefixed.data(), 1, str_prefixed.size(), stdout); | ||||
fflush(stdout); | fflush(stdout); | ||||
} | } | ||||
if (m_print_to_file) { | if (m_print_to_file) { | ||||
std::lock_guard<std::mutex> scoped_lock(m_file_mutex); | assert(m_fileout != nullptr); | ||||
// Buffer if we haven't opened the log yet. | |||||
if (m_fileout == nullptr) { | |||||
m_msgs_before_open.push_back(str_prefixed); | |||||
} else { | |||||
// Reopen the log file, if requested. | // Reopen the log file, if requested. | ||||
if (m_reopen_file) { | if (m_reopen_file) { | ||||
m_reopen_file = false; | m_reopen_file = false; | ||||
FILE *new_fileout = fsbridge::fopen(m_file_path, "a"); | FILE *new_fileout = fsbridge::fopen(m_file_path, "a"); | ||||
if (new_fileout) { | if (new_fileout) { | ||||
// unbuffered. | // unbuffered. | ||||
setbuf(m_fileout, nullptr); | setbuf(m_fileout, nullptr); | ||||
fclose(m_fileout); | fclose(m_fileout); | ||||
m_fileout = new_fileout; | m_fileout = new_fileout; | ||||
} | } | ||||
} | } | ||||
FileWriteStr(str_prefixed, m_fileout); | FileWriteStr(str_prefixed, m_fileout); | ||||
} | } | ||||
} | } | ||||
} | |||||
void BCLog::Logger::ShrinkDebugFile() { | void BCLog::Logger::ShrinkDebugFile() { | ||||
// Amount of debug.log to save at end when shrinking (must fit in memory) | // Amount of debug.log to save at end when shrinking (must fit in memory) | ||||
constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000; | constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000; | ||||
assert(!m_file_path.empty()); | assert(!m_file_path.empty()); | ||||
// Scroll debug.log if it's getting too big. | // Scroll debug.log if it's getting too big. | ||||
▲ Show 20 Lines • Show All 73 Lines • Show Last 20 Lines |