diff options
| author | lizzie <lizzie@eden-emu.dev> | 2025-10-27 20:55:01 +0100 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2025-10-27 20:55:01 +0100 |
| commit | dd9cae4ebcf4256b3da4c92e34f61fcffd85035b (patch) | |
| tree | 38685fa2cd55c504326c6ee3c979c539ca5a2460 /src/common | |
| parent | 8fa36a7737e3fe1a53029dabff62adc827a56630 (diff) | |
[logging, debugger] remove unescesary logic and only query USER env variable once (#2800)
- censoring an username would lead to the variable being queried everytime something is written, just store it on a static
- dont use a map<> for something that can be done in a switch statment (and that the compiler will optimise for free!!!)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2800
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/logging/backend.cpp | 62 | ||||
| -rw-r--r-- | src/common/logging/text_formatter.cpp | 149 |
2 files changed, 78 insertions, 133 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index c2cbf3f4a5..12cf15f9cf 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -53,11 +53,8 @@ constexpr const char* TrimSourcePath(std::string_view source) { class Backend { public: virtual ~Backend() = default; - virtual void Write(const Entry& entry) = 0; - virtual void EnableForStacktrace() = 0; - virtual void Flush() = 0; }; @@ -65,13 +62,11 @@ public: class ColorConsoleBackend final : public Backend { public: explicit ColorConsoleBackend() = default; - ~ColorConsoleBackend() override = default; void Write(const Entry& entry) override { - if (enabled.load(std::memory_order_relaxed)) { + if (enabled.load(std::memory_order_relaxed)) PrintColoredMessage(entry); - } } void Flush() override { @@ -97,51 +92,50 @@ public: auto old_filename = filename; old_filename += ".old.txt"; - // Existence checks are done within the functions themselves. - // We don't particularly care if these succeed or not. + // Existence checks are done within the functions themselves. + // We don't particularly care if these succeed or not. static_cast<void>(FS::RemoveFile(old_filename)); static_cast<void>(FS::RenameFile(filename, old_filename)); - file = std::make_unique<FS::IOFile>(filename, FS::FileAccessMode::Write, - FS::FileType::TextFile); + file = std::make_unique<FS::IOFile>(filename, FS::FileAccessMode::Write, FS::FileType::TextFile); } ~FileBackend() override = default; void Write(const Entry& entry) override { - if (!enabled) { + if (!enabled) return; - } auto message = FormatLogMessage(entry).append(1, '\n'); - -#ifndef ANDROID +#ifndef __ANDROID__ if (Settings::values.censor_username.GetValue()) { - char* username = getenv("USER"); - if (!username) { - username = getenv("USERNAME"); - } - boost::replace_all(message, username, "user"); + // This must be a static otherwise it would get checked on EVERY + // instance of logging an entry... + static std::string username = []() -> std::string { + auto* s = getenv("USER"); + if (s == nullptr) + s = getenv("USERNAME"); + return std::string{s}; + }(); + if (!username.empty()) + boost::replace_all(message, username, "user"); } #endif - bytes_written += file->WriteString(message); // Option to log each line rather than 4k buffers - if (Settings::values.log_flush_line.GetValue()) { + if (Settings::values.log_flush_line.GetValue()) file->Flush(); - } using namespace Common::Literals; // Prevent logs from exceeding a set maximum size in the event that log entries are spammed. const auto write_limit = Settings::values.extended_logging.GetValue() ? 1_GiB : 100_MiB; const bool write_limit_exceeded = bytes_written > write_limit; if (entry.log_level >= Level::Error || write_limit_exceeded) { - if (write_limit_exceeded) { - // Stop writing after the write limit is exceeded. - // Don't close the file so we can print a stacktrace if necessary + // Stop writing after the write limit is exceeded. + // Don't close the file so we can print a stacktrace if necessary + if (write_limit_exceeded) enabled = false; - } file->Flush(); } } @@ -157,8 +151,8 @@ public: private: std::unique_ptr<FS::IOFile> file; - bool enabled = true; std::size_t bytes_written = 0; + bool enabled = true; }; /** @@ -209,9 +203,8 @@ bool initialization_in_progress_suppress_logging = true; class Impl { public: static Impl& Instance() { - if (!instance) { + if (!instance) throw std::runtime_error("Using Logging instance before its initialization"); - } return *instance; } @@ -277,25 +270,21 @@ private: }; while (!stop_token.stop_requested()) { message_queue.PopWait(entry, stop_token); - if (entry.filename != nullptr) { + 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.TryPop(entry)) { + while (max_logs_to_write-- && message_queue.TryPop(entry)) write_logs(); - } }); } void StopBackendThread() { backend_thread.request_stop(); - if (backend_thread.joinable()) { + if (backend_thread.joinable()) backend_thread.join(); - } - ForEachBackend([](Backend& backend) { backend.Flush(); }); } @@ -304,7 +293,6 @@ private: using std::chrono::duration_cast; using std::chrono::microseconds; using std::chrono::steady_clock; - return { .timestamp = duration_cast<microseconds>(steady_clock::now() - time_origin), .log_class = log_class, diff --git a/src/common/logging/text_formatter.cpp b/src/common/logging/text_formatter.cpp index 2c453177ba..17d94fe751 100644 --- a/src/common/logging/text_formatter.cpp +++ b/src/common/logging/text_formatter.cpp @@ -1,14 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include <array> #include <cstdio> +#include <cstdint> +#include <string> #ifdef _WIN32 #include <windows.h> -#endif - -#ifdef ANDROID +#elif defined(__ANDROID__) #include <android/log.h> #endif @@ -21,123 +24,77 @@ namespace Common::Log { std::string FormatLogMessage(const Entry& entry) { - unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000); - unsigned int time_fractional = static_cast<unsigned int>(entry.timestamp.count() % 1000000); - - const char* class_name = GetLogClassName(entry.log_class); - const char* level_name = GetLevelName(entry.log_level); - + auto const time_seconds = uint32_t(entry.timestamp.count() / 1000000); + auto const time_fractional = uint32_t(entry.timestamp.count() % 1000000); + char const* class_name = GetLogClassName(entry.log_class); + char const* level_name = GetLevelName(entry.log_level); return fmt::format("[{:4d}.{:06d}] {} <{}> {}:{}:{}: {}", time_seconds, time_fractional, class_name, level_name, entry.filename, entry.function, entry.line_num, entry.message); } void PrintMessage(const Entry& entry) { - const auto str = FormatLogMessage(entry).append(1, '\n'); - fputs(str.c_str(), stderr); +#ifdef _WIN32 + auto const str = FormatLogMessage(entry).append(1, '\n'); +#else +#define ESC "\x1b" + auto str = std::string{[&entry]() -> const char* { + switch (entry.log_level) { + case Level::Debug: return ESC "[0;36m"; // Cyan + case Level::Info: return ESC "[0;37m"; // Bright gray + case Level::Warning: return ESC "[1;33m"; // Bright yellow + case Level::Error: return ESC "[1;31m"; // Bright red + case Level::Critical: return ESC "[1;35m"; // Bright magenta + default: return ESC "[1;30m"; // Grey + } + }()}; + str.append(FormatLogMessage(entry)); + str.append(ESC "[0m\n"); +#undef ESC +#endif + fwrite(str.c_str(), 1, str.size(), stderr); } void PrintColoredMessage(const Entry& entry) { #ifdef _WIN32 HANDLE console_handle = GetStdHandle(STD_ERROR_HANDLE); - if (console_handle == INVALID_HANDLE_VALUE) { + if (console_handle == INVALID_HANDLE_VALUE) return; - } - CONSOLE_SCREEN_BUFFER_INFO original_info = {}; GetConsoleScreenBufferInfo(console_handle, &original_info); - - WORD color = 0; - switch (entry.log_level) { - case Level::Trace: // Grey - color = FOREGROUND_INTENSITY; - break; - case Level::Debug: // Cyan - color = FOREGROUND_GREEN | FOREGROUND_BLUE; - break; - case Level::Info: // Bright gray - color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - break; - case Level::Warning: // Bright yellow - color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; - break; - case Level::Error: // Bright red - color = FOREGROUND_RED | FOREGROUND_INTENSITY; - break; - case Level::Critical: // Bright magenta - color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - break; - case Level::Count: - UNREACHABLE(); - } - + WORD color = WORD([&entry]() { + switch (entry.log_level) { + case Level::Debug: return FOREGROUND_GREEN | FOREGROUND_BLUE; // Cyan + case Level::Info: return FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; // Bright gray + case Level::Warning: return FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; + case Level::Error: return FOREGROUND_RED | FOREGROUND_INTENSITY; + case Level::Critical: return FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; + default: break; + } + return FOREGROUND_INTENSITY; // Grey + }()); SetConsoleTextAttribute(console_handle, color); -#else -#define ESC "\x1b" - const char* color = ""; - switch (entry.log_level) { - case Level::Trace: // Grey - color = ESC "[1;30m"; - break; - case Level::Debug: // Cyan - color = ESC "[0;36m"; - break; - case Level::Info: // Bright gray - color = ESC "[0;37m"; - break; - case Level::Warning: // Bright yellow - color = ESC "[1;33m"; - break; - case Level::Error: // Bright red - color = ESC "[1;31m"; - break; - case Level::Critical: // Bright magenta - color = ESC "[1;35m"; - break; - case Level::Count: - UNREACHABLE(); - } - - fputs(color, stderr); #endif - PrintMessage(entry); - #ifdef _WIN32 SetConsoleTextAttribute(console_handle, original_info.wAttributes); -#else - fputs(ESC "[0m", stderr); -#undef ESC #endif } void PrintMessageToLogcat(const Entry& entry) { #ifdef ANDROID - const auto str = FormatLogMessage(entry); - - android_LogPriority android_log_priority; - switch (entry.log_level) { - case Level::Trace: - android_log_priority = ANDROID_LOG_VERBOSE; - break; - case Level::Debug: - android_log_priority = ANDROID_LOG_DEBUG; - break; - case Level::Info: - android_log_priority = ANDROID_LOG_INFO; - break; - case Level::Warning: - android_log_priority = ANDROID_LOG_WARN; - break; - case Level::Error: - android_log_priority = ANDROID_LOG_ERROR; - break; - case Level::Critical: - android_log_priority = ANDROID_LOG_FATAL; - break; - case Level::Count: - UNREACHABLE(); - } + android_LogPriority android_log_priority = [&]() { + switch (entry.log_level) { + case Level::Debug: return ANDROID_LOG_DEBUG; + case Level::Info: return ANDROID_LOG_INFO; + case Level::Warning: return ANDROID_LOG_WARN; + case Level::Error: return ANDROID_LOG_ERROR; + case Level::Critical: return ANDROID_LOG_FATAL; + case Level::Count: + case Level::Trace: return ANDROID_LOG_VERBOSE; + } + }(); + auto const str = FormatLogMessage(entry); __android_log_print(android_log_priority, "YuzuNative", "%s", str.c_str()); #endif } |
