aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-12-06 08:44:46 +0100
committerGitHub <[email protected]>2023-12-06 08:44:46 +0100
commit94fc3302c898825d7bc460ad4504577e33f744d9 (patch)
tree786ab5da6801dd5aabaca28f503c205af529363f /src
parentUse correct iterator index when looking up memcached payload in GatherReferen... (diff)
downloadzen-94fc3302c898825d7bc460ad4504577e33f744d9.tar.xz
zen-94fc3302c898825d7bc460ad4504577e33f744d9.zip
logging configuration via command line options (#589)
with these changes it is possible to configure loggers on the command line. For instance: `xmake run zenserver --log-trace=http_requests,http` will configure the system so that the `http_request` and `http` loggers are set to TRACE level
Diffstat (limited to 'src')
-rw-r--r--src/zencore/include/zencore/logging.h4
-rw-r--r--src/zencore/logging.cpp77
-rw-r--r--src/zenserver/config.cpp25
-rw-r--r--src/zenserver/config.h2
-rw-r--r--src/zenserver/diag/logging.cpp4
-rw-r--r--src/zenutil/logging.cpp9
6 files changed, 114 insertions, 7 deletions
diff --git a/src/zencore/include/zencore/logging.h b/src/zencore/include/zencore/logging.h
index d14d1ab8d..8b76d754c 100644
--- a/src/zencore/include/zencore/logging.h
+++ b/src/zencore/include/zencore/logging.h
@@ -35,6 +35,10 @@ LoggerRef ErrorLog();
void SetErrorLog(std::string_view LoggerId);
LoggerRef Get(std::string_view Name);
+void ConfigureLogLevels(level::LogLevel Level, std::string_view Loggers);
+void RefreshLogLevels();
+void RefreshLogLevels(level::LogLevel DefaultLevel);
+
struct LogCategory
{
inline LogCategory(std::string_view InCategory) : CategoryName(InCategory) {}
diff --git a/src/zencore/logging.cpp b/src/zencore/logging.cpp
index 025ed4262..0bf07affd 100644
--- a/src/zencore/logging.cpp
+++ b/src/zencore/logging.cpp
@@ -4,10 +4,14 @@
#include <zencore/string.h>
#include <zencore/testing.h>
+#include <zencore/thread.h>
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <spdlog/details/registry.h>
#include <spdlog/sinks/null_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
+ZEN_THIRD_PARTY_INCLUDES_END
#if ZEN_PLATFORM_WINDOWS
# pragma section(".zlog$a", read)
@@ -46,6 +50,8 @@ LoggingContext::~LoggingContext()
{
}
+//////////////////////////////////////////////////////////////////////////
+
static inline bool
IsErrorLevel(int LogLevel)
{
@@ -176,8 +182,77 @@ ToStringView(level::LogLevel Level)
} // namespace zen::logging::level
+//////////////////////////////////////////////////////////////////////////
+
namespace zen::logging {
+RwLock LogLevelsLock;
+std::string LogLevels[level::LogLevelCount];
+
+void
+ConfigureLogLevels(level::LogLevel Level, std::string_view Loggers)
+{
+ RwLock::ExclusiveLockScope _(LogLevelsLock);
+ LogLevels[Level] = Loggers;
+}
+
+void
+RefreshLogLevels(level::LogLevel* DefaultLevel)
+{
+ spdlog::details::registry::log_levels Levels;
+
+ {
+ RwLock::SharedLockScope _(LogLevelsLock);
+
+ for (int i = 0; i < level::LogLevelCount; ++i)
+ {
+ level::LogLevel CurrentLevel{i};
+
+ std::string_view Spec = LogLevels[i];
+
+ while (!Spec.empty())
+ {
+ std::string LoggerName;
+
+ if (auto CommaPos = Spec.find_first_of(','); CommaPos != std::string_view::npos)
+ {
+ LoggerName = Spec.substr(CommaPos + 1);
+ Spec.remove_prefix(CommaPos + 1);
+ }
+ else
+ {
+ LoggerName = Spec;
+ Spec = {};
+ }
+
+ Levels[LoggerName] = to_spdlog_level(CurrentLevel);
+ }
+ }
+ }
+
+ if (DefaultLevel)
+ {
+ spdlog::level::level_enum SpdDefaultLevel = to_spdlog_level(*DefaultLevel);
+ spdlog::details::registry::instance().set_levels(Levels, &SpdDefaultLevel);
+ }
+ else
+ {
+ spdlog::details::registry::instance().set_levels(Levels, nullptr);
+ }
+}
+
+void
+RefreshLogLevels(level::LogLevel DefaultLevel)
+{
+ RefreshLogLevels(&DefaultLevel);
+}
+
+void
+RefreshLogLevels()
+{
+ RefreshLogLevels(nullptr);
+}
+
void
SetLogLevel(level::LogLevel NewLogLevel)
{
@@ -240,6 +315,7 @@ Get(std::string_view Name)
if (!Logger)
{
Logger = Default().SpdLogger->clone(std::string(Name));
+ spdlog::apply_logger_env_levels(Logger);
spdlog::register_logger(Logger);
}
@@ -262,6 +338,7 @@ ConsoleLog()
if (!ConLogger)
{
ConLogger = spdlog::stdout_color_mt("console");
+ spdlog::apply_logger_env_levels(ConLogger);
ConLogger->set_pattern("%v");
}
diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp
index fe92613f4..3fe0b0c63 100644
--- a/src/zenserver/config.cpp
+++ b/src/zenserver/config.cpp
@@ -9,6 +9,7 @@
#include <zencore/except.h>
#include <zencore/fmtutils.h>
#include <zencore/iobuffer.h>
+#include <zencore/logging.h>
#include <zencore/string.h>
#include <zenhttp/zenhttp.h>
#include <zenutil/basicfile.h>
@@ -519,7 +520,6 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
cxxopts::value<bool>(ServerOptions.IsCleanStart)->default_value("false"));
options.add_options()("help", "Show command line help");
options.add_options()("t, test", "Enable test mode", cxxopts::value<bool>(ServerOptions.IsTest)->default_value("false"));
- options.add_options()("log-id", "Specify id for adding context to log output", cxxopts::value<std::string>(ServerOptions.LogId));
options.add_options()("data-dir", "Specify persistence root", cxxopts::value<std::string>(DataDir));
options.add_options()("snapshot-dir",
"Specify a snapshot of server state to mirror into the persistence root at startup",
@@ -528,7 +528,6 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
options.add_options()("powercycle",
"Exit immediately after initialization is complete",
cxxopts::value<bool>(ServerOptions.IsPowerCycle));
- options.add_options()("abslog", "Path to log file", cxxopts::value<std::string>(AbsLogFile));
options.add_options()("config", "Path to Lua config file", cxxopts::value<std::string>(ConfigFile));
options.add_options()("write-config", "Path to output Lua config file", cxxopts::value<std::string>(OutputConfigFile));
options.add_options()("no-sentry",
@@ -537,7 +536,21 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
options.add_options()("sentry-allow-personal-info",
"Allow personally identifiable information in sentry crash reports",
cxxopts::value<bool>(ServerOptions.SentryAllowPII)->default_value("false"));
- options.add_options()("quiet", "Disable console logging", cxxopts::value<bool>(ServerOptions.NoConsoleOutput)->default_value("false"));
+
+ // clang-format off
+ options.add_options("logging")
+ ("abslog", "Path to log file", cxxopts::value<std::string>(AbsLogFile))
+ ("log-id", "Specify id for adding context to log output", cxxopts::value<std::string>(ServerOptions.LogId))
+ ("quiet", "Disable console logging", cxxopts::value<bool>(ServerOptions.NoConsoleOutput)->default_value("false"))
+ ("log-trace", "Change selected loggers to level TRACE", cxxopts::value<std::string>(ServerOptions.Loggers[logging::level::Trace]))
+ ("log-debug", "Change selected loggers to level DEBUG", cxxopts::value<std::string>(ServerOptions.Loggers[logging::level::Debug]))
+ ("log-info", "Change selected loggers to level INFO", cxxopts::value<std::string>(ServerOptions.Loggers[logging::level::Info]))
+ ("log-warn", "Change selected loggers to level WARN", cxxopts::value<std::string>(ServerOptions.Loggers[logging::level::Warn]))
+ ("log-error", "Change selected loggers to level ERROR", cxxopts::value<std::string>(ServerOptions.Loggers[logging::level::Err]))
+ ("log-critical", "Change selected loggers to level CRITICAL", cxxopts::value<std::string>(ServerOptions.Loggers[logging::level::Critical]))
+ ("log-off", "Change selected loggers to level OFF", cxxopts::value<std::string>(ServerOptions.Loggers[logging::level::Off]))
+ ;
+ // clang-format on
options.add_option("security",
"",
@@ -952,6 +965,12 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
exit(0);
}
+ for (int i = 0; i < logging::level::LogLevelCount; ++i)
+ {
+ logging::ConfigureLogLevels(logging::level::LogLevel(i), ServerOptions.Loggers[i]);
+ }
+ logging::RefreshLogLevels();
+
ServerOptions.DataDir = MakeSafePath(DataDir);
ServerOptions.BaseSnapshotDir = MakeSafePath(BaseSnapshotDir);
ServerOptions.ContentDir = MakeSafePath(ContentDir);
diff --git a/src/zenserver/config.h b/src/zenserver/config.h
index 8135bf8f0..11311f9d8 100644
--- a/src/zenserver/config.h
+++ b/src/zenserver/config.h
@@ -2,6 +2,7 @@
#pragma once
+#include <zencore/logbase.h>
#include <zencore/zencore.h>
#include <zenhttp/httpserver.h>
#include <filesystem>
@@ -151,6 +152,7 @@ struct ZenServerOptions
bool SentryAllowPII = false; // Allow personally identifiable information in sentry crash reports
bool ObjectStoreEnabled = false;
bool NoConsoleOutput = false; // Control default use of stdout for diagnostics
+ std::string Loggers[zen::logging::level::LogLevelCount];
#if ZEN_WITH_TRACE
std::string TraceHost; // Host name or IP address to send trace data to
std::string TraceFile; // Path of a file to write a trace
diff --git a/src/zenserver/diag/logging.cpp b/src/zenserver/diag/logging.cpp
index e2d57b840..dc1675819 100644
--- a/src/zenserver/diag/logging.cpp
+++ b/src/zenserver/diag/logging.cpp
@@ -42,6 +42,7 @@ InitializeServerLogging(const ZenServerOptions& InOptions)
/* max files */ 16,
/* rotate on open */ true);
auto HttpLogger = std::make_shared<spdlog::logger>("http_requests", HttpSink);
+ spdlog::apply_logger_env_levels(HttpLogger);
spdlog::register_logger(HttpLogger);
// Cache request logging
@@ -53,16 +54,19 @@ InitializeServerLogging(const ZenServerOptions& InOptions)
/* max files */ 16,
/* rotate on open */ false);
auto CacheLogger = std::make_shared<spdlog::logger>("z$", CacheSink);
+ spdlog::apply_logger_env_levels(CacheLogger);
spdlog::register_logger(CacheLogger);
// Jupiter - only log upstream HTTP traffic to file
auto JupiterLogger = std::make_shared<spdlog::logger>("jupiter", FileSink);
+ spdlog::apply_logger_env_levels(JupiterLogger);
spdlog::register_logger(JupiterLogger);
// Zen - only log upstream HTTP traffic to file
auto ZenClientLogger = std::make_shared<spdlog::logger>("zenclient", FileSink);
+ spdlog::apply_logger_env_levels(ZenClientLogger);
spdlog::register_logger(ZenClientLogger);
FinishInitializeLogging(LogOptions);
diff --git a/src/zenutil/logging.cpp b/src/zenutil/logging.cpp
index d0a6ac0b4..d82789e42 100644
--- a/src/zenutil/logging.cpp
+++ b/src/zenutil/logging.cpp
@@ -12,6 +12,7 @@ ZEN_THIRD_PARTY_INCLUDES_END
#include <zencore/compactbinary.h>
#include <zencore/filesystem.h>
+#include <zencore/logging.h>
#include <zencore/string.h>
#include <zenutil/logging/fullformatter.h>
#include <zenutil/logging/jsonformatter.h>
@@ -152,21 +153,21 @@ BeginInitializeLogging(const LoggingOptions& LogOptions)
void
FinishInitializeLogging(const LoggingOptions& LogOptions)
{
- spdlog::level::level_enum LogLevel = spdlog::level::info;
+ logging::level::LogLevel LogLevel = logging::level::Info;
if (LogOptions.IsDebug)
{
- LogLevel = spdlog::level::debug;
+ LogLevel = logging::level::Debug;
}
if (LogOptions.IsTest)
{
- LogLevel = spdlog::level::trace;
+ LogLevel = logging::level::Trace;
}
// Configure all registered loggers according to settings
- spdlog::set_level(LogLevel);
+ logging::RefreshLogLevels(LogLevel);
spdlog::flush_on(spdlog::level::err);
spdlog::flush_every(std::chrono::seconds{2});
spdlog::set_formatter(std::make_unique<logging::full_formatter>(LogOptions.LogId, std::chrono::system_clock::now()));