summaryrefslogtreecommitdiff
path: root/src/common/logging/backend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/logging/backend.cpp')
-rw-r--r--src/common/logging/backend.cpp160
1 files changed, 22 insertions, 138 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 6aa8ac960..b6fa4affb 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -17,7 +17,10 @@
17#endif 17#endif
18 18
19#include "common/assert.h" 19#include "common/assert.h"
20#include "common/fs/file.h"
20#include "common/fs/fs.h" 21#include "common/fs/fs.h"
22#include "common/literals.h"
23
21#include "common/logging/backend.h" 24#include "common/logging/backend.h"
22#include "common/logging/log.h" 25#include "common/logging/log.h"
23#include "common/logging/text_formatter.h" 26#include "common/logging/text_formatter.h"
@@ -97,8 +100,8 @@ private:
97 write_logs(entry); 100 write_logs(entry);
98 } 101 }
99 102
100 // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case 103 // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a
101 // where a system is repeatedly spamming logs even on close. 104 // case where a system is repeatedly spamming logs even on close.
102 const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100; 105 const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100;
103 int logs_written = 0; 106 int logs_written = 0;
104 while (logs_written++ < MAX_LOGS_TO_WRITE && message_queue.Pop(entry)) { 107 while (logs_written++ < MAX_LOGS_TO_WRITE && message_queue.Pop(entry)) {
@@ -140,10 +143,14 @@ private:
140 std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; 143 std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
141}; 144};
142 145
146ConsoleBackend::~ConsoleBackend() = default;
147
143void ConsoleBackend::Write(const Entry& entry) { 148void ConsoleBackend::Write(const Entry& entry) {
144 PrintMessage(entry); 149 PrintMessage(entry);
145} 150}
146 151
152ColorConsoleBackend::~ColorConsoleBackend() = default;
153
147void ColorConsoleBackend::Write(const Entry& entry) { 154void ColorConsoleBackend::Write(const Entry& entry) {
148 PrintColoredMessage(entry); 155 PrintColoredMessage(entry);
149} 156}
@@ -154,19 +161,23 @@ FileBackend::FileBackend(const std::filesystem::path& filename) {
154 161
155 // Existence checks are done within the functions themselves. 162 // Existence checks are done within the functions themselves.
156 // We don't particularly care if these succeed or not. 163 // We don't particularly care if these succeed or not.
157 void(FS::RemoveFile(old_filename)); 164 FS::RemoveFile(old_filename);
158 void(FS::RenameFile(filename, old_filename)); 165 void(FS::RenameFile(filename, old_filename));
159 166
160 file = FS::IOFile(filename, FS::FileAccessMode::Write, FS::FileType::TextFile); 167 file =
168 std::make_unique<FS::IOFile>(filename, FS::FileAccessMode::Write, FS::FileType::TextFile);
161} 169}
162 170
171FileBackend::~FileBackend() = default;
172
163void FileBackend::Write(const Entry& entry) { 173void FileBackend::Write(const Entry& entry) {
174 using namespace Common::Literals;
164 // prevent logs from going over the maximum size (in case its spamming and the user doesn't 175 // prevent logs from going over the maximum size (in case its spamming and the user doesn't
165 // know) 176 // know)
166 constexpr std::size_t MAX_BYTES_WRITTEN = 100 * 1024 * 1024; 177 constexpr std::size_t MAX_BYTES_WRITTEN = 100_MiB;
167 constexpr std::size_t MAX_BYTES_WRITTEN_EXTENDED = 1024 * 1024 * 1024; 178 constexpr std::size_t MAX_BYTES_WRITTEN_EXTENDED = 1_GiB;
168 179
169 if (!file.IsOpen()) { 180 if (!file->IsOpen()) {
170 return; 181 return;
171 } 182 }
172 183
@@ -176,147 +187,20 @@ void FileBackend::Write(const Entry& entry) {
176 return; 187 return;
177 } 188 }
178 189
179 bytes_written += file.WriteString(FormatLogMessage(entry).append(1, '\n')); 190 bytes_written += file->WriteString(FormatLogMessage(entry).append(1, '\n'));
180 if (entry.log_level >= Level::Error) { 191 if (entry.log_level >= Level::Error) {
181 void(file.Flush()); 192 file->Flush();
182 } 193 }
183} 194}
184 195
196DebuggerBackend::~DebuggerBackend() = default;
197
185void DebuggerBackend::Write(const Entry& entry) { 198void DebuggerBackend::Write(const Entry& entry) {
186#ifdef _WIN32 199#ifdef _WIN32
187 ::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str()); 200 ::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str());
188#endif 201#endif
189} 202}
190 203
191/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this.
192#define ALL_LOG_CLASSES() \
193 CLS(Log) \
194 CLS(Common) \
195 SUB(Common, Filesystem) \
196 SUB(Common, Memory) \
197 CLS(Core) \
198 SUB(Core, ARM) \
199 SUB(Core, Timing) \
200 CLS(Config) \
201 CLS(Debug) \
202 SUB(Debug, Emulated) \
203 SUB(Debug, GPU) \
204 SUB(Debug, Breakpoint) \
205 SUB(Debug, GDBStub) \
206 CLS(Kernel) \
207 SUB(Kernel, SVC) \
208 CLS(Service) \
209 SUB(Service, ACC) \
210 SUB(Service, Audio) \
211 SUB(Service, AM) \
212 SUB(Service, AOC) \
213 SUB(Service, APM) \
214 SUB(Service, ARP) \
215 SUB(Service, BCAT) \
216 SUB(Service, BPC) \
217 SUB(Service, BGTC) \
218 SUB(Service, BTDRV) \
219 SUB(Service, BTM) \
220 SUB(Service, Capture) \
221 SUB(Service, ERPT) \
222 SUB(Service, ETicket) \
223 SUB(Service, EUPLD) \
224 SUB(Service, Fatal) \
225 SUB(Service, FGM) \
226 SUB(Service, Friend) \
227 SUB(Service, FS) \
228 SUB(Service, GRC) \
229 SUB(Service, HID) \
230 SUB(Service, IRS) \
231 SUB(Service, LBL) \
232 SUB(Service, LDN) \
233 SUB(Service, LDR) \
234 SUB(Service, LM) \
235 SUB(Service, Migration) \
236 SUB(Service, Mii) \
237 SUB(Service, MM) \
238 SUB(Service, NCM) \
239 SUB(Service, NFC) \
240 SUB(Service, NFP) \
241 SUB(Service, NIFM) \
242 SUB(Service, NIM) \
243 SUB(Service, NPNS) \
244 SUB(Service, NS) \
245 SUB(Service, NVDRV) \
246 SUB(Service, OLSC) \
247 SUB(Service, PCIE) \
248 SUB(Service, PCTL) \
249 SUB(Service, PCV) \
250 SUB(Service, PM) \
251 SUB(Service, PREPO) \
252 SUB(Service, PSC) \
253 SUB(Service, PSM) \
254 SUB(Service, SET) \
255 SUB(Service, SM) \
256 SUB(Service, SPL) \
257 SUB(Service, SSL) \
258 SUB(Service, TCAP) \
259 SUB(Service, Time) \
260 SUB(Service, USB) \
261 SUB(Service, VI) \
262 SUB(Service, WLAN) \
263 CLS(HW) \
264 SUB(HW, Memory) \
265 SUB(HW, LCD) \
266 SUB(HW, GPU) \
267 SUB(HW, AES) \
268 CLS(IPC) \
269 CLS(Frontend) \
270 CLS(Render) \
271 SUB(Render, Software) \
272 SUB(Render, OpenGL) \
273 SUB(Render, Vulkan) \
274 CLS(Audio) \
275 SUB(Audio, DSP) \
276 SUB(Audio, Sink) \
277 CLS(Input) \
278 CLS(Network) \
279 CLS(Loader) \
280 CLS(CheatEngine) \
281 CLS(Crypto) \
282 CLS(WebService)
283
284// GetClassName is a macro defined by Windows.h, grrr...
285const char* GetLogClassName(Class log_class) {
286 switch (log_class) {
287#define CLS(x) \
288 case Class::x: \
289 return #x;
290#define SUB(x, y) \
291 case Class::x##_##y: \
292 return #x "." #y;
293 ALL_LOG_CLASSES()
294#undef CLS
295#undef SUB
296 case Class::Count:
297 break;
298 }
299 return "Invalid";
300}
301
302const char* GetLevelName(Level log_level) {
303#define LVL(x) \
304 case Level::x: \
305 return #x
306 switch (log_level) {
307 LVL(Trace);
308 LVL(Debug);
309 LVL(Info);
310 LVL(Warning);
311 LVL(Error);
312 LVL(Critical);
313 case Level::Count:
314 break;
315 }
316#undef LVL
317 return "Invalid";
318}
319
320void SetGlobalFilter(const Filter& filter) { 204void SetGlobalFilter(const Filter& filter) {
321 Impl::Instance().SetGlobalFilter(filter); 205 Impl::Instance().SetGlobalFilter(filter);
322} 206}