Merge pull request #7272 from behunin/the-courteous-logger
Logging: Impl refactor
This commit is contained in:
commit
0eacc362dd
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user