[common/logging] faster logging by avoiding constructing unused strings/results (and filtering first)
Some checks failed
eden-license / license-header (pull_request) Failing after 25s

Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie 2025-09-27 20:35:58 +00:00
parent cc50571275
commit 2f327c786e
Signed by: Lizzie
GPG key ID: 00287378CADCAB13
4 changed files with 39 additions and 45 deletions

View file

@ -39,9 +39,17 @@ namespace Common::Log {
namespace { namespace {
/** /// @brief Trims up to and including the last of ../, ..\, src/, src\ in a string
* Interface for logging backends. /// do not be fooled this isn't generating new strings on .rodata :)
*/ constexpr const char* TrimSourcePath(std::string_view source) {
const auto rfind = [source](const std::string_view match) {
return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size());
};
auto idx = (std::max)({rfind("src/"), rfind("src\\"), rfind("../"), rfind("..\\")});
return source.data() + idx;
}
/// @brief Interface for logging backends.
class Backend { class Backend {
public: public:
virtual ~Backend() = default; virtual ~Backend() = default;
@ -53,9 +61,7 @@ public:
virtual void Flush() = 0; virtual void Flush() = 0;
}; };
/** /// @brief Backend that writes to stderr and with color
* Backend that writes to stderr and with color
*/
class ColorConsoleBackend final : public Backend { class ColorConsoleBackend final : public Backend {
public: public:
explicit ColorConsoleBackend() = default; explicit ColorConsoleBackend() = default;
@ -84,9 +90,7 @@ private:
std::atomic_bool enabled{false}; std::atomic_bool enabled{false};
}; };
/** /// @brief Backend that writes to a file passed into the constructor
* Backend that writes to a file passed into the constructor
*/
class FileBackend final : public Backend { class FileBackend final : public Backend {
public: public:
explicit FileBackend(const std::filesystem::path& filename) { explicit FileBackend(const std::filesystem::path& filename) {
@ -248,13 +252,14 @@ public:
color_console_backend.SetEnabled(enabled); color_console_backend.SetEnabled(enabled);
} }
bool CanPushEntry(Class log_class, Level log_level) const noexcept {
return filter.CheckMessage(log_class, log_level);
}
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) noexcept {
if (!filter.CheckMessage(log_class, log_level)) {
return;
}
message_queue.EmplaceWait( message_queue.EmplaceWait(
CreateEntry(log_class, log_level, filename, line_num, function, std::move(message))); CreateEntry(log_class, log_level, TrimSourcePath(filename), line_num, function, std::move(message)));
} }
private: private:
@ -368,8 +373,9 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, fmt::string_view format, unsigned int line_num, const char* function, fmt::string_view format,
const fmt::format_args& args) { const fmt::format_args& args) {
if (!initialization_in_progress_suppress_logging) { if (!initialization_in_progress_suppress_logging) {
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function, auto& instance = Impl::Instance();
fmt::vformat(format, args)); if (instance.CanPushEntry(log_class, log_level))
instance.PushEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args));
} }
} }
} // namespace Common::Log } // namespace Common::Log

View file

@ -9,22 +9,20 @@ namespace Common::Log {
namespace { namespace {
template <typename It> template <typename It>
Level GetLevelByName(const It begin, const It end) { Level GetLevelByName(const It begin, const It end) {
for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) { for (u32 i = 0; i < u32(Level::Count); ++i) {
const char* level_name = GetLevelName(static_cast<Level>(i)); const char* level_name = GetLevelName(Level(i));
if (Common::ComparePartialString(begin, end, level_name)) { if (Common::ComparePartialString(begin, end, level_name))
return static_cast<Level>(i); return Level(i);
}
} }
return Level::Count; return Level::Count;
} }
template <typename It> template <typename It>
Class GetClassByName(const It begin, const It end) { Class GetClassByName(const It begin, const It end) {
for (u8 i = 0; i < static_cast<u8>(Class::Count); ++i) { for (u32 i = 0; i < u32(Class::Count); ++i) {
const char* level_name = GetLogClassName(static_cast<Class>(i)); const char* level_name = GetLogClassName(Class(i));
if (Common::ComparePartialString(begin, end, level_name)) { if (Common::ComparePartialString(begin, end, level_name))
return static_cast<Class>(i); return Class(i);
}
} }
return Class::Count; return Class::Count;
} }
@ -229,13 +227,12 @@ void Filter::ParseFilterString(std::string_view filter_view) {
} }
bool Filter::CheckMessage(Class log_class, Level level) const { bool Filter::CheckMessage(Class log_class, Level level) const {
return static_cast<u8>(level) >= return u8(level) >= u8(class_levels[std::size_t(log_class)]);
static_cast<u8>(class_levels[static_cast<std::size_t>(log_class)]);
} }
bool Filter::IsDebug() const { bool Filter::IsDebug() const {
return std::any_of(class_levels.begin(), class_levels.end(), [](const Level& l) { return std::any_of(class_levels.begin(), class_levels.end(), [](const Level& l) {
return static_cast<u8>(l) <= static_cast<u8>(Level::Debug); return u8(l) <= u8(Level::Debug);
}); });
} }

View file

@ -16,15 +16,6 @@
namespace Common::Log { namespace Common::Log {
// trims up to and including the last of ../, ..\, src/, src\ in a string
constexpr const char* TrimSourcePath(std::string_view source) {
const auto rfind = [source](const std::string_view match) {
return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size());
};
auto idx = (std::max)({rfind("src/"), rfind("src\\"), rfind("../"), rfind("..\\")});
return source.data() + idx;
}
/// Logs a message to the global logger, using fmt /// Logs a message to the global logger, using fmt
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, fmt::string_view format, unsigned int line_num, const char* function, fmt::string_view format,
@ -42,7 +33,7 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
#ifdef _DEBUG #ifdef _DEBUG
#define LOG_TRACE(log_class, ...) \ #define LOG_TRACE(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#else #else
#define LOG_TRACE(log_class, fmt, ...) (void(0)) #define LOG_TRACE(log_class, fmt, ...) (void(0))
@ -50,21 +41,21 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
#define LOG_DEBUG(log_class, ...) \ #define LOG_DEBUG(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_INFO(log_class, ...) \ #define LOG_INFO(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_WARNING(log_class, ...) \ #define LOG_WARNING(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_ERROR(log_class, ...) \ #define LOG_ERROR(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_CRITICAL(log_class, ...) \ #define LOG_CRITICAL(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)

View file

@ -286,7 +286,7 @@ Result CheckOpenSSLErrors() {
msg.append(data); msg.append(data);
} }
Common::Log::FmtLogMessage(Common::Log::Class::Service_SSL, Common::Log::Level::Error, Common::Log::FmtLogMessage(Common::Log::Class::Service_SSL, Common::Log::Level::Error,
Common::Log::TrimSourcePath(file), line, func, "OpenSSL: {}", file, line, func, "OpenSSL: {}",
msg); msg);
} }
return ResultInternalError; return ResultInternalError;