summaryrefslogtreecommitdiff
path: root/Source/Core/Common
diff options
context:
space:
mode:
authorDentomologist <dentomologist@gmail.com>2025-09-11 16:38:07 -0700
committerDentomologist <dentomologist@gmail.com>2025-09-19 13:25:42 -0700
commit2d48043b61613dc293a48e3ed863e36ffdf6643e (patch)
treea0c6936afca68650e5a7e2915aad413640951e66 /Source/Core/Common
parent79614956f39fc1f6d47ff3fcf6484ef19f4e1ae4 (diff)
Logging: Don't overwrite LDEBUG verbosity in Release builds
Preserve the configured logging verbosity unless the user actually changes it, rather than capping it to LINFO on release builds. Rename LogManager::m_level to m_effective_level and distinguish between the config and effective level in various function/variable names. Make m_effective_level atomic to prevent data races when setting the effective log level from the config changed callback.
Diffstat (limited to 'Source/Core/Common')
-rw-r--r--Source/Core/Common/Assert.h4
-rw-r--r--Source/Core/Common/Logging/Log.h6
-rw-r--r--Source/Core/Common/Logging/LogManager.cpp32
-rw-r--r--Source/Core/Common/Logging/LogManager.h17
4 files changed, 41 insertions, 18 deletions
diff --git a/Source/Core/Common/Assert.h b/Source/Core/Common/Assert.h
index 5611e0e04e..ab3142437f 100644
--- a/Source/Core/Common/Assert.h
+++ b/Source/Core/Common/Assert.h
@@ -25,7 +25,7 @@
#define DEBUG_ASSERT_MSG(_t_, _a_, _fmt_, ...) \
do \
{ \
- if constexpr (Common::Log::MAX_LOGLEVEL >= Common::Log::LogLevel::LDEBUG) \
+ if constexpr (Common::Log::MAX_EFFECTIVE_LOGLEVEL >= Common::Log::LogLevel::LDEBUG) \
ASSERT_MSG(_t_, _a_, _fmt_ __VA_OPT__(, ) __VA_ARGS__); \
} while (0)
@@ -45,6 +45,6 @@
#define DEBUG_ASSERT(_a_) \
do \
{ \
- if constexpr (Common::Log::MAX_LOGLEVEL >= Common::Log::LogLevel::LDEBUG) \
+ if constexpr (Common::Log::MAX_EFFECTIVE_LOGLEVEL >= Common::Log::LogLevel::LDEBUG) \
ASSERT(_a_); \
} while (0)
diff --git a/Source/Core/Common/Logging/Log.h b/Source/Core/Common/Logging/Log.h
index 4b40297836..c4f38e72f6 100644
--- a/Source/Core/Common/Logging/Log.h
+++ b/Source/Core/Common/Logging/Log.h
@@ -82,9 +82,9 @@ enum class LogLevel : int
};
#if defined(_DEBUG) || defined(DEBUGFAST)
-constexpr auto MAX_LOGLEVEL = Common::Log::LogLevel::LDEBUG;
+constexpr auto MAX_EFFECTIVE_LOGLEVEL = Common::Log::LogLevel::LDEBUG;
#else
-constexpr auto MAX_LOGLEVEL = Common::Log::LogLevel::LINFO;
+constexpr auto MAX_EFFECTIVE_LOGLEVEL = Common::Log::LogLevel::LINFO;
#endif // logging
static const char LOG_LEVEL_TO_CHAR[7] = "-NEWID";
@@ -114,7 +114,7 @@ void GenericLogFmt(LogLevel level, LogType type, const char* file, int line, con
#define GENERIC_LOG_FMT(t, v, format, ...) \
do \
{ \
- if (v <= Common::Log::MAX_LOGLEVEL) \
+ if (v <= Common::Log::MAX_EFFECTIVE_LOGLEVEL) \
{ \
/* Use a macro-like name to avoid shadowing warnings */ \
constexpr auto GENERIC_LOG_FMT_N = Common::CountFmtReplacementFields(format); \
diff --git a/Source/Core/Common/Logging/LogManager.cpp b/Source/Core/Common/Logging/LogManager.cpp
index d0117ad07f..a1302a8171 100644
--- a/Source/Core/Common/Logging/LogManager.cpp
+++ b/Source/Core/Common/Logging/LogManager.cpp
@@ -4,6 +4,7 @@
#include "Common/Logging/LogManager.h"
#include <algorithm>
+#include <atomic>
#include <chrono>
#include <cstdarg>
#include <cstring>
@@ -156,9 +157,7 @@ LogManager::LogManager()
RegisterListener(LogListener::CONSOLE_LISTENER, std::make_unique<ConsoleListener>());
// Set up log listeners
- LogLevel verbosity = Config::Get(LOGGER_VERBOSITY);
-
- SetLogLevel(verbosity);
+ SetEffectiveLogLevel();
EnableListener(LogListener::FILE_LISTENER, Config::Get(LOGGER_WRITE_TO_FILE));
EnableListener(LogListener::CONSOLE_LISTENER, Config::Get(LOGGER_WRITE_TO_CONSOLE));
EnableListener(LogListener::LOG_WINDOW_LISTENER, Config::Get(LOGGER_WRITE_TO_WINDOW));
@@ -170,9 +169,15 @@ LogManager::LogManager()
}
m_path_cutoff_point = DeterminePathCutOffPoint();
+
+ m_config_changed_callback_id =
+ Config::AddConfigChangedCallback([this]() { SetEffectiveLogLevel(); });
}
-LogManager::~LogManager() = default;
+LogManager::~LogManager()
+{
+ Config::RemoveConfigChangedCallback(m_config_changed_callback_id);
+}
void LogManager::SaveSettings()
{
@@ -183,7 +188,6 @@ void LogManager::SaveSettings()
IsListenerEnabled(LogListener::CONSOLE_LISTENER));
Config::SetBaseOrCurrent(LOGGER_WRITE_TO_WINDOW,
IsListenerEnabled(LogListener::LOG_WINDOW_LISTENER));
- Config::SetBaseOrCurrent(LOGGER_VERBOSITY, GetLogLevel());
for (const auto& container : m_log)
{
@@ -228,14 +232,22 @@ void LogManager::LogWithFullPath(LogLevel level, LogType type, const char* file,
}
}
-LogLevel LogManager::GetLogLevel() const
+LogLevel LogManager::GetEffectiveLogLevel() const
+{
+ return m_effective_level.load(std::memory_order_relaxed);
+}
+
+void LogManager::SetConfigLogLevel(const LogLevel level)
{
- return m_level;
+ Config::SetBaseOrCurrent(LOGGER_VERBOSITY, level);
+ SetEffectiveLogLevel();
}
-void LogManager::SetLogLevel(LogLevel level)
+void LogManager::SetEffectiveLogLevel()
{
- m_level = std::clamp(level, LogLevel::LNOTICE, MAX_LOGLEVEL);
+ const LogLevel clamped_level =
+ std::clamp(Config::Get(LOGGER_VERBOSITY), LogLevel::LNOTICE, MAX_EFFECTIVE_LOGLEVEL);
+ m_effective_level.store(clamped_level, std::memory_order_relaxed);
}
void LogManager::SetEnable(LogType type, bool enable)
@@ -245,7 +257,7 @@ void LogManager::SetEnable(LogType type, bool enable)
bool LogManager::IsEnabled(LogType type, LogLevel level) const
{
- return m_log[type].m_enable && GetLogLevel() >= level;
+ return m_log[type].m_enable && GetEffectiveLogLevel() >= level;
}
std::vector<LogManager::LogContainer> LogManager::GetLogTypes()
diff --git a/Source/Core/Common/Logging/LogManager.h b/Source/Core/Common/Logging/LogManager.h
index d3a235634c..8253c5e118 100644
--- a/Source/Core/Common/Logging/LogManager.h
+++ b/Source/Core/Common/Logging/LogManager.h
@@ -4,17 +4,25 @@
#pragma once
#include <array>
+#include <atomic>
#include <cstdarg>
#include <memory>
#include <string>
#include <vector>
#include "Common/BitSet.h"
+#include "Common/Config/Config.h"
#include "Common/EnumMap.h"
#include "Common/Logging/Log.h"
namespace Common::Log
{
+// This variable should only be read to update the effective log level, and its base layer should
+// only be set when the user selects a new verbosity. Everything else should use the effective log
+// level instead. When running a release build this prevents overwriting the LDEBUG config value
+// with the clamped LINFO level.
+extern const Config::Info<LogLevel> LOGGER_VERBOSITY;
+
// pure virtual interface
class LogListener
{
@@ -52,8 +60,9 @@ public:
void LogWithFullPath(LogLevel level, LogType type, const char* file, int line,
const char* message);
- LogLevel GetLogLevel() const;
- void SetLogLevel(LogLevel level);
+ // Use this function instead of LOGGER_VERBOSITY to determine which logs should be printed.
+ LogLevel GetEffectiveLogLevel() const;
+ void SetConfigLogLevel(LogLevel level);
void SetEnable(LogType type, bool enable);
bool IsEnabled(LogType type, LogLevel level = LogLevel::LNOTICE) const;
@@ -78,8 +87,10 @@ private:
LogManager& operator=(LogManager&&) = delete;
static std::string GetTimestamp();
+ void SetEffectiveLogLevel();
- LogLevel m_level;
+ std::atomic<LogLevel> m_effective_level;
+ Config::ConfigChangedCallbackID m_config_changed_callback_id;
EnumMap<LogContainer, LAST_LOG_TYPE> m_log{};
std::array<std::unique_ptr<LogListener>, LogListener::NUMBER_OF_LISTENERS> m_listeners{};
BitSet32 m_listener_ids;