From ffae535a5ca879f7f543335adbd9035340380702 Mon Sep 17 00:00:00 2001 From: Niram7777 Date: Mon, 9 Feb 2026 18:19:39 +0000 Subject: [PATCH] [LOG] group same lines with counter (#4010) * [LOG] group same lines with counter * Log in single line counter * Protect log singleton from ps4 threads * Log always compact --- src/common/logging/backend.cpp | 50 ++++++++++++++++++++++++++++------ src/common/logging/log_entry.h | 1 + 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index d7c816da3..168350b96 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -208,26 +209,41 @@ public: } } + std::unique_lock entry_loc(_mutex); + + if (_last_entry.message == message) { + ++_last_entry.counter; + return; + } + + if (_last_entry.counter >= 2) { + _last_entry.message += " x" + std::to_string(_last_entry.counter); + } + + if (_last_entry.counter >= 1) { + if (Config::getLogType() == "async") { + message_queue.EmplaceWait(_last_entry); + } else { + ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); }); + std::fflush(stdout); + } + } + using std::chrono::duration_cast; using std::chrono::microseconds; using std::chrono::steady_clock; - const Entry entry = { + this->_last_entry = { .timestamp = duration_cast(steady_clock::now() - time_origin), .log_class = log_class, .log_level = log_level, .filename = filename, .line_num = line_num, .function = function, - .message = std::move(message), + .message = message, .thread = Common::GetCurrentThreadName(), + .counter = 1, }; - if (Config::getLogType() == "async") { - message_queue.EmplaceWait(entry); - } else { - ForEachBackend([&entry](auto& backend) { backend.Write(entry); }); - std::fflush(stdout); - } } private: @@ -259,6 +275,22 @@ private: } void StopBackendThread() { + // log last message + if (_last_entry.counter >= 2) { + _last_entry.message += " x" + std::to_string(_last_entry.counter); + } + + if (_last_entry.counter >= 1) { + if (Config::getLogType() == "async") { + message_queue.EmplaceWait(_last_entry); + } else { + ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); }); + std::fflush(stdout); + } + } + + this->_last_entry = {}; + backend_thread.request_stop(); if (backend_thread.joinable()) { backend_thread.join(); @@ -292,6 +324,8 @@ private: MPSCQueue message_queue{}; std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; std::jthread backend_thread; + Entry _last_entry; + std::mutex _mutex; }; } // namespace diff --git a/src/common/logging/log_entry.h b/src/common/logging/log_entry.h index 6c529f878..7b52ad7e1 100644 --- a/src/common/logging/log_entry.h +++ b/src/common/logging/log_entry.h @@ -22,6 +22,7 @@ struct Entry { std::string function; std::string message; std::string thread; + u32 counter = 0; }; } // namespace Common::Log