diff --git a/doc/release-notes-15849.md b/doc/release-notes-15849.md new file mode 100644 index 0000000000..a1df31f250 --- /dev/null +++ b/doc/release-notes-15849.md @@ -0,0 +1,6 @@ +Thread names in logs +-------------------- + +On platforms supporting `thread_local`, log lines can be prefixed with the name +of the thread that caused the log. To enable this behavior, use +`-logthreadnames=1`. diff --git a/src/init.cpp b/src/init.cpp index 408a133e4e..84fb313e96 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -508,6 +508,7 @@ void SetupServerArgs() gArgs.AddArg("-debugexclude=", strprintf("Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories."), false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), false, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-logthreadnames", strprintf("Prepend debug output with name of the originating thread (only available on platforms supporting thread_local) (default: %u)", DEFAULT_LOGTHREADNAMES), false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-mocktime=", "Replace actual time with seconds since epoch (default: 0)", true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-maxsigcachesize=", strprintf("Limit sum of signature cache and script execution cache sizes to MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE), true, OptionsCategory::DEBUG_TEST); @@ -866,6 +867,7 @@ void InitLogging() LogInstance().m_print_to_console = gArgs.GetBoolArg("-printtoconsole", !gArgs.GetBoolArg("-daemon", false)); LogInstance().m_log_timestamps = gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); LogInstance().m_log_time_micros = gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); + LogInstance().m_log_threadnames = gArgs.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES); fLogIPs = gArgs.GetBoolArg("-logips", DEFAULT_LOGIPS); diff --git a/src/logging.cpp b/src/logging.cpp index 36cad6573a..3eda4995db 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -4,8 +4,11 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include +#include + const char * const DEFAULT_DEBUGLOGFILE = "debug.log"; BCLog::Logger& LogInstance() @@ -174,7 +177,7 @@ std::vector ListActiveLogCategories() return ret; } -std::string BCLog::Logger::LogTimestampStr(const std::string &str) +std::string BCLog::Logger::LogTimestampStr(const std::string& str) { std::string strStamped; @@ -196,21 +199,24 @@ std::string BCLog::Logger::LogTimestampStr(const std::string &str) } else strStamped = str; - if (!str.empty() && str[str.size()-1] == '\n') - m_started_new_line = true; - else - m_started_new_line = false; - return strStamped; } void BCLog::Logger::LogPrintStr(const std::string &str) { - std::string strTimestamped = LogTimestampStr(str); + std::string str_prefixed = str; + + if (m_log_threadnames && m_started_new_line) { + str_prefixed.insert(0, "[" + util::ThreadGetInternalName() + "] "); + } + + str_prefixed = LogTimestampStr(str_prefixed); + + m_started_new_line = !str.empty() && str[str.size()-1] == '\n'; if (m_print_to_console) { // print to console - fwrite(strTimestamped.data(), 1, strTimestamped.size(), stdout); + fwrite(str_prefixed.data(), 1, str_prefixed.size(), stdout); fflush(stdout); } if (m_print_to_file) { @@ -218,7 +224,7 @@ void BCLog::Logger::LogPrintStr(const std::string &str) // buffer if we haven't opened the log yet if (m_fileout == nullptr) { - m_msgs_before_open.push_back(strTimestamped); + m_msgs_before_open.push_back(str_prefixed); } else { @@ -232,7 +238,7 @@ void BCLog::Logger::LogPrintStr(const std::string &str) m_fileout = new_fileout; } } - FileWriteStr(strTimestamped, m_fileout); + FileWriteStr(str_prefixed, m_fileout); } } } diff --git a/src/logging.h b/src/logging.h index ac9d0dc0c7..e399d4c307 100644 --- a/src/logging.h +++ b/src/logging.h @@ -19,6 +19,7 @@ static const bool DEFAULT_LOGTIMEMICROS = false; static const bool DEFAULT_LOGIPS = false; static const bool DEFAULT_LOGTIMESTAMPS = true; +static const bool DEFAULT_LOGTHREADNAMES = false; extern const char * const DEFAULT_DEBUGLOGFILE; extern bool fLogIPs; @@ -81,6 +82,7 @@ namespace BCLog { bool m_log_timestamps = DEFAULT_LOGTIMESTAMPS; bool m_log_time_micros = DEFAULT_LOGTIMEMICROS; + bool m_log_threadnames = DEFAULT_LOGTHREADNAMES; fs::path m_file_path; std::atomic m_reopen_file{false};