summaryrefslogtreecommitdiff
path: root/src/common/logging
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/logging')
-rw-r--r--src/common/logging/backend.cpp70
-rw-r--r--src/common/logging/backend.h5
-rw-r--r--src/common/logging/log.h1
3 files changed, 35 insertions, 41 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 12f6d0114..4462ff3fb 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -39,10 +39,10 @@ public:
39 Impl(Impl const&) = delete; 39 Impl(Impl const&) = delete;
40 const Impl& operator=(Impl const&) = delete; 40 const Impl& operator=(Impl const&) = delete;
41 41
42 void PushEntry(Entry e) { 42 void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
43 std::lock_guard<std::mutex> lock(message_mutex); 43 const char* function, std::string message) {
44 message_queue.Push(std::move(e)); 44 message_queue.Push(
45 message_cv.notify_one(); 45 CreateEntry(log_class, log_level, filename, line_num, function, std::move(message)));
46 } 46 }
47 47
48 void AddBackend(std::unique_ptr<Backend> backend) { 48 void AddBackend(std::unique_ptr<Backend> backend) {
@@ -86,15 +86,13 @@ private:
86 } 86 }
87 }; 87 };
88 while (true) { 88 while (true) {
89 { 89 entry = message_queue.PopWait();
90 std::unique_lock<std::mutex> lock(message_mutex); 90 if (entry.final_entry) {
91 message_cv.wait(lock, [&] { return !running || message_queue.Pop(entry); });
92 }
93 if (!running) {
94 break; 91 break;
95 } 92 }
96 write_logs(entry); 93 write_logs(entry);
97 } 94 }
95
98 // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case 96 // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case
99 // where a system is repeatedly spamming logs even on close. 97 // where a system is repeatedly spamming logs even on close.
100 const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100; 98 const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100;
@@ -106,18 +104,36 @@ private:
106 } 104 }
107 105
108 ~Impl() { 106 ~Impl() {
109 running = false; 107 Entry entry;
110 message_cv.notify_one(); 108 entry.final_entry = true;
109 message_queue.Push(entry);
111 backend_thread.join(); 110 backend_thread.join();
112 } 111 }
113 112
114 std::atomic_bool running{true}; 113 Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
115 std::mutex message_mutex, writing_mutex; 114 const char* function, std::string message) const {
116 std::condition_variable message_cv; 115 using std::chrono::duration_cast;
116 using std::chrono::steady_clock;
117
118 Entry entry;
119 entry.timestamp =
120 duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin);
121 entry.log_class = log_class;
122 entry.log_level = log_level;
123 entry.filename = Common::TrimSourcePath(filename);
124 entry.line_num = line_nr;
125 entry.function = function;
126 entry.message = std::move(message);
127
128 return entry;
129 }
130
131 std::mutex writing_mutex;
117 std::thread backend_thread; 132 std::thread backend_thread;
118 std::vector<std::unique_ptr<Backend>> backends; 133 std::vector<std::unique_ptr<Backend>> backends;
119 Common::MPSCQueue<Log::Entry> message_queue; 134 Common::MPSCQueue<Log::Entry> message_queue;
120 Filter filter; 135 Filter filter;
136 std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
121}; 137};
122 138
123void ConsoleBackend::Write(const Entry& entry) { 139void ConsoleBackend::Write(const Entry& entry) {
@@ -232,6 +248,7 @@ void DebuggerBackend::Write(const Entry& entry) {
232 CLS(Render) \ 248 CLS(Render) \
233 SUB(Render, Software) \ 249 SUB(Render, Software) \
234 SUB(Render, OpenGL) \ 250 SUB(Render, OpenGL) \
251 SUB(Render, Vulkan) \
235 CLS(Audio) \ 252 CLS(Audio) \
236 SUB(Audio, DSP) \ 253 SUB(Audio, DSP) \
237 SUB(Audio, Sink) \ 254 SUB(Audio, Sink) \
@@ -275,25 +292,6 @@ const char* GetLevelName(Level log_level) {
275#undef LVL 292#undef LVL
276} 293}
277 294
278Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
279 const char* function, std::string message) {
280 using std::chrono::duration_cast;
281 using std::chrono::steady_clock;
282
283 static steady_clock::time_point time_origin = steady_clock::now();
284
285 Entry entry;
286 entry.timestamp = duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin);
287 entry.log_class = log_class;
288 entry.log_level = log_level;
289 entry.filename = Common::TrimSourcePath(filename);
290 entry.line_num = line_nr;
291 entry.function = function;
292 entry.message = std::move(message);
293
294 return entry;
295}
296
297void SetGlobalFilter(const Filter& filter) { 295void SetGlobalFilter(const Filter& filter) {
298 Impl::Instance().SetGlobalFilter(filter); 296 Impl::Instance().SetGlobalFilter(filter);
299} 297}
@@ -318,9 +316,7 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
318 if (!filter.CheckMessage(log_class, log_level)) 316 if (!filter.CheckMessage(log_class, log_level))
319 return; 317 return;
320 318
321 Entry entry = 319 instance.PushEntry(log_class, log_level, filename, line_num, function,
322 CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args)); 320 fmt::vformat(format, args));
323
324 instance.PushEntry(std::move(entry));
325} 321}
326} // namespace Log 322} // namespace Log
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h
index 91bb0c309..fca0267a1 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -27,6 +27,7 @@ struct Entry {
27 unsigned int line_num; 27 unsigned int line_num;
28 std::string function; 28 std::string function;
29 std::string message; 29 std::string message;
30 bool final_entry = false;
30 31
31 Entry() = default; 32 Entry() = default;
32 Entry(Entry&& o) = default; 33 Entry(Entry&& o) = default;
@@ -134,10 +135,6 @@ const char* GetLogClassName(Class log_class);
134 */ 135 */
135const char* GetLevelName(Level log_level); 136const char* GetLevelName(Level log_level);
136 137
137/// Creates a log entry by formatting the given source location, and message.
138Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
139 const char* function, std::string message);
140
141/** 138/**
142 * The global filter will prevent any messages from even being processed if they are filtered. Each 139 * The global filter will prevent any messages from even being processed if they are filtered. Each
143 * backend can have a filter, but if the level is lower than the global filter, the backend will 140 * backend can have a filter, but if the level is lower than the global filter, the backend will
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index d4ec31ec3..8ed6d5050 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -112,6 +112,7 @@ enum class Class : ClassType {
112 Render, ///< Emulator video output and hardware acceleration 112 Render, ///< Emulator video output and hardware acceleration
113 Render_Software, ///< Software renderer backend 113 Render_Software, ///< Software renderer backend
114 Render_OpenGL, ///< OpenGL backend 114 Render_OpenGL, ///< OpenGL backend
115 Render_Vulkan, ///< Vulkan backend
115 Audio, ///< Audio emulation 116 Audio, ///< Audio emulation
116 Audio_DSP, ///< The HLE implementation of the DSP 117 Audio_DSP, ///< The HLE implementation of the DSP
117 Audio_Sink, ///< Emulator audio output backend 118 Audio_Sink, ///< Emulator audio output backend