mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-04 11:55:51 +00:00
refactor: Put log options in log section in config (#2440)
This commit is contained in:
@@ -13,8 +13,8 @@ Clio repository provides an [example](https://github.com/XRPLF/clio/blob/develop
|
||||
|
||||
Config file recommendations:
|
||||
|
||||
- Set `log_to_console` to `false` if you want to avoid logs being written to `stdout`.
|
||||
- Set `log_directory` to `/opt/clio/log` to store logs in a volume.
|
||||
- Set `log.enable_console` to `false` if you want to avoid logs being written to `stdout`.
|
||||
- Set `log.directory` to `/opt/clio/log` to store logs in a volume.
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@@ -415,7 +415,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: The value must be one of the following: `sync`, `async`, `none`.
|
||||
- **Description**: The strategy used for Cache loading.
|
||||
|
||||
### log_channels.[].channel
|
||||
### log.channels.[].channel
|
||||
|
||||
- **Required**: False
|
||||
- **Type**: string
|
||||
@@ -423,7 +423,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: The value must be one of the following: `General`, `WebServer`, `Backend`, `RPC`, `ETL`, `Subscriptions`, `Performance`, `Migration`.
|
||||
- **Description**: The name of the log channel.
|
||||
|
||||
### log_channels.[].log_level
|
||||
### log.channels.[].level
|
||||
|
||||
- **Required**: False
|
||||
- **Type**: string
|
||||
@@ -431,7 +431,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`.
|
||||
- **Description**: The log level for the specific log channel.
|
||||
|
||||
### log_level
|
||||
### log.level
|
||||
|
||||
- **Required**: True
|
||||
- **Type**: string
|
||||
@@ -439,7 +439,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`.
|
||||
- **Description**: The general logging level of Clio. This level is applied to all log channels that do not have an explicitly defined logging level.
|
||||
|
||||
### spdlog_format
|
||||
### log.format
|
||||
|
||||
- **Required**: True
|
||||
- **Type**: string
|
||||
@@ -447,7 +447,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: None
|
||||
- **Description**: The format string for log messages using spdlog format patterns. Documentation can be found at: <https://github.com/gabime/spdlog/wiki/Custom-formatting>.
|
||||
|
||||
### spdlog_async
|
||||
### log.is_async
|
||||
|
||||
- **Required**: True
|
||||
- **Type**: boolean
|
||||
@@ -455,7 +455,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: None
|
||||
- **Description**: Whether spdlog is asynchronous or not.
|
||||
|
||||
### log_to_console
|
||||
### log.enable_console
|
||||
|
||||
- **Required**: True
|
||||
- **Type**: boolean
|
||||
@@ -463,7 +463,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: None
|
||||
- **Description**: Enables or disables logging to the console.
|
||||
|
||||
### log_directory
|
||||
### log.directory
|
||||
|
||||
- **Required**: False
|
||||
- **Type**: string
|
||||
@@ -471,7 +471,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: None
|
||||
- **Description**: The directory path for the log files.
|
||||
|
||||
### log_rotation_size
|
||||
### log.rotation_size
|
||||
|
||||
- **Required**: True
|
||||
- **Type**: int
|
||||
@@ -479,7 +479,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
|
||||
- **Description**: The log rotation size in megabytes. When the log file reaches this particular size, a new log file starts.
|
||||
|
||||
### log_directory_max_files
|
||||
### log.directory_max_files
|
||||
|
||||
- **Required**: True
|
||||
- **Type**: int
|
||||
@@ -487,7 +487,7 @@ This document provides a list of all available Clio configuration properties in
|
||||
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
|
||||
- **Description**: The maximum number of log files in the directory.
|
||||
|
||||
### log_tag_style
|
||||
### log.tag_style
|
||||
|
||||
- **Required**: True
|
||||
- **Type**: string
|
||||
|
||||
@@ -80,34 +80,52 @@
|
||||
},
|
||||
// Time in seconds for graceful shutdown. Defaults to 10 seconds. Not fully implemented yet.
|
||||
"graceful_period": 10.0,
|
||||
// Overrides log level on a per logging channel.
|
||||
// Defaults to global "log_level" for each unspecified channel.
|
||||
"log_channels": [
|
||||
{
|
||||
"channel": "Backend",
|
||||
"log_level": "fatal"
|
||||
},
|
||||
{
|
||||
"channel": "WebServer",
|
||||
"log_level": "info"
|
||||
},
|
||||
{
|
||||
"channel": "Subscriptions",
|
||||
"log_level": "info"
|
||||
},
|
||||
{
|
||||
"channel": "RPC",
|
||||
"log_level": "error"
|
||||
},
|
||||
{
|
||||
"channel": "ETL",
|
||||
"log_level": "debug"
|
||||
},
|
||||
{
|
||||
"channel": "Performance",
|
||||
"log_level": "trace"
|
||||
}
|
||||
],
|
||||
"log": {
|
||||
// Overrides log level on a per logging channel.
|
||||
// Defaults to global "log.level" for each unspecified channel.
|
||||
"channels": [
|
||||
{
|
||||
"channel": "Backend",
|
||||
"level": "fatal"
|
||||
},
|
||||
{
|
||||
"channel": "WebServer",
|
||||
"level": "info"
|
||||
},
|
||||
{
|
||||
"channel": "Subscriptions",
|
||||
"level": "info"
|
||||
},
|
||||
{
|
||||
"channel": "RPC",
|
||||
"level": "error"
|
||||
},
|
||||
{
|
||||
"channel": "ETL",
|
||||
"level": "debug"
|
||||
},
|
||||
{
|
||||
"channel": "Performance",
|
||||
"level": "trace"
|
||||
}
|
||||
],
|
||||
// The general logging level of Clio. This level is applied to all log channels that do not have an explicitly defined logging level.
|
||||
"level": "info",
|
||||
// Log format using spdlog format patterns (this is the default format)
|
||||
"format": "%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v",
|
||||
// Whether spdlog is asynchronous or not.
|
||||
"is_async": true,
|
||||
// Enables or disables logging to the console.
|
||||
"enable_console": true,
|
||||
// Clio logs to file in the specified directory only if "log.directory" is set
|
||||
// "directory": "./clio_log",
|
||||
// The log rotation size in megabytes. When the log file reaches this particular size, a new log file starts.
|
||||
"rotation_size": 2048,
|
||||
// The maximum number of log files in the directory.
|
||||
"directory_max_files": 25,
|
||||
// Log tags style to use
|
||||
"tag_style": "uint"
|
||||
},
|
||||
"cache": {
|
||||
// Configure this to use either "num_diffs", "num_cursors_from_diff", or "num_cursors_from_account". By default, Clio uses "num_diffs".
|
||||
"num_diffs": 32, // Generate the cursors from the latest ledger diff, then use the cursors to partition the ledger to load concurrently. The cursors number is affected by the busyness of the network.
|
||||
@@ -121,17 +139,6 @@
|
||||
"enabled": true,
|
||||
"compress_reply": true
|
||||
},
|
||||
"log_level": "info",
|
||||
// Log format using spdlog format patterns (this is the default format)
|
||||
"spdlog_format": "%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v",
|
||||
// Whether spdlog is asynchronous or not.
|
||||
"spdlog_async": true,
|
||||
"log_to_console": true,
|
||||
// Clio logs to file in the specified directory only if "log_directory" is set
|
||||
// "log_directory": "./clio_log",
|
||||
"log_rotation_size": 2048,
|
||||
"log_directory_max_files": 25,
|
||||
"log_tag_style": "uint",
|
||||
"extractor_threads": 8,
|
||||
"read_only": false,
|
||||
// "start_sequence": [integer] the ledger index to start from,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# Logging
|
||||
|
||||
Clio provides several logging options, which all are configurable via the config file. These are detailed in the following sections.
|
||||
Clio provides several logging options, which all are configurable via the config file under the `log` section.
|
||||
These are detailed in the following sections.
|
||||
|
||||
## `log_level`
|
||||
## `log.level`
|
||||
|
||||
The minimum level of severity at which the log message will be outputted by default. Severity options are `trace`, `debug`, `info`, `warning`, `error`, `fatal`. Defaults to `info`.
|
||||
|
||||
## `spdlog_format`
|
||||
## `log.format`
|
||||
|
||||
The format of log lines produced by Clio using spdlog format patterns. Defaults to `"%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v"`.
|
||||
|
||||
@@ -26,52 +27,52 @@ Some additional variables that might be useful:
|
||||
|
||||
For more information about spdlog format patterns, see: <https://github.com/gabime/spdlog/wiki/Custom-formatting>
|
||||
|
||||
## `spdlog_async`
|
||||
## `log.is_async`
|
||||
|
||||
Whether spdlog is asynchronous or not.
|
||||
|
||||
## `log_channels`
|
||||
## `log.channels`
|
||||
|
||||
An array of JSON objects, each overriding properties for a logging `channel`.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> At the time of writing, only `log_level` can be overridden using this mechanism.
|
||||
> At the time of writing, only `log.level` can be overridden using this mechanism.
|
||||
|
||||
Each object is of this format:
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "Backend",
|
||||
"log_level": "fatal"
|
||||
"level": "fatal"
|
||||
}
|
||||
```
|
||||
|
||||
If no override is present for a given channel, that channel will log at the severity specified by the global `log_level`.
|
||||
If no override is present for a given channel, that channel will log at the severity specified by the global `log.level`.
|
||||
|
||||
The log channels that can be overridden are: `Backend`, `WebServer`, `Subscriptions`, `RPC`, `ETL` and `Performance`.
|
||||
|
||||
> [!NOTE]
|
||||
> See [example-config.json](../docs/examples/config/example-config.json) for more details.
|
||||
|
||||
## `log_to_console`
|
||||
## `log.enable_console`
|
||||
|
||||
Enable or disable log output to console. Options are `true`/`false`. This option defaults to `true`.
|
||||
|
||||
## `log_directory`
|
||||
## `log.directory`
|
||||
|
||||
Path to the directory where log files are stored. If such directory doesn't exist, Clio will create it.
|
||||
|
||||
If the option is not specified, the logs are not written to a file.
|
||||
|
||||
## `log_rotation_size`
|
||||
## `log.rotation_size`
|
||||
|
||||
The max size of the log file in **megabytes** before it will rotate into a smaller file. Defaults to 2GB.
|
||||
|
||||
## `log_directory_max_files`
|
||||
## `log.directory_max_files`
|
||||
|
||||
The max number of log files in the directory before old log files will be deleted to free up space. Defaults to 25.
|
||||
|
||||
## `log_tag_style`
|
||||
## `log.tag_style`
|
||||
|
||||
Tag implementation to use. Must be one of:
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ class TagDecoratorFactory final {
|
||||
if (boost::iequals(style, "uuid"))
|
||||
return TagDecoratorFactory::Type::UUID;
|
||||
|
||||
ASSERT(false, "log_tag_style does not have valid value");
|
||||
ASSERT(false, "log.tag_style does not have valid value");
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ public:
|
||||
* @param config The configuration as a json object
|
||||
*/
|
||||
explicit TagDecoratorFactory(util::config::ClioConfigDefinition const& config)
|
||||
: type_{getLogTagType(config.get<std::string>("log_tag_style"))}
|
||||
: type_{getLogTagType(config.get<std::string>("log.tag_style"))}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -465,10 +465,10 @@ static constinit PortConstraint gValidatePort{};
|
||||
static constinit ValidIPConstraint gValidateIp{};
|
||||
|
||||
static constinit OneOf gValidateChannelName{"channel", Logger::kCHANNELS};
|
||||
static constinit OneOf gValidateLogLevelName{"log_level", kLOG_LEVELS};
|
||||
static constinit OneOf gValidateLogLevelName{"log.level", kLOG_LEVELS};
|
||||
static constinit OneOf gValidateCassandraName{"database.type", kDATABASE_TYPE};
|
||||
static constinit OneOf gValidateLoadMode{"cache.load", kLOAD_CACHE_MODE};
|
||||
static constinit OneOf gValidateLogTag{"log_tag_style", kLOG_TAGS};
|
||||
static constinit OneOf gValidateLogTag{"log.tag_style", kLOG_TAGS};
|
||||
static constinit OneOf gValidateProcessingPolicy{"server.processing_policy", kPROCESSING_POLICY};
|
||||
|
||||
static constinit PositiveDouble gValidatePositiveDouble{};
|
||||
|
||||
@@ -351,26 +351,26 @@ getClioConfig()
|
||||
{"cache.page_fetch_size", ConfigValue{ConfigType::Integer}.defaultValue(512).withConstraint(gValidateUint16)},
|
||||
{"cache.load", ConfigValue{ConfigType::String}.defaultValue("async").withConstraint(gValidateLoadMode)},
|
||||
|
||||
{"log_channels.[].channel",
|
||||
{"log.channels.[].channel",
|
||||
Array{ConfigValue{ConfigType::String}.optional().withConstraint(gValidateChannelName)}},
|
||||
{"log_channels.[].log_level",
|
||||
{"log.channels.[].level",
|
||||
Array{ConfigValue{ConfigType::String}.optional().withConstraint(gValidateLogLevelName)}},
|
||||
|
||||
{"log_level", ConfigValue{ConfigType::String}.defaultValue("info").withConstraint(gValidateLogLevelName)},
|
||||
{"log.level", ConfigValue{ConfigType::String}.defaultValue("info").withConstraint(gValidateLogLevelName)},
|
||||
|
||||
{"spdlog_format", ConfigValue{ConfigType::String}.defaultValue(R"(%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v)")},
|
||||
{"log.format", ConfigValue{ConfigType::String}.defaultValue(R"(%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v)")},
|
||||
|
||||
{"spdlog_async", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
|
||||
{"log.is_async", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
|
||||
|
||||
{"log_to_console", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
|
||||
{"log.enable_console", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
|
||||
|
||||
{"log_directory", ConfigValue{ConfigType::String}.optional()},
|
||||
{"log.directory", ConfigValue{ConfigType::String}.optional()},
|
||||
|
||||
{"log_rotation_size", ConfigValue{ConfigType::Integer}.defaultValue(2048).withConstraint(gValidateUint32)},
|
||||
{"log.rotation_size", ConfigValue{ConfigType::Integer}.defaultValue(2048).withConstraint(gValidateUint32)},
|
||||
|
||||
{"log_directory_max_files", ConfigValue{ConfigType::Integer}.defaultValue(25).withConstraint(gValidateUint32)},
|
||||
{"log.directory_max_files", ConfigValue{ConfigType::Integer}.defaultValue(25).withConstraint(gValidateUint32)},
|
||||
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("none").withConstraint(gValidateLogTag)},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("none").withConstraint(gValidateLogTag)},
|
||||
|
||||
{"extractor_threads", ConfigValue{ConfigType::Integer}.defaultValue(1u).withConstraint(gValidateUint32)},
|
||||
|
||||
|
||||
@@ -258,22 +258,22 @@ private:
|
||||
"If set to `0`, the system defaults to generating cursors based on `cache.num_diffs`."},
|
||||
KV{.key = "cache.page_fetch_size", .value = "The number of ledger objects to fetch concurrently per marker."},
|
||||
KV{.key = "cache.load", .value = "The strategy used for Cache loading."},
|
||||
KV{.key = "log_channels.[].channel", .value = "The name of the log channel."},
|
||||
KV{.key = "log_channels.[].log_level", .value = "The log level for the specific log channel."},
|
||||
KV{.key = "log_level",
|
||||
KV{.key = "log.channels.[].channel", .value = "The name of the log channel."},
|
||||
KV{.key = "log.channels.[].level", .value = "The log level for the specific log channel."},
|
||||
KV{.key = "log.level",
|
||||
.value = "The general logging level of Clio. This level is applied to all log channels that do not have an "
|
||||
"explicitly defined logging level."},
|
||||
KV{.key = "spdlog_format",
|
||||
KV{.key = "log.format",
|
||||
.value = "The format string for log messages using spdlog format patterns. Documentation can be found at: "
|
||||
"<https://github.com/gabime/spdlog/wiki/Custom-formatting>."},
|
||||
KV{.key = "spdlog_async", .value = "Whether spdlog is asynchronous or not."},
|
||||
KV{.key = "log_to_console", .value = "Enables or disables logging to the console."},
|
||||
KV{.key = "log_directory", .value = "The directory path for the log files."},
|
||||
KV{.key = "log_rotation_size",
|
||||
KV{.key = "log.is_async", .value = "Whether spdlog is asynchronous or not."},
|
||||
KV{.key = "log.enable_console", .value = "Enables or disables logging to the console."},
|
||||
KV{.key = "log.directory", .value = "The directory path for the log files."},
|
||||
KV{.key = "log.rotation_size",
|
||||
.value = "The log rotation size in megabytes. When the log file reaches this particular size, a new log "
|
||||
"file starts."},
|
||||
KV{.key = "log_directory_max_files", .value = "The maximum number of log files in the directory."},
|
||||
KV{.key = "log_tag_style",
|
||||
KV{.key = "log.directory_max_files", .value = "The maximum number of log files in the directory."},
|
||||
KV{.key = "log.tag_style",
|
||||
.value =
|
||||
"Log tags are unique identifiers for log messages. `uint`/`int` starts logging from 0 and increments, "
|
||||
"making it faster. In contrast, `uuid` generates a random unique identifier, which adds overhead."},
|
||||
|
||||
@@ -116,7 +116,7 @@ getSeverityLevel(std::string_view logLevel)
|
||||
return Severity::FTL;
|
||||
|
||||
// already checked during parsing of config that value must be valid
|
||||
ASSERT(false, "Parsing of log_level is incorrect");
|
||||
ASSERT(false, "Parsing of log level is incorrect");
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ getMinSeverity(config::ClioConfigDefinition const& config, Severity defaultSever
|
||||
for (auto const& channel : Logger::kCHANNELS)
|
||||
minSeverity[channel] = defaultSeverity;
|
||||
|
||||
auto const overrides = config.getArray("log_channels");
|
||||
auto const overrides = config.getArray("log.channels");
|
||||
|
||||
for (auto it = overrides.begin<util::config::ObjectView>(); it != overrides.end<util::config::ObjectView>(); ++it) {
|
||||
auto const& channelConfig = *it;
|
||||
@@ -190,7 +190,7 @@ getMinSeverity(config::ClioConfigDefinition const& config, Severity defaultSever
|
||||
return std::unexpected{fmt::format("Can't override settings for log channel {}: invalid channel", name)};
|
||||
}
|
||||
|
||||
minSeverity[name] = getSeverityLevel(channelConfig.get<std::string>("log_level"));
|
||||
minSeverity[name] = getSeverityLevel(channelConfig.get<std::string>("level"));
|
||||
}
|
||||
|
||||
return minSeverity;
|
||||
@@ -226,15 +226,15 @@ LogService::init(config::ClioConfigDefinition const& config)
|
||||
// Drop existing loggers
|
||||
spdlog::drop_all();
|
||||
|
||||
data.isAsync = config.get<bool>("spdlog_async");
|
||||
data.isAsync = config.get<bool>("log.is_async");
|
||||
|
||||
if (data.isAsync) {
|
||||
spdlog::init_thread_pool(8192, 1);
|
||||
}
|
||||
|
||||
data.allSinks = createConsoleSinks(config.get<bool>("log_to_console"));
|
||||
data.allSinks = createConsoleSinks(config.get<bool>("log.enable_console"));
|
||||
|
||||
if (auto const logDir = config.maybeValue<std::string>("log_directory"); logDir.has_value()) {
|
||||
if (auto const logDir = config.maybeValue<std::string>("log.directory"); logDir.has_value()) {
|
||||
std::filesystem::path const dirPath{logDir.value()};
|
||||
if (not std::filesystem::exists(dirPath)) {
|
||||
if (std::error_code error; not std::filesystem::create_directories(dirPath, error)) {
|
||||
@@ -246,14 +246,14 @@ LogService::init(config::ClioConfigDefinition const& config)
|
||||
|
||||
FileLoggingParams const params{
|
||||
.logDir = logDir.value(),
|
||||
.rotationSizeMB = config.get<uint32_t>("log_rotation_size"),
|
||||
.dirMaxFiles = config.get<uint32_t>("log_directory_max_files"),
|
||||
.rotationSizeMB = config.get<uint32_t>("log.rotation_size"),
|
||||
.dirMaxFiles = config.get<uint32_t>("log.directory_max_files"),
|
||||
};
|
||||
data.allSinks.push_back(createFileSink(params));
|
||||
}
|
||||
|
||||
// get default severity, can be overridden per channel using the `log_channels` array
|
||||
auto const defaultSeverity = getSeverityLevel(config.get<std::string>("log_level"));
|
||||
// get default severity, can be overridden per channel using the `log.channels` array
|
||||
auto const defaultSeverity = getSeverityLevel(config.get<std::string>("log.level"));
|
||||
auto const maybeMinSeverity = getMinSeverity(config, defaultSeverity);
|
||||
if (!maybeMinSeverity) {
|
||||
return std::unexpected{maybeMinSeverity.error()};
|
||||
@@ -269,7 +269,7 @@ LogService::init(config::ClioConfigDefinition const& config)
|
||||
|
||||
spdlog::set_default_logger(spdlog::get("General"));
|
||||
|
||||
std::string const format = config.get<std::string>("spdlog_format");
|
||||
std::string const format = config.get<std::string>("log.format");
|
||||
spdlog::set_pattern(format);
|
||||
|
||||
LOG(LogService::info()) << "Default log level = " << toString(defaultSeverity);
|
||||
|
||||
@@ -40,7 +40,7 @@ struct MockSession : public web::SubscriptionContextInterface {
|
||||
MOCK_METHOD(uint32_t, apiSubversion, (), (const, override));
|
||||
|
||||
util::TagDecoratorFactory tagDecoratorFactory{util::config::ClioConfigDefinition{
|
||||
{"log_tag_style", util::config::ConfigValue{util::config::ConfigType::String}.defaultValue("none")}
|
||||
{"log.tag_style", util::config::ConfigValue{util::config::ConfigType::String}.defaultValue("none")}
|
||||
}};
|
||||
|
||||
MockSession() : web::SubscriptionContextInterface(tagDecoratorFactory)
|
||||
|
||||
@@ -53,25 +53,25 @@ using util::config::ConfigValue;
|
||||
struct LogServiceInitTests : virtual public ::testing::Test {
|
||||
protected:
|
||||
util::config::ClioConfigDefinition config_{
|
||||
{"log_channels.[].channel", Array{ConfigValue{ConfigType::String}}},
|
||||
{"log_channels.[].log_level", Array{ConfigValue{ConfigType::String}}},
|
||||
{"log.channels.[].channel", Array{ConfigValue{ConfigType::String}}},
|
||||
{"log.channels.[].level", Array{ConfigValue{ConfigType::String}}},
|
||||
|
||||
{"log_level", ConfigValue{ConfigType::String}.defaultValue("info")},
|
||||
{"log.level", ConfigValue{ConfigType::String}.defaultValue("info")},
|
||||
|
||||
{"spdlog_format", ConfigValue{ConfigType::String}.defaultValue(R"(%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v)")},
|
||||
{"spdlog_async", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
|
||||
{"log.format", ConfigValue{ConfigType::String}.defaultValue(R"(%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v)")},
|
||||
{"log.is_async", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
|
||||
|
||||
{"log_to_console", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
|
||||
{"log.enable_console", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
|
||||
|
||||
{"log_directory", ConfigValue{ConfigType::String}.optional()},
|
||||
{"log.directory", ConfigValue{ConfigType::String}.optional()},
|
||||
|
||||
{"log_rotation_size",
|
||||
{"log.rotation_size",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(2048).withConstraint(config::gValidateUint32)},
|
||||
|
||||
{"log_directory_max_files",
|
||||
{"log.directory_max_files",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(25).withConstraint(config::gValidateUint32)},
|
||||
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("none")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("none")},
|
||||
};
|
||||
|
||||
std::string
|
||||
@@ -104,7 +104,8 @@ private:
|
||||
|
||||
TEST_F(LogServiceInitTests, DefaultLogLevel)
|
||||
{
|
||||
auto const parsingErrors = config_.parse(ConfigFileJson{boost::json::object{{"log_level", "warn"}}});
|
||||
auto const parsingErrors =
|
||||
config_.parse(ConfigFileJson{boost::json::object{{"log", boost::json::object{{"level", "warn"}}}}});
|
||||
ASSERT_FALSE(parsingErrors.has_value());
|
||||
std::string const logString = "some log";
|
||||
|
||||
@@ -134,13 +135,15 @@ TEST_F(LogServiceInitTests, ChannelLogLevel)
|
||||
{
|
||||
std::string const configStr = R"JSON(
|
||||
{
|
||||
"log_level": "error",
|
||||
"log_channels": [
|
||||
{
|
||||
"channel": "Backend",
|
||||
"log_level": "warning"
|
||||
}
|
||||
]
|
||||
"log": {
|
||||
"level": "error",
|
||||
"channels": [
|
||||
{
|
||||
"channel": "Backend",
|
||||
"level": "warning"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
)JSON";
|
||||
|
||||
@@ -177,7 +180,8 @@ TEST_F(LogServiceInitTests, ChannelLogLevel)
|
||||
TEST_F(LogServiceInitTests, InitReturnsErrorIfCouldNotCreateLogDirectory)
|
||||
{
|
||||
// "/proc" directory is read only on any unix OS
|
||||
auto const parsingErrors = config_.parse(ConfigFileJson{boost::json::object{{"log_directory", "/proc/logs"}}});
|
||||
auto const parsingErrors =
|
||||
config_.parse(ConfigFileJson{boost::json::object{{"log", boost::json::object{{"directory", "/proc/logs"}}}}});
|
||||
ASSERT_FALSE(parsingErrors.has_value());
|
||||
|
||||
auto const result = LogService::init(config_);
|
||||
@@ -189,12 +193,14 @@ TEST_F(LogServiceInitTests, InitReturnsErrorIfProvidedInvalidChannel)
|
||||
{
|
||||
auto const jsonStr = R"JSON(
|
||||
{
|
||||
"log_channels": [
|
||||
{
|
||||
"channel": "SomeChannel",
|
||||
"log_level": "warn"
|
||||
}
|
||||
]
|
||||
"log": {
|
||||
"channels": [
|
||||
{
|
||||
"channel": "SomeChannel",
|
||||
"level": "warn"
|
||||
}
|
||||
]
|
||||
}
|
||||
})JSON";
|
||||
|
||||
auto const json = boost::json::parse(jsonStr).as_object();
|
||||
@@ -208,7 +214,7 @@ TEST_F(LogServiceInitTests, InitReturnsErrorIfProvidedInvalidChannel)
|
||||
|
||||
TEST_F(LogServiceInitTests, LogSizeAndHourRotationCannotBeZero)
|
||||
{
|
||||
std::vector<std::string_view> const keys{"log_directory_max_files", "log_rotation_size"};
|
||||
std::vector<std::string_view> const keys{"log.directory_max_files", "log.rotation_size"};
|
||||
|
||||
auto const jsonStr = fmt::format(
|
||||
R"JSON(
|
||||
|
||||
@@ -57,7 +57,7 @@ using namespace util::config;
|
||||
struct WebHandlersTest : virtual NoLoggerFixture {
|
||||
DOSGuardStrictMock dosGuardMock;
|
||||
util::TagDecoratorFactory const tagFactory{
|
||||
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
ClioConfigDefinition{{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
};
|
||||
std::string const ip = "some ip";
|
||||
StrictMockConnection connectionMock{ip, boost::beast::flat_buffer{}, tagFactory};
|
||||
|
||||
@@ -57,7 +57,7 @@ protected:
|
||||
std::shared_ptr<MockHandlerProvider> handlerProvider_ = std::make_shared<MockHandlerProvider>();
|
||||
MockCounters counters_;
|
||||
|
||||
ClioConfigDefinition const config_{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("none")}};
|
||||
ClioConfigDefinition const config_{{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("none")}};
|
||||
util::TagDecoratorFactory tagFactory_{config_};
|
||||
|
||||
rpc::impl::ForwardingProxy<MockCounters, MockHandlerProvider> proxy_{loadBalancer_, counters_, handlerProvider_};
|
||||
|
||||
@@ -80,7 +80,7 @@ generateDefaultRPCEngineConfig()
|
||||
{"workers", ConfigValue{ConfigType::Integer}.defaultValue(4).withConstraint(gValidateUint16)},
|
||||
{"rpc.cache_timeout",
|
||||
ConfigValue{ConfigType::Double}.defaultValue(0.0).withConstraint(gValidatePositiveDouble)},
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"dos_guard.whitelist.[]", Array{ConfigValue{ConfigType::String}.optional()}},
|
||||
{"dos_guard.max_fetches",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(1000'000u).withConstraint(gValidateUint32)},
|
||||
|
||||
@@ -1299,7 +1299,7 @@ struct RPCHelpersLogDurationTest : LoggerFixture, testing::WithParamInterface<RP
|
||||
}}
|
||||
};
|
||||
util::TagDecoratorFactory tagFactory{util::config::ClioConfigDefinition{
|
||||
{"log_tag_style", util::config::ConfigValue{util::config::ConfigType::String}.defaultValue("none")}
|
||||
{"log.tag_style", util::config::ConfigValue{util::config::ConfigType::String}.defaultValue("none")}
|
||||
}};
|
||||
struct DummyTaggable : util::Taggable {
|
||||
DummyTaggable(util::TagDecoratorFactory& f) : util::Taggable(f)
|
||||
|
||||
@@ -182,17 +182,17 @@ TEST_F(ConstraintTest, OneOfConstraintOneValue)
|
||||
TEST_F(ConstraintTest, OneOfConstraint)
|
||||
{
|
||||
std::array<char const*, 3> const arr = {"123", "trace", "haha"};
|
||||
auto const oneOfCons{OneOf{"log_level", arr}};
|
||||
auto const oneOfCons{OneOf{"log.level", arr}};
|
||||
|
||||
EXPECT_FALSE(oneOfCons.checkConstraint("trace").has_value());
|
||||
|
||||
EXPECT_TRUE(oneOfCons.checkConstraint(345).has_value());
|
||||
EXPECT_EQ(oneOfCons.checkConstraint(345)->error, R"(Key "log_level"'s value must be a string)");
|
||||
EXPECT_EQ(oneOfCons.checkConstraint(345)->error, R"(Key "log.level"'s value must be a string)");
|
||||
|
||||
EXPECT_TRUE(oneOfCons.checkConstraint("PETER_WAS_HERE").has_value());
|
||||
EXPECT_EQ(
|
||||
oneOfCons.checkConstraint("PETER_WAS_HERE")->error,
|
||||
R"(You provided value "PETER_WAS_HERE". Key "log_level"'s value must be one of the following: 123, trace, haha)"
|
||||
R"(You provided value "PETER_WAS_HERE". Key "log.level"'s value must be one of the following: 123, trace, haha)"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ struct MockWsBase : public web::ConnectionBase {
|
||||
|
||||
struct WebRPCServerHandlerTest : util::prometheus::WithPrometheus, MockBackendTest, SyncAsioContextTest {
|
||||
util::config::ClioConfigDefinition cfg{
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("none")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("none")},
|
||||
{"api_version.default", ConfigValue{ConfigType::Integer}.defaultValue(rpc::kAPI_VERSION_DEFAULT)},
|
||||
{"api_version.min", ConfigValue{ConfigType::Integer}.defaultValue(rpc::kAPI_VERSION_MIN)},
|
||||
{"api_version.max", ConfigValue{ConfigType::Integer}.defaultValue(rpc::kAPI_VERSION_MAX)}
|
||||
|
||||
@@ -125,7 +125,7 @@ getParseServerConfig(boost::json::value val)
|
||||
{"server.admin_password", ConfigValue{ConfigType::String}.optional()},
|
||||
{"server.local_admin", ConfigValue{ConfigType::Boolean}.optional()},
|
||||
{"server.ws_max_sending_queue_size", ConfigValue{ConfigType::Integer}.defaultValue(1500)},
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"dos_guard.max_fetches", ConfigValue{ConfigType::Integer}},
|
||||
{"dos_guard.sweep_interval", ConfigValue{ConfigType::Integer}},
|
||||
{"dos_guard.max_connections", ConfigValue{ConfigType::Integer}},
|
||||
@@ -525,7 +525,7 @@ getParseAdminServerConfig(boost::json::value val)
|
||||
{"ssl_key_file", ConfigValue{ConfigType::String}.optional()},
|
||||
{"prometheus.enabled", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
|
||||
{"prometheus.compress_reply", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}
|
||||
};
|
||||
auto const errors = config.parse(jsonVal);
|
||||
[&]() { ASSERT_FALSE(errors.has_value()); }();
|
||||
|
||||
@@ -38,7 +38,7 @@ using namespace util::config;
|
||||
struct SubscriptionContextTests : NoLoggerFixture {
|
||||
protected:
|
||||
util::TagDecoratorFactory tagFactory_{ClioConfigDefinition{
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
}};
|
||||
ConnectionBaseStrictMockPtr connection_ =
|
||||
std::make_shared<testing::StrictMock<ConnectionBaseMock>>(tagFactory_, "some ip");
|
||||
|
||||
@@ -44,7 +44,7 @@ using namespace util::config;
|
||||
struct ErrorHandlingTests : NoLoggerFixture {
|
||||
protected:
|
||||
util::TagDecoratorFactory tagFactory_{ClioConfigDefinition{
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
}};
|
||||
std::string const clientIp_ = "some ip";
|
||||
ConnectionBaseStrictMockPtr connection_ =
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace http = boost::beast::http;
|
||||
|
||||
struct NgRpcServerHandlerTest : util::prometheus::WithPrometheus, MockBackendTestStrict, SyncAsioContextTest {
|
||||
ClioConfigDefinition config{ClioConfigDefinition{
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"api_version.min", ConfigValue{ConfigType::Integer}.defaultValue(1)},
|
||||
{"api_version.max", ConfigValue{ConfigType::Integer}.defaultValue(2)},
|
||||
{"api_version.default", ConfigValue{ConfigType::Integer}.defaultValue(1)}
|
||||
|
||||
@@ -139,7 +139,7 @@ TEST_F(ResponseTest, asConstBufferJson)
|
||||
TEST_F(ResponseTest, createFromStringAndConnection)
|
||||
{
|
||||
util::TagDecoratorFactory const tagDecoratorFactory{
|
||||
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
ClioConfigDefinition{{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
};
|
||||
StrictMockConnection const connection{"some ip", boost::beast::flat_buffer{}, tagDecoratorFactory};
|
||||
std::string const responseMessage = "response message";
|
||||
@@ -158,7 +158,7 @@ TEST_F(ResponseTest, createFromStringAndConnection)
|
||||
TEST_F(ResponseTest, createFromJsonAndConnection)
|
||||
{
|
||||
util::TagDecoratorFactory const tagDecoratorFactory{
|
||||
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
ClioConfigDefinition{{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
};
|
||||
StrictMockConnection const connection{"some ip", boost::beast::flat_buffer{}, tagDecoratorFactory};
|
||||
boost::json::object const responseMessage{{"key", "value"}};
|
||||
|
||||
@@ -87,7 +87,7 @@ TEST_P(MakeServerTest, Make)
|
||||
{"server.processing_policy", ConfigValue{ConfigType::String}.defaultValue("parallel")},
|
||||
{"server.parallel_requests_limit", ConfigValue{ConfigType::Integer}.optional()},
|
||||
{"server.ws_max_sending_queue_size", ConfigValue{ConfigType::Integer}.defaultValue(1500)},
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"ssl_cert_file", ConfigValue{ConfigType::String}.optional()},
|
||||
{"ssl_key_file", ConfigValue{ConfigType::String}.optional()}
|
||||
|
||||
@@ -174,7 +174,7 @@ protected:
|
||||
{"server.local_admin", ConfigValue{ConfigType::Boolean}.optional()},
|
||||
{"server.parallel_requests_limit", ConfigValue{ConfigType::Integer}.optional()},
|
||||
{"server.ws_max_sending_queue_size", ConfigValue{ConfigType::Integer}.defaultValue(1500)},
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"ssl_key_file", ConfigValue{ConfigType::String}.optional()},
|
||||
{"ssl_cert_file", ConfigValue{ConfigType::String}.optional()}
|
||||
};
|
||||
@@ -201,7 +201,7 @@ TEST_F(ServerTest, BadEndpoint)
|
||||
{
|
||||
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::make_address("1.2.3.4"), 0};
|
||||
util::TagDecoratorFactory const tagDecoratorFactory{
|
||||
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
ClioConfigDefinition{{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
};
|
||||
Server server{
|
||||
ctx_,
|
||||
@@ -262,7 +262,7 @@ TEST_F(ServerHttpTest, OnConnectCheck)
|
||||
auto const serverPort = tests::util::generateFreePort();
|
||||
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::make_address("0.0.0.0"), serverPort};
|
||||
util::TagDecoratorFactory const tagDecoratorFactory{
|
||||
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
ClioConfigDefinition{{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
};
|
||||
|
||||
testing::StrictMock<testing::MockFunction<std::expected<void, Response>(Connection const&)>> onConnectCheck;
|
||||
@@ -322,7 +322,7 @@ TEST_F(ServerHttpTest, OnConnectCheckFailed)
|
||||
auto const serverPort = tests::util::generateFreePort();
|
||||
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::make_address("0.0.0.0"), serverPort};
|
||||
util::TagDecoratorFactory const tagDecoratorFactory{
|
||||
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
ClioConfigDefinition{{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
};
|
||||
|
||||
testing::StrictMock<testing::MockFunction<std::expected<void, Response>(Connection const&)>> onConnectCheck;
|
||||
@@ -381,7 +381,7 @@ TEST_F(ServerHttpTest, OnDisconnectHook)
|
||||
auto const serverPort = tests::util::generateFreePort();
|
||||
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::make_address("0.0.0.0"), serverPort};
|
||||
util::TagDecoratorFactory const tagDecoratorFactory{
|
||||
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
ClioConfigDefinition{{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
|
||||
};
|
||||
|
||||
testing::StrictMock<testing::MockFunction<void(Connection const&)>> onDisconnectHookMock;
|
||||
|
||||
@@ -53,7 +53,7 @@ struct NgSubscriptionContextTests : SyncAsioContextTest {
|
||||
|
||||
protected:
|
||||
util::TagDecoratorFactory tagFactory_{ClioConfigDefinition{
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
}};
|
||||
MockWsConnectionImpl connection_{"some ip", boost::beast::flat_buffer{}, tagFactory_};
|
||||
testing::StrictMock<testing::MockFunction<bool(web::ng::Error const&, Connection const&)>> errorHandler_;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace websocket = boost::beast::websocket;
|
||||
struct ConnectionHandlerTest : prometheus::WithPrometheus, SyncAsioContextTest {
|
||||
ConnectionHandlerTest(ProcessingPolicy policy, std::optional<size_t> maxParallelConnections)
|
||||
: tagFactory{util::config::ClioConfigDefinition{
|
||||
{"log_tag_style", config::ConfigValue{config::ConfigType::String}.defaultValue("uint")}
|
||||
{"log.tag_style", config::ConfigValue{config::ConfigType::String}.defaultValue("uint")}
|
||||
}}
|
||||
, connectionHandler{policy, maxParallelConnections, tagFactory, std::nullopt, onDisconnectMock.AsStdFunction()}
|
||||
{
|
||||
@@ -103,7 +103,7 @@ struct ConnectionHandlerTest : prometheus::WithPrometheus, SyncAsioContextTest {
|
||||
ConnectionHandler connectionHandler;
|
||||
|
||||
util::TagDecoratorFactory tagDecoratorFactory{config::ClioConfigDefinition{
|
||||
{"log_tag_style", config::ConfigValue{config::ConfigType::String}.defaultValue("uint")}
|
||||
{"log.tag_style", config::ConfigValue{config::ConfigType::String}.defaultValue("uint")}
|
||||
}};
|
||||
StrictMockHttpConnectionPtr mockHttpConnection =
|
||||
std::make_unique<StrictMockHttpConnection>("1.2.3.4", beast::flat_buffer{}, tagDecoratorFactory);
|
||||
|
||||
@@ -70,7 +70,7 @@ struct HttpConnectionTests : SyncAsioContextTest {
|
||||
|
||||
protected:
|
||||
util::TagDecoratorFactory tagDecoratorFactory_{
|
||||
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("int")}}
|
||||
ClioConfigDefinition{{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("int")}}
|
||||
};
|
||||
TestHttpServer httpServer_{ctx_, "localhost"};
|
||||
HttpAsyncClient httpClient_{ctx_};
|
||||
|
||||
@@ -85,7 +85,7 @@ struct WebWsConnectionTests : SyncAsioContextTest {
|
||||
|
||||
protected:
|
||||
util::TagDecoratorFactory tagDecoratorFactory_{config::ClioConfigDefinition{
|
||||
{"log_tag_style", config::ConfigValue{config::ConfigType::String}.defaultValue("int")}
|
||||
{"log.tag_style", config::ConfigValue{config::ConfigType::String}.defaultValue("int")}
|
||||
}};
|
||||
TestHttpServer httpServer_{ctx_, "localhost"};
|
||||
WebSocketAsyncClient wsClient_{ctx_};
|
||||
|
||||
Reference in New Issue
Block a user