multiprocess: align our logging with libmultiprocess's

Without this change, logging (even if unused) may account for a
substantial portion of bitcoin-node's and/or client's runtime cpu usage, due
to libmultiprocess's expensive message serialization.

This (along with some recent upstream changes) avoids the overhead by opting
out of log handling for messages that we're not interested in.

Info, Warning, and Error are logged unconditionally to match our behavior
elsewhere. See BCLog::Logger::GetCategoryLogLevel .
This commit is contained in:
Cory Fields 2025-10-01 16:14:08 +00:00
parent 6c1de3ead9
commit c3f700feb6
1 changed files with 26 additions and 1 deletions

View File

@ -30,9 +30,32 @@
namespace ipc { namespace ipc {
namespace capnp { namespace capnp {
namespace { namespace {
BCLog::Level ConvertIPCLogLevel(mp::Log level)
{
switch (level) {
case mp::Log::Trace: return BCLog::Level::Trace;
case mp::Log::Debug: return BCLog::Level::Debug;
case mp::Log::Info: return BCLog::Level::Info;
case mp::Log::Warning: return BCLog::Level::Warning;
case mp::Log::Error: return BCLog::Level::Error;
case mp::Log::Raise: return BCLog::Level::Error;
} // no default case, so the compiler can warn about missing cases
assert(false);
}
mp::Log GetRequestedIPCLogLevel()
{
if (LogAcceptCategory(BCLog::IPC, BCLog::Level::Trace)) return mp::Log::Trace;
if (LogAcceptCategory(BCLog::IPC, BCLog::Level::Debug)) return mp::Log::Debug;
// Info, Warning, and Error are logged unconditionally
return mp::Log::Info;
}
void IpcLogFn(mp::LogMessage message) void IpcLogFn(mp::LogMessage message)
{ {
LogDebug(BCLog::IPC, "%s\n", message.message); LogPrintLevel(BCLog::IPC, ConvertIPCLogLevel(message.level), "%s\n", message.message);
if (message.level == mp::Log::Raise) throw Exception(message.message); if (message.level == mp::Log::Raise) throw Exception(message.message);
} }
@ -64,6 +87,7 @@ public:
mp::g_thread_context.thread_name = mp::ThreadName(exe_name); mp::g_thread_context.thread_name = mp::ThreadName(exe_name);
mp::LogOptions opts = { mp::LogOptions opts = {
.log_fn = IpcLogFn, .log_fn = IpcLogFn,
.log_level = GetRequestedIPCLogLevel()
}; };
m_loop.emplace(exe_name, std::move(opts), &m_context); m_loop.emplace(exe_name, std::move(opts), &m_context);
if (ready_fn) ready_fn(); if (ready_fn) ready_fn();
@ -95,6 +119,7 @@ public:
util::ThreadRename("capnp-loop"); util::ThreadRename("capnp-loop");
mp::LogOptions opts = { mp::LogOptions opts = {
.log_fn = IpcLogFn, .log_fn = IpcLogFn,
.log_level = GetRequestedIPCLogLevel()
}; };
m_loop.emplace(exe_name, std::move(opts), &m_context); m_loop.emplace(exe_name, std::move(opts), &m_context);
m_loop_ref.emplace(*m_loop); m_loop_ref.emplace(*m_loop);