diff options
Diffstat (limited to 'src/common/logging/backend.cpp')
| -rw-r--r-- | src/common/logging/backend.cpp | 160 |
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 | ||
| 146 | ConsoleBackend::~ConsoleBackend() = default; | ||
| 147 | |||
| 143 | void ConsoleBackend::Write(const Entry& entry) { | 148 | void ConsoleBackend::Write(const Entry& entry) { |
| 144 | PrintMessage(entry); | 149 | PrintMessage(entry); |
| 145 | } | 150 | } |
| 146 | 151 | ||
| 152 | ColorConsoleBackend::~ColorConsoleBackend() = default; | ||
| 153 | |||
| 147 | void ColorConsoleBackend::Write(const Entry& entry) { | 154 | void 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 | ||
| 171 | FileBackend::~FileBackend() = default; | ||
| 172 | |||
| 163 | void FileBackend::Write(const Entry& entry) { | 173 | void 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 | ||
| 196 | DebuggerBackend::~DebuggerBackend() = default; | ||
| 197 | |||
| 185 | void DebuggerBackend::Write(const Entry& entry) { | 198 | void 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... | ||
| 285 | const 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 | |||
| 302 | const 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 | |||
| 320 | void SetGlobalFilter(const Filter& filter) { | 204 | void SetGlobalFilter(const Filter& filter) { |
| 321 | Impl::Instance().SetGlobalFilter(filter); | 205 | Impl::Instance().SetGlobalFilter(filter); |
| 322 | } | 206 | } |