Merge pull request #7272 from behunin/the-courteous-logger

Logging: Impl refactor
master
bunnei 2021-11-13 00:03:54 +07:00 committed by GitHub
commit 0eacc362dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 28 deletions

@ -6,6 +6,7 @@
#include <chrono> #include <chrono>
#include <climits> #include <climits>
#include <exception> #include <exception>
#include <stop_token>
#include <thread> #include <thread>
#include <vector> #include <vector>
@ -186,6 +187,10 @@ public:
initialization_in_progress_suppress_logging = false; initialization_in_progress_suppress_logging = false;
} }
static void Start() {
instance->StartBackendThread();
}
Impl(const Impl&) = delete; Impl(const Impl&) = delete;
Impl& operator=(const Impl&) = delete; Impl& operator=(const Impl&) = delete;
@ -201,7 +206,7 @@ public:
} }
void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, std::string message) { const char* function, std::string&& message) {
if (!filter.CheckMessage(log_class, log_level)) if (!filter.CheckMessage(log_class, log_level))
return; return;
const Entry& entry = const Entry& entry =
@ -211,40 +216,41 @@ public:
private: private:
Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_) Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_)
: filter{filter_}, file_backend{file_backend_filename}, backend_thread{std::thread([this] { : filter{filter_}, file_backend{file_backend_filename} {}
Common::SetCurrentThreadName("yuzu:Log");
Entry entry;
const auto write_logs = [this, &entry]() {
ForEachBackend([&entry](Backend& backend) { backend.Write(entry); });
};
while (true) {
entry = message_queue.PopWait();
if (entry.final_entry) {
break;
}
write_logs();
}
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a
// case where a system is repeatedly spamming logs even on close.
int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100;
while (max_logs_to_write-- && message_queue.Pop(entry)) {
write_logs();
}
})} {}
~Impl() { ~Impl() {
StopBackendThread(); StopBackendThread();
} }
void StartBackendThread() {
backend_thread = std::thread([this] {
Common::SetCurrentThreadName("yuzu:Log");
Entry entry;
const auto write_logs = [this, &entry]() {
ForEachBackend([&entry](Backend& backend) { backend.Write(entry); });
};
while (!stop.stop_requested()) {
entry = message_queue.PopWait(stop.get_token());
if (entry.filename != nullptr) {
write_logs();
}
}
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a
// case where a system is repeatedly spamming logs even on close.
int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100;
while (max_logs_to_write-- && message_queue.Pop(entry)) {
write_logs();
}
});
}
void StopBackendThread() { void StopBackendThread() {
Entry stop_entry{}; stop.request_stop();
stop_entry.final_entry = true;
message_queue.Push(stop_entry);
backend_thread.join(); backend_thread.join();
} }
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
const char* function, std::string message) const { const char* function, std::string&& message) const {
using std::chrono::duration_cast; using std::chrono::duration_cast;
using std::chrono::microseconds; using std::chrono::microseconds;
using std::chrono::steady_clock; using std::chrono::steady_clock;
@ -257,7 +263,6 @@ private:
.line_num = line_nr, .line_num = line_nr,
.function = function, .function = function,
.message = std::move(message), .message = std::move(message),
.final_entry = false,
}; };
} }
@ -278,8 +283,9 @@ private:
ColorConsoleBackend color_console_backend{}; ColorConsoleBackend color_console_backend{};
FileBackend file_backend; FileBackend file_backend;
std::stop_source stop;
std::thread backend_thread; std::thread backend_thread;
MPSCQueue<Entry> message_queue{}; MPSCQueue<Entry, true> message_queue{};
std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
}; };
} // namespace } // namespace
@ -288,6 +294,10 @@ void Initialize() {
Impl::Initialize(); Impl::Initialize();
} }
void Start() {
Impl::Start();
}
void DisableLoggingInTests() { void DisableLoggingInTests() {
initialization_in_progress_suppress_logging = true; initialization_in_progress_suppress_logging = true;
} }

@ -14,6 +14,8 @@ class Filter;
/// Initializes the logging system. This should be the first thing called in main. /// Initializes the logging system. This should be the first thing called in main.
void Initialize(); void Initialize();
void Start();
void DisableLoggingInTests(); void DisableLoggingInTests();
/** /**

@ -22,7 +22,6 @@ struct Entry {
unsigned int line_num = 0; unsigned int line_num = 0;
std::string function; std::string function;
std::string message; std::string message;
bool final_entry = false;
}; };
} // namespace Common::Log } // namespace Common::Log

@ -299,6 +299,8 @@ GMainWindow::GMainWindow()
SDL_EnableScreenSaver(); SDL_EnableScreenSaver();
#endif #endif
Common::Log::Start();
QStringList args = QApplication::arguments(); QStringList args = QApplication::arguments();
if (args.size() < 2) { if (args.size() < 2) {