From 85566fbe9258fb3f9f60f4792242be0e62e47b36 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Mon, 13 Jun 2022 21:43:05 +0200 Subject: [PATCH] Add separate log levels for each output `stdout_output_level` for printing to stdout, `console_output_level` for printing to local console and remote console and `loglevel` for the log file. Keep the old log level filters 0 for info and more severe, 1 for debug and more severe and 2 for trace and more severe, introducing -1 for warn, and -2 for error. -3 will show no log messages at all. --- src/base/log.cpp | 54 +++++++++++++++++++++----- src/base/logger.h | 45 +++++++++++++++------ src/engine/client/client.cpp | 48 ++++++++++++++++++----- src/engine/client/client.h | 7 +++- src/engine/console.h | 1 + src/engine/server/main.cpp | 12 ++++-- src/engine/server/server.cpp | 44 ++++++++++++++++----- src/engine/server/server.h | 9 ++++- src/engine/server/server_logger.cpp | 4 ++ src/engine/shared/assertion_logger.cpp | 4 ++ src/engine/shared/config_variables.h | 7 ++-- src/engine/shared/console.cpp | 9 +++++ src/game/client/components/console.cpp | 17 ++++++-- src/game/client/components/console.h | 1 + src/game/server/gamecontext.cpp | 4 ++ 15 files changed, 216 insertions(+), 50 deletions(-) diff --git a/src/base/log.cpp b/src/base/log.cpp index 96f53cf36..db62be0fa 100644 --- a/src/base/log.cpp +++ b/src/base/log.cpp @@ -20,16 +20,10 @@ #include #endif -std::atomic loglevel = LEVEL_INFO; std::atomic global_logger = nullptr; thread_local ILogger *scope_logger = nullptr; thread_local bool in_logger = false; -void log_set_loglevel(LEVEL level) -{ - loglevel.store(level, std::memory_order_release); -} - void log_set_global_logger(ILogger *logger) { ILogger *null = nullptr; @@ -80,9 +74,6 @@ void log_log_impl(LEVEL level, bool have_color, LOG_COLOR color, const char *sys void log_log_impl(LEVEL level, bool have_color, LOG_COLOR color, const char *sys, const char *fmt, va_list args) { - if(level > loglevel.load(std::memory_order_acquire)) - return; - // Make sure we're not logging recursively. if(in_logger) { @@ -146,12 +137,21 @@ void log_log_color(LEVEL level, LOG_COLOR color, const char *sys, const char *fm va_end(args); } +bool CLogFilter::Filters(const CLogMessage *pMessage) +{ + return pMessage->m_Level > m_MaxLevel.load(std::memory_order_relaxed); +} + #if defined(CONF_PLATFORM_ANDROID) class CLoggerAndroid : public ILogger { public: void Log(const CLogMessage *pMessage) override { + if(m_Filter.Filters(pMessage)) + { + return; + } int AndroidLevel; switch(pMessage->m_Level) { @@ -184,9 +184,14 @@ public: CLoggerCollection(std::vector> &&vpLoggers) : m_vpLoggers(std::move(vpLoggers)) { + m_Filter.m_MaxLevel.store(LEVEL_TRACE, std::memory_order_relaxed); } void Log(const CLogMessage *pMessage) override { + if(m_Filter.Filters(pMessage)) + { + return; + } for(auto &pLogger : m_vpLoggers) { pLogger->Log(pMessage); @@ -221,6 +226,10 @@ public: } void Log(const CLogMessage *pMessage) override { + if(m_Filter.Filters(pMessage)) + { + return; + } aio_lock(m_pAio); if(m_AnsiTruecolor) { @@ -329,6 +338,10 @@ public: } void Log(const CLogMessage *pMessage) override { + if(m_Filter.Filters(pMessage)) + { + return; + } const std::wstring WideMessage = windows_utf8_to_wide(pMessage->m_aLine) + L"\r\n"; int Color = m_BackgroundColor; @@ -372,6 +385,10 @@ public: } void Log(const CLogMessage *pMessage) override { + if(m_Filter.Filters(pMessage)) + { + return; + } m_OutputLock.lock(); DWORD Written; // we don't care about the value, but Windows 7 crashes if we pass NULL WriteFile(m_pFile, pMessage->m_aLine, pMessage->m_LineLength, &Written, NULL); @@ -408,6 +425,10 @@ class CLoggerWindowsDebugger : public ILogger public: void Log(const CLogMessage *pMessage) override { + if(m_Filter.Filters(pMessage)) + { + return; + } const std::wstring WideMessage = windows_utf8_to_wide(pMessage->m_aLine); OutputDebugStringW(WideMessage.c_str()); } @@ -452,6 +473,12 @@ void CFutureLogger::Log(const CLogMessage *pMessage) return; } m_PendingLock.lock(); + pLogger = std::atomic_load_explicit(&m_pLogger, std::memory_order_relaxed); + if(pLogger) + { + pLogger->Log(pMessage); + return; + } m_vPending.push_back(*pMessage); m_PendingLock.unlock(); } @@ -464,3 +491,12 @@ void CFutureLogger::GlobalFinish() pLogger->GlobalFinish(); } } + +void CFutureLogger::OnFilterChange() +{ + auto pLogger = std::atomic_load_explicit(&m_pLogger, std::memory_order_acquire); + if(pLogger) + { + pLogger->SetFilter(m_Filter); + } +} diff --git a/src/base/logger.h b/src/base/logger.h index 9624c8c12..33c6519cc 100644 --- a/src/base/logger.h +++ b/src/base/logger.h @@ -50,11 +50,36 @@ public: } }; -class ILogger +class CLogFilter { +public: + /** + * The highest `LEVEL` that is still logged, -1 corresponds to no + * printing at all. + */ + std::atomic_int m_MaxLevel{LEVEL_INFO}; + + bool Filters(const CLogMessage *pMessage); +}; + +class ILogger +{ +protected: + CLogFilter m_Filter; + public: virtual ~ILogger() {} + /** + * Set a new filter. It's up to the logger implementation to actually + * use the filter. + */ + void SetFilter(const CLogFilter &Filter) + { + m_Filter.m_MaxLevel.store(Filter.m_MaxLevel.load(std::memory_order_relaxed), std::memory_order_relaxed); + OnFilterChange(); + } + /** * Send the specified message to the logging backend. * @@ -77,18 +102,12 @@ public: * @see log_global_logger_finish */ virtual void GlobalFinish() {} + /** + * Notifies thte logger of a changed `m_Filter`. + */ + virtual void OnFilterChange() {} }; -/** - * @ingroup Log - * - * Sets the global loglevel to the given value. Log messages with a less severe - * loglevel will not be forwarded to loggers. - * - * @param level The loglevel. - */ -void log_set_loglevel(LEVEL level); - /** * @ingroup Log * @@ -198,6 +217,9 @@ std::unique_ptr log_logger_windows_debugger(); * * Useful when you want to set a global logger without all logging targets * being configured. + * + * This logger forwards `SetFilter` calls, `SetFilter` calls before a logger is + * set have no effect. */ class CFutureLogger : public ILogger { @@ -214,6 +236,7 @@ public: void Set(std::shared_ptr pLogger); void Log(const CLogMessage *pMessage) override; void GlobalFinish() override; + void OnFilterChange() override; }; /** diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index c72f09916..aa43525c7 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -4356,12 +4356,6 @@ void CClient::ConchainTimeoutSeed(IConsole::IResult *pResult, void *pUserData, I pSelf->m_GenerateTimeoutSeed = false; } -void CClient::ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) -{ - pfnCallback(pResult, pCallbackUserData); - log_set_loglevel((LEVEL)g_Config.m_Loglevel); -} - void CClient::ConchainPassword(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) { CClient *pSelf = (CClient *)pUserData; @@ -4390,6 +4384,26 @@ void CClient::ConchainReplays(IConsole::IResult *pResult, void *pUserData, ICons } } +void CClient::ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + CClient *pSelf = (CClient *)pUserData; + pfnCallback(pResult, pCallbackUserData); + if(pResult->NumArguments()) + { + pSelf->m_pFileLogger->SetFilter(CLogFilter{IConsole::ToLogLevelFilter(g_Config.m_Loglevel)}); + } +} + +void CClient::ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + CClient *pSelf = (CClient *)pUserData; + pfnCallback(pResult, pCallbackUserData); + if(pResult->NumArguments() && pSelf->m_pStdoutLogger) + { + pSelf->m_pStdoutLogger->SetFilter(CLogFilter{IConsole::ToLogLevelFilter(g_Config.m_StdoutOutputLevel)}); + } +} + void CClient::RegisterCommands() { m_pConsole = Kernel()->RequestInterface(); @@ -4446,7 +4460,6 @@ void CClient::RegisterCommands() m_pConsole->Chain("cl_timeout_seed", ConchainTimeoutSeed, this); m_pConsole->Chain("cl_replays", ConchainReplays, this); - m_pConsole->Chain("loglevel", ConchainLoglevel, this); m_pConsole->Chain("password", ConchainPassword, this); // used for server browser update @@ -4462,6 +4475,9 @@ void CClient::RegisterCommands() m_pConsole->Chain("gfx_borderless", ConchainWindowBordered, this); m_pConsole->Chain("gfx_vsync", ConchainWindowVSync, this); + m_pConsole->Chain("loglevel", ConchainLoglevel, this); + m_pConsole->Chain("stdout_output_level", ConchainStdoutOutputLevel, this); + // DDRace #define CONSOLE_COMMAND(name, params, flags, callback, userdata, help) m_pConsole->Register(name, params, flags, 0, 0, help); @@ -4577,14 +4593,19 @@ int main(int argc, const char **argv) #endif std::vector> vpLoggers; + std::shared_ptr pStdoutLogger = nullptr; #if defined(CONF_PLATFORM_ANDROID) - vpLoggers.push_back(std::shared_ptr(log_logger_android())); + pStdoutLogger = std::shared_ptr(log_logger_android()); #else if(!Silent) { - vpLoggers.push_back(std::shared_ptr(log_logger_stdout())); + pStdoutLogger = std::shared_ptr(log_logger_stdout()); } #endif + if(pStdoutLogger) + { + vpLoggers.push_back(pStdoutLogger); + } std::shared_ptr pFutureFileLogger = std::make_shared(); vpLoggers.push_back(pFutureFileLogger); std::shared_ptr pFutureConsoleLogger = std::make_shared(); @@ -4625,6 +4646,8 @@ int main(int argc, const char **argv) CleanerFunctions.push([]() { SDL_Quit(); }); CClient *pClient = CreateClient(); + pClient->SetLoggers(pFutureFileLogger, std::move(pStdoutLogger)); + IKernel *pKernel = IKernel::Create(); pKernel->RegisterInterface(pClient, false); pClient->RegisterInterfaces(); @@ -4790,7 +4813,6 @@ int main(int argc, const char **argv) pSteam->ClearConnectAddress(); } - log_set_loglevel((LEVEL)g_Config.m_Loglevel); const int Mode = g_Config.m_Logappend ? IOFLAG_APPEND : IOFLAG_WRITE; if(g_Config.m_Logfile[0]) { @@ -5087,3 +5109,9 @@ void CClient::GetGPUInfoString(char (&aGPUInfo)[256]) str_copy(aGPUInfo, "Graphics backend was not yet initialized."); } } + +void CClient::SetLoggers(std::shared_ptr &&pFileLogger, std::shared_ptr &&pStdoutLogger) +{ + m_pFileLogger = pFileLogger; + m_pStdoutLogger = pStdoutLogger; +} diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 5814cea0f..d23b9da0f 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -298,6 +298,9 @@ class CClient : public IClient, public CDemoPlayer::IListener int MaxLatencyTicks() const; int PredictionMargin() const; + std::shared_ptr m_pFileLogger = nullptr; + std::shared_ptr m_pStdoutLogger = nullptr; + public: IEngine *Engine() { return m_pEngine; } IEngineGraphics *Graphics() { return m_pGraphics; } @@ -465,9 +468,10 @@ public: static void ConchainWindowScreen(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainWindowVSync(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainTimeoutSeed(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); - static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainPassword(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainReplays(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); + static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); + static void ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void Con_DemoSlice(IConsole::IResult *pResult, void *pUserData); static void Con_DemoSliceBegin(IConsole::IResult *pResult, void *pUserData); @@ -551,6 +555,7 @@ public: void ShowMessageBox(const char *pTitle, const char *pMessage, EMessageBoxType Type = MESSAGE_BOX_TYPE_ERROR) override; void GetGPUInfoString(char (&aGPUInfo)[256]) override; + void SetLoggers(std::shared_ptr &&pFileLogger, std::shared_ptr &&pStdoutLogger); }; #endif diff --git a/src/engine/console.h b/src/engine/console.h index e0708e835..570790908 100644 --- a/src/engine/console.h +++ b/src/engine/console.h @@ -122,6 +122,7 @@ public: virtual void ResetServerGameSettings() = 0; static LEVEL ToLogLevel(int ConsoleLevel); + static int ToLogLevelFilter(int ConsoleLevel); // DDRace diff --git a/src/engine/server/main.cpp b/src/engine/server/main.cpp index 5425a16e4..83fb3a18f 100644 --- a/src/engine/server/main.cpp +++ b/src/engine/server/main.cpp @@ -67,14 +67,19 @@ int main(int argc, const char **argv) #endif std::vector> vpLoggers; + std::shared_ptr pStdoutLogger; #if defined(CONF_PLATFORM_ANDROID) - vpLoggers.push_back(std::shared_ptr(log_logger_android())); + pStdoutLogger = std::shared_ptr(log_logger_android()); #else if(!Silent) { - vpLoggers.push_back(std::shared_ptr(log_logger_stdout())); + pStdoutLogger = std::shared_ptr(log_logger_stdout()); } #endif + if(pStdoutLogger) + { + vpLoggers.push_back(pStdoutLogger); + } std::shared_ptr pFutureFileLogger = std::make_shared(); vpLoggers.push_back(pFutureFileLogger); std::shared_ptr pFutureConsoleLogger = std::make_shared(); @@ -102,6 +107,8 @@ int main(int argc, const char **argv) #endif CServer *pServer = CreateServer(); + pServer->SetLoggers(pFutureFileLogger, std::move(pStdoutLogger)); + IKernel *pKernel = IKernel::Create(); // create the components @@ -169,7 +176,6 @@ int main(int argc, const char **argv) pConsole->Register("sv_test_cmds", "", CFGFLAG_SERVER, CServer::ConTestingCommands, pConsole, "Turns testing commands aka cheats on/off (setting only works in initial config)"); pConsole->Register("sv_rescue", "", CFGFLAG_SERVER, CServer::ConRescue, pConsole, "Allow /rescue command so players can teleport themselves out of freeze (setting only works in initial config)"); - log_set_loglevel((LEVEL)g_Config.m_Loglevel); const int Mode = g_Config.m_Logappend ? IOFLAG_APPEND : IOFLAG_WRITE; if(g_Config.m_Logfile[0]) { diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 8b1377a65..563b1633c 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -284,6 +284,10 @@ public: void CRconClientLogger::Log(const CLogMessage *pMessage) { + if(m_Filter.Filters(pMessage)) + { + return; + } m_pServer->SendRconLogLine(m_ClientID, pMessage); } @@ -553,11 +557,11 @@ int CServer::Init() void CServer::SendLogLine(const CLogMessage *pMessage) { - if(pMessage->m_Level <= IConsole::ToLogLevel(g_Config.m_ConsoleOutputLevel)) + if(pMessage->m_Level <= IConsole::ToLogLevelFilter(g_Config.m_ConsoleOutputLevel)) { SendRconLogLine(-1, pMessage); } - if(pMessage->m_Level <= IConsole::ToLogLevel(g_Config.m_EcOutputLevel)) + if(pMessage->m_Level <= IConsole::ToLogLevelFilter(g_Config.m_EcOutputLevel)) { m_Econ.Send(-1, pMessage->m_aLine); } @@ -3499,12 +3503,6 @@ void CServer::ConDumpSqlServers(IConsole::IResult *pResult, void *pUserData) } } -void CServer::ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) -{ - pfnCallback(pResult, pCallbackUserData); - log_set_loglevel((LEVEL)g_Config.m_Loglevel); -} - void CServer::ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) { pfnCallback(pResult, pCallbackUserData); @@ -3669,6 +3667,26 @@ void CServer::ConchainSixupUpdate(IConsole::IResult *pResult, void *pUserData, I pThis->m_MapReload |= (pThis->m_apCurrentMapData[MAP_TYPE_SIXUP] != 0) != (pResult->GetInteger(0) != 0); } +void CServer::ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + CServer *pSelf = (CServer *)pUserData; + pfnCallback(pResult, pCallbackUserData); + if(pResult->NumArguments()) + { + pSelf->m_pFileLogger->SetFilter(CLogFilter{IConsole::ToLogLevelFilter(g_Config.m_Loglevel)}); + } +} + +void CServer::ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + CServer *pSelf = (CServer *)pUserData; + pfnCallback(pResult, pCallbackUserData); + if(pResult->NumArguments() && pSelf->m_pStdoutLogger) + { + pSelf->m_pStdoutLogger->SetFilter(CLogFilter{IConsole::ToLogLevelFilter(g_Config.m_StdoutOutputLevel)}); + } +} + #if defined(CONF_FAMILY_UNIX) void CServer::ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) { @@ -3736,7 +3754,6 @@ void CServer::RegisterCommands() RustVersionRegister(*Console()); Console()->Chain("sv_name", ConchainSpecialInfoupdate, this); - Console()->Chain("loglevel", ConchainLoglevel, this); Console()->Chain("password", ConchainSpecialInfoupdate, this); Console()->Chain("sv_max_clients_per_ip", ConchainMaxclientsperipUpdate, this); @@ -3748,6 +3765,9 @@ void CServer::RegisterCommands() Console()->Chain("sv_map", ConchainMapUpdate, this); Console()->Chain("sv_sixup", ConchainSixupUpdate, this); + Console()->Chain("loglevel", ConchainLoglevel, this); + Console()->Chain("stdout_output_level", ConchainStdoutOutputLevel, this); + #if defined(CONF_FAMILY_UNIX) Console()->Chain("sv_conn_logging_server", ConchainConnLoggingServerChange, this); #endif @@ -3868,3 +3888,9 @@ void CServer::SetErrorShutdown(const char *pReason) { str_copy(m_aErrorShutdownReason, pReason); } + +void CServer::SetLoggers(std::shared_ptr &&pFileLogger, std::shared_ptr &&pStdoutLogger) +{ + m_pFileLogger = pFileLogger; + m_pStdoutLogger = pStdoutLogger; +} diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 8e5285e63..4ad6a520d 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -36,6 +36,7 @@ class CLogMessage; class CMsgPacker; class CPacker; class IEngineMap; +class ILogger; class CSnapIDPool { @@ -273,6 +274,9 @@ public: std::vector m_vAnnouncements; char m_aAnnouncementFile[IO_MAX_PATH_LENGTH]; + std::shared_ptr m_pFileLogger = nullptr; + std::shared_ptr m_pStdoutLogger = nullptr; + CServer(); ~CServer(); @@ -418,7 +422,6 @@ public: static void ConAddSqlServer(IConsole::IResult *pResult, void *pUserData); static void ConDumpSqlServers(IConsole::IResult *pResult, void *pUserData); - static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainMaxclientsperipUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainCommandAccessUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); @@ -432,6 +435,8 @@ public: static void ConchainRconHelperPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainMapUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainSixupUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); + static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); + static void ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); #if defined(CONF_FAMILY_UNIX) static void ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); @@ -481,6 +486,8 @@ public: bool IsSixup(int ClientID) const override { return ClientID != SERVER_DEMO_CLIENT && m_aClients[ClientID].m_Sixup; } + void SetLoggers(std::shared_ptr &&pFileLogger, std::shared_ptr &&pStdoutLogger); + #ifdef CONF_FAMILY_UNIX enum CONN_LOGGING_CMD { diff --git a/src/engine/server/server_logger.cpp b/src/engine/server/server_logger.cpp index 6f05b99de..2d0e2d15a 100644 --- a/src/engine/server/server_logger.cpp +++ b/src/engine/server/server_logger.cpp @@ -11,6 +11,10 @@ CServerLogger::CServerLogger(CServer *pServer) : void CServerLogger::Log(const CLogMessage *pMessage) { + if(m_Filter.Filters(pMessage)) + { + return; + } m_PendingLock.lock(); if(m_MainThread == std::this_thread::get_id()) { diff --git a/src/engine/shared/assertion_logger.cpp b/src/engine/shared/assertion_logger.cpp index c8ff07a45..c37d6e054 100644 --- a/src/engine/shared/assertion_logger.cpp +++ b/src/engine/shared/assertion_logger.cpp @@ -30,6 +30,10 @@ public: void CAssertionLogger::Log(const CLogMessage *pMessage) { + if(m_Filter.Filters(pMessage)) + { + return; + } std::unique_lock Lock(m_DbgMessageMutex); SDebugMessageItem *pMsgItem = (SDebugMessageItem *)m_DbgMessages.Allocate(sizeof(SDebugMessageItem)); str_copy(pMsgItem->m_aMessage, pMessage->m_aLine); diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index f671446e3..e063aaef3 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -11,10 +11,11 @@ MACRO_CONFIG_STR(PlayerClan, player_clan, 12, "", CFGFLAG_SAVE | CFGFLAG_CLIENT MACRO_CONFIG_INT(PlayerCountry, player_country, -1, -1, 1000, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Country of the player") MACRO_CONFIG_STR(Password, password, 32, "", CFGFLAG_CLIENT | CFGFLAG_SERVER | CFGFLAG_NONTEEHISTORIC, "Password to the server") MACRO_CONFIG_STR(Logfile, logfile, 128, "", CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Filename to log all output to") -MACRO_CONFIG_INT(Loglevel, loglevel, 2, 0, 4, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Log level (0 = Error, 1 = Warn, 2 = Info, 3 = Debug, 4 = Trace)") +MACRO_CONFIG_INT(Loglevel, loglevel, 0, -3, 2, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Log level (-3 = none, -2 = error, 1 = Warn, 2 = Info, 3 = Debug, 4 = Trace)") MACRO_CONFIG_INT(Logappend, logappend, 1, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Append to logfile instead of overwriting it every time") -MACRO_CONFIG_INT(ConsoleOutputLevel, console_output_level, 0, 0, 2, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Adjusts the amount of information in the console") -MACRO_CONFIG_INT(ConsoleEnableColors, console_enable_colors, 1, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Enable colors in console output") +MACRO_CONFIG_INT(StdoutOutputLevel, stdout_output_level, 0, -3, 2, CFGFLAG_CLIENT | CFGFLAG_SERVER, "Adjusts the amount of information in the console (-3 = none, -2 = error only, -1 = warn, 0 = info, 1 = debug, 2 = trace)") +MACRO_CONFIG_INT(ConsoleOutputLevel, console_output_level, 0, -3, 2, CFGFLAG_CLIENT | CFGFLAG_SERVER, "Adjusts the amount of information in the console (-3 = none, -2 = error only, -1 = warn, 0 = info, 1 = debug, 2 = trace)") +MACRO_CONFIG_INT(ConsoleEnableColors, console_enable_colors, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SERVER, "Enable colors in console output") MACRO_CONFIG_INT(Events, events, 1, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Enable triggering of events, (eye emotes on some holidays in server, christmas skins in client).") MACRO_CONFIG_STR(SteamName, steam_name, 16, "", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Last seen name of the Steam profile") diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index d59902f6d..e7ed72dfb 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -293,6 +293,15 @@ LEVEL IConsole::ToLogLevel(int Level) return LEVEL_INFO; } +int IConsole::ToLogLevelFilter(int Level) +{ + if(!(-3 <= Level && Level <= 2)) + { + dbg_assert(0, "invalid log level filter"); + } + return Level + 2; +} + LOG_COLOR ColorToLogColor(ColorRGBA Color) { return LOG_COLOR{ diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index 5fba9a196..91603d21c 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -42,8 +42,7 @@ public: void CConsoleLogger::Log(const CLogMessage *pMessage) { - // TODO: Fix thread-unsafety of accessing `g_Config.m_ConsoleOutputLevel` - if(pMessage->m_Level > IConsole::ToLogLevel(g_Config.m_ConsoleOutputLevel)) + if(m_Filter.Filters(pMessage)) { return; } @@ -384,6 +383,8 @@ CGameConsole::CGameConsole() : m_ConsoleState = CONSOLE_CLOSED; m_StateChangeEnd = 0.0f; m_StateChangeDuration = 0.1f; + + m_pConsoleLogger = new CConsoleLogger(this); } CGameConsole::~CGameConsole() @@ -940,6 +941,16 @@ void CGameConsole::ConConsolePageDown(IConsole::IResult *pResult, void *pUserDat pConsole->m_BacklogCurPage = 0; } +void CGameConsole::ConchainConsoleOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + CGameConsole *pSelf = (CGameConsole *)pUserData; + pfnCallback(pResult, pCallbackUserData); + if(pResult->NumArguments()) + { + pSelf->m_pConsoleLogger->SetFilter(CLogFilter{IConsole::ToLogLevelFilter(g_Config.m_ConsoleOutputLevel)}); + } +} + void CGameConsole::RequireUsername(bool UsernameReq) { if((m_RemoteConsole.m_UsernameReq = UsernameReq)) @@ -974,11 +985,11 @@ void CGameConsole::OnConsoleInit() Console()->Register("console_page_up", "", CFGFLAG_CLIENT, ConConsolePageUp, this, "Previous page in console"); Console()->Register("console_page_down", "", CFGFLAG_CLIENT, ConConsolePageDown, this, "Next page in console"); + Console()->Chain("console_output_level", ConchainConsoleOutputLevel, this); } void CGameConsole::OnInit() { - m_pConsoleLogger = new CConsoleLogger(this); Engine()->SetAdditionalLogger(std::unique_ptr(m_pConsoleLogger)); // add resize event Graphics()->AddWindowResizeListener([this]() { diff --git a/src/game/client/components/console.h b/src/game/client/components/console.h index 6780c59d2..f9945d0f5 100644 --- a/src/game/client/components/console.h +++ b/src/game/client/components/console.h @@ -118,6 +118,7 @@ class CGameConsole : public CComponent static void ConDumpRemoteConsole(IConsole::IResult *pResult, void *pUserData); static void ConConsolePageUp(IConsole::IResult *pResult, void *pUserData); static void ConConsolePageDown(IConsole::IResult *pResult, void *pUserData); + static void ConchainConsoleOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); public: enum diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 105e74e89..66ba65fc8 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -54,6 +54,10 @@ void CClientChatLogger::Log(const CLogMessage *pMessage) { if(str_comp(pMessage->m_aSystem, "chatresp") == 0) { + if(m_Filter.Filters(pMessage)) + { + return; + } m_pGameServer->SendChatTarget(m_ClientID, pMessage->Message()); } else