numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
toml_log_config_parser.h
Go to the documentation of this file.
1/*
2 * Copyright 2022 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <exception>
23#include <filesystem>
24#include <memory>
25#include <string>
26#include <string_view>
27#include <unordered_map>
28#include <utility>
29
30#include <fmt/format.h>
31#include <toml++/toml.h>
32
47
49
50namespace impl {
51
60inline auto require_log_level(const ::toml::table& table, std::string_view path,
61 std::string_view config_name) -> log_level {
62 const auto str =
63 require_value<std::string>(table, path, config_name, "a string");
65}
66
75 const ::toml::table& table, log_sink_factory_table& sinks) {
76 if (table.contains("sink")) {
77 const auto sink_name = require_value<std::string>(table, "sink",
78 "sink in num_collect.logging.tag_configs element", "a string");
79 config.sink(sinks.get(sink_name));
80 }
81
82 if (table.contains("output_log_level")) {
83 const auto level = require_log_level(table, "output_log_level",
84 "output_log_level in num_collect.logging.tag_configs element");
85 config.output_log_level(level);
86 }
87
88 if (table.contains("output_log_level_in_child_iterations")) {
89 const auto level =
90 require_log_level(table, "output_log_level_in_child_iterations",
91 "output_log_level_in_child_iterations in "
92 "num_collect.logging.tag_configs element");
94 }
95
96 if (table.contains("iteration_output_period")) {
97 const auto val =
98 require_value<index_type>(table, "iteration_output_period",
99 "iteration_output_period in num_collect.logging.tag_configs "
100 "element",
101 "an integer");
102 config.iteration_output_period(val);
103 }
104
105 if (table.contains("iteration_label_period")) {
106 const auto val =
107 require_value<index_type>(table, "iteration_label_period",
108 "iteration_label_period in num_collect.logging.tag_configs "
109 "element",
110 "an integer");
111 config.iteration_label_period(val);
112 }
113}
114
115} // namespace impl
116
123public:
129 "console", std::make_shared<toml_console_log_sink_config_parser>());
130 append_log_sink_config_parser("single_file",
131 std::make_shared<toml_single_file_log_sink_config_parser>());
133 std::make_shared<toml_combined_log_sink_config_parser>());
134 }
135
137 void parse_from_file(std::string_view filepath) override {
138 if (!std::filesystem::exists(std::filesystem::path(filepath)) ||
139 !std::filesystem::is_regular_file(
140 std::filesystem::path(filepath))) {
141 throw invalid_argument(fmt::format(
142 "Invalid filepath to load configurations {}.", filepath));
143 }
144 try {
145 const auto parse_result = ::toml::parse_file(filepath);
146 parse_from_table(parse_result);
147 } catch (const std::exception& e) {
148 throw invalid_argument(
149 fmt::format("Failed to load {}: {}", filepath, e.what()));
150 }
151 }
152
154 void parse_from_text(std::string_view text) override {
155 try {
156 const auto parse_result = ::toml::parse(text);
157 parse_from_table(parse_result);
158 } catch (const std::exception& e) {
159 throw invalid_argument(
160 fmt::format("Failed to load from a text: {}\n"
161 "Input:\n"
162 "{}",
163 e.what(), text));
164 }
165 }
166
172 void parse_from_table(const ::toml::table& table) {
174
175 const auto log_sink_configs_node =
176 table.at_path("num_collect.logging.sinks");
177 if (log_sink_configs_node) {
178 const auto* log_sink_configs_array =
179 log_sink_configs_node.as_array();
180 if (log_sink_configs_array == nullptr) {
181 throw invalid_argument(
182 "Configuration num_collect.logging.sinks must be an "
183 "array.");
184 }
185 parse_log_sinks(*log_sink_configs_array, sinks);
186 }
187
188 const auto log_tag_configs_node =
189 table.at_path("num_collect.logging.tag_configs");
190 if (log_tag_configs_node) {
191 const auto* log_tag_configs_array = log_tag_configs_node.as_array();
192 if (log_tag_configs_array == nullptr) {
193 throw invalid_argument(
194 "Configuration num_collect.logging.tag_configs must be an "
195 "array.");
196 }
197 parse_and_apply_log_tag_configs(*log_tag_configs_array, sinks);
198 }
199 }
200
207 void append_log_sink_config_parser(const std::string& name,
208 const std::shared_ptr<toml_log_sink_config_parser_base>& parser) {
209 if (!log_sink_config_parsers_.try_emplace(name, parser).second) {
210 throw invalid_argument(fmt::format(
211 "Duplicate name of parsers of configurations of log sinks {}.",
212 name));
213 }
214 }
215
219 ~toml_log_config_parser() noexcept override = default;
220
223 auto operator=(const toml_log_config_parser&)
224 -> toml_log_config_parser& = delete;
225 auto operator=(toml_log_config_parser&&)
226 -> toml_log_config_parser& = delete;
227
228private:
236 const ::toml::array& array, log_sink_factory_table& sinks) {
237 for (const auto& elem_node : array) {
238 const auto* elem_table = elem_node.as_table();
239 if (elem_table == nullptr) {
240 throw invalid_argument(
241 "Each element in configuration num_collect.logging.sinks "
242 "must be a table.");
243 }
244
245 const auto name = require_value<std::string>(*elem_table, "name",
246 "name in num_collect.logging.sinks element", "a string");
247 const auto type = require_value<std::string>(*elem_table, "type",
248 "type in num_collect.logging.sinks element", "a string");
249
250 const auto parser_iter = log_sink_config_parsers_.find(type);
251 if (parser_iter == log_sink_config_parsers_.end()) {
252 throw invalid_argument(
253 fmt::format("Invalid type of log sink {}.", type));
254 }
255 const auto sink_factory = parser_iter->second->parse(*elem_table);
256
257 sinks.append(name, sink_factory);
258 }
259 }
260
268 const ::toml::array& array, log_sink_factory_table& sinks) {
269 for (const auto& elem_node : array) {
270 const auto* elem_table = elem_node.as_table();
271 if (elem_table == nullptr) {
272 throw invalid_argument(
273 "Each element in configuration "
274 "num_collect.logging.tag_configs "
275 "must be a table.");
276 }
277
278 const auto tag_string = require_value<std::string>(*elem_table,
279 "tag", "tag in num_collect.logging.tag_configs element",
280 "a string");
281 const auto tag = log_tag(tag_string);
282
283 auto config = get_config_of(tag);
284
285 impl::parse_log_tag_config_to(config, *elem_table, sinks);
286
287 set_config_of(tag, config);
288 }
289 }
290
292 std::unordered_map<std::string,
293 std::shared_ptr<toml_log_sink_config_parser_base>>
295};
296
297} // namespace num_collect::logging::config::toml
Class of exception on invalid arguments.
Definition exception.h:85
Interface of parsers of logging configurations.
auto get(const std::string &name) -> sinks::log_sink
Get a log sink creating it if needed.
Class to parse log configuration from a TOML file.
void parse_from_text(std::string_view text) override
Parse configuration from a file.
~toml_log_config_parser() noexcept override=default
Destructor.
static void parse_and_apply_log_tag_configs(const ::toml::array &array, log_sink_factory_table &sinks)
Parse and apply configurations of log tags.
std::unordered_map< std::string, std::shared_ptr< toml_log_sink_config_parser_base > > log_sink_config_parsers_
Parses of configurations of log sinks.
void parse_from_file(std::string_view filepath) override
Parse configuration from a file.
void parse_log_sinks(const ::toml::array &array, log_sink_factory_table &sinks)
Parse configurations of log sinks.
void append_log_sink_config_parser(const std::string &name, const std::shared_ptr< toml_log_sink_config_parser_base > &parser)
Append a parser of configurations of log sinks.
void parse_from_table(const ::toml::table &table)
Parse configuration from a TOML table.
Class to hold configurations for log tags.
auto iteration_output_period() const noexcept -> index_type
Get the period to write iteration logs.
auto sink() const noexcept -> const sinks::log_sink &
Get the log sink.
auto iteration_label_period() const noexcept -> index_type
Get the period to write labels of iteration logs.
auto output_log_level_in_child_iterations() const noexcept -> log_level
Get the minimum log level to output in child iterations.
auto output_log_level() const noexcept -> log_level
Get the minimum log level to output.
Class of tags of logs.
Definition log_tag.h:33
Definition of exceptions.
Definition of index_type type.
Definition of functions to get and set logging configurations.
Definition of log_config_parser_base class.
Definition of log_level enumeration.
Definition of log_sink_factory_table class.
Definition of log_tag class.
Definition of log_tag_config class.
auto require_log_level(const ::toml::table &table, std::string_view path, std::string_view config_name) -> log_level
Get a log level value or throw exception.
void parse_log_tag_config_to(log_tag_config &config, const ::toml::table &table, log_sink_factory_table &sinks)
Parse configurations of logging for a log tag.
Namespace of logging configuration in TOML files.
auto require_value(const ::toml::table &table, std::string_view path, std::string_view config_name, std::string_view type_name) -> T
Get a value or throw exceptions.
Definition toml_helper.h:44
auto parse_output_log_level_str(std::string_view str) -> log_level
Parse a log level from a string to use in output_log_level of log_tag_config class.
NUM_COLLECT_EXPORT void set_config_of(log_tag_view tag, const log_tag_config &config)
Set the configuration of a tag.
log_level
Enumeration of log levels.
Definition log_level.h:47
NUM_COLLECT_EXPORT auto get_config_of(log_tag_view tag) -> log_tag_config
Get the configuration of a tag.
Definition of parse_output_log_level_str function.
Definition of toml_combined_log_sink_config_parser class.
Definition of toml_console_log_sink_config_parser class.
Definition of helper functions for parsing TOML files.
Definition of toml_log_sink_config_parser_base class.
Definition of toml_single_file_log_sink_config_parser class.