From c3f700feb6f650a7ceb62714f2d8eb0d5f1cb2ae Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 1 Oct 2025 16:14:08 +0000 Subject: [PATCH] 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 . --- src/ipc/capnp/protocol.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/ipc/capnp/protocol.cpp b/src/ipc/capnp/protocol.cpp index 4263aebd284..12b6594c29d 100644 --- a/src/ipc/capnp/protocol.cpp +++ b/src/ipc/capnp/protocol.cpp @@ -30,9 +30,32 @@ namespace ipc { namespace capnp { 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) { - 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); } @@ -64,6 +87,7 @@ public: mp::g_thread_context.thread_name = mp::ThreadName(exe_name); mp::LogOptions opts = { .log_fn = IpcLogFn, + .log_level = GetRequestedIPCLogLevel() }; m_loop.emplace(exe_name, std::move(opts), &m_context); if (ready_fn) ready_fn(); @@ -95,6 +119,7 @@ public: util::ThreadRename("capnp-loop"); mp::LogOptions opts = { .log_fn = IpcLogFn, + .log_level = GetRequestedIPCLogLevel() }; m_loop.emplace(exe_name, std::move(opts), &m_context); m_loop_ref.emplace(*m_loop);