22#include "util/Assert.hpp"
23#include "util/newconfig/ConfigDefinition.hpp"
24#include "util/newconfig/Error.hpp"
38namespace util::config {
50 std::string_view value;
66 [[nodiscard]]
static constexpr std::string_view
67 get(std::string_view key)
69 auto const itr = std::ranges::find_if(kCONFIG_DESCRIPTION, [&](
auto const& v) {
return v.key == key; });
70 ASSERT(itr != kCONFIG_DESCRIPTION.end(),
"Key {} doesn't exist in config", key);
80 [[nodiscard]]
static std::expected<void, Error>
83 namespace fs = std::filesystem;
86 auto const dir = path.parent_path();
87 if (!dir.empty() && !fs::exists(dir)) {
88 return std::unexpected<Error>{
89 fmt::format(
"Error: Directory '{}' does not exist or provided path is invalid", dir.string())
93 std::ofstream file(path.string());
94 if (!file.is_open()) {
95 return std::unexpected{fmt::format(
"Failed to create file '{}': {}", path.string(), std::strerror(errno))};
101 std::cout <<
"Markdown file generated successfully: " << path <<
"\n";
113 file <<
"# Clio Config Description\n\n";
114 file <<
"This document provides a list of all available Clio configuration properties in detail.\n\n";
115 file <<
"> [!NOTE]\n";
116 file <<
"> Dot notation in configuration key names represents nested fields. For example, "
117 "**database.scylladb** refers to the _scylladb_ field inside the _database_ object. If a key name "
118 "includes \"[]\", it indicates that the nested field is an array (e.g., etl_sources.[]).\n\n";
119 file <<
"## Configuration Details\n";
121 for (
auto const& [key, val] : kCONFIG_DESCRIPTION) {
122 file <<
"\n### " << key <<
"\n\n";
126 if (key.contains(
"[]")) {
127 file << gClioConfig.asArray(key);
129 file << gClioConfig.getValueView(key);
131 file <<
"- **Description**: " << val <<
"\n";
136 static constexpr auto kCONFIG_DESCRIPTION = std::array{
137 KV{.key =
"database.type",
139 "Specifies the type of database used for storing and retrieving data required by the Clio server. Both "
140 "ScyllaDB and Cassandra can serve as backends for Clio; however, this value must be set to `cassandra`."
142 KV{.key =
"database.cassandra.contact_points",
143 .value =
"A list of IP addresses or hostnames for the initial cluster nodes (Cassandra or ScyllaDB) that "
144 "the client connects to when establishing a database connection. If you're running Clio locally, "
145 "set this value to `localhost` or `127.0.0.1`."},
146 KV{.key =
"database.cassandra.secure_connect_bundle",
147 .value =
"The configuration file that contains the necessary credentials and connection details for "
148 "securely connecting to a Cassandra database cluster."},
149 KV{.key =
"database.cassandra.port", .value =
"The port number used to connect to the Cassandra database."},
150 KV{.key =
"database.cassandra.keyspace",
151 .value =
"The Cassandra keyspace to use for the database. If you don't provide a value, this is set to "
152 "`clio` by default."},
153 KV{.key =
"database.cassandra.replication_factor",
154 .value =
"Represents the number of replicated nodes for ScyllaDB. For more details see [Fault Tolerance "
156 "Factor](https://university.scylladb.com/courses/scylla-essentials-overview/lessons/"
157 "high-availability/topic/fault-tolerance-replication-factor/)."},
158 KV{.key =
"database.cassandra.table_prefix",
159 .value =
"An optional field to specify a prefix for the Cassandra database table names."},
160 KV{.key =
"database.cassandra.max_write_requests_outstanding",
161 .value =
"Represents the maximum number of outstanding write requests. Write requests are API calls that "
162 "write to the database."},
163 KV{.key =
"database.cassandra.max_read_requests_outstanding",
165 "Maximum number of outstanding read requests. Read requests are API calls that read from the database."},
166 KV{.key =
"database.cassandra.threads",
167 .value =
"Represents the number of threads that will be used for database operations."},
168 KV{.key =
"database.cassandra.core_connections_per_host",
169 .value =
"The number of core connections per host for the Cassandra database."},
170 KV{.key =
"database.cassandra.queue_size_io",
171 .value =
"Defines the queue size of the input/output (I/O) operations in Cassandra."},
172 KV{.key =
"database.cassandra.write_batch_size",
173 .value =
"Represents the batch size for write operations in Cassandra."},
174 KV{.key =
"database.cassandra.connect_timeout",
175 .value =
"The maximum amount of time in seconds that the system waits for a database connection to be "
177 KV{.key =
"database.cassandra.request_timeout",
178 .value =
"The maximum amount of time in seconds that the system waits for a request to be fetched from the "
180 KV{.key =
"database.cassandra.username", .value =
"The username used for authenticating with the database."},
181 KV{.key =
"database.cassandra.password", .value =
"The password used for authenticating with the database."},
182 KV{.key =
"database.cassandra.certfile",
183 .value =
"The path to the SSL/TLS certificate file used to establish a secure connection between the client "
184 "and the Cassandra database."},
185 KV{.key =
"allow_no_etl", .value =
"If set to `True`, allows Clio to start without any ETL source."},
186 KV{.key =
"etl_sources.[].ip", .value =
"The IP address of the ETL source."},
187 KV{.key =
"etl_sources.[].ws_port", .value =
"The WebSocket port of the ETL source."},
188 KV{.key =
"etl_sources.[].grpc_port", .value =
"The gRPC port of the ETL source."},
189 KV{.key =
"forwarding.cache_timeout",
190 .value =
"Specifies the timeout duration (in seconds) for the forwarding cache used in `rippled` "
191 "communication. A value of `0` means disabling this feature."},
192 KV{.key =
"forwarding.request_timeout",
194 "Specifies the timeout duration (in seconds) for the forwarding request used in `rippled` communication."
196 KV{.key =
"rpc.cache_timeout",
197 .value =
"Specifies the timeout duration (in seconds) for RPC cache response to timeout. A value of `0` "
198 "means disabling this feature."},
199 KV{.key =
"num_markers", .value =
"Specifies the number of coroutines used to download the initial ledger."},
200 KV{.key =
"dos_guard.whitelist.[]", .value =
"The list of IP addresses to whitelist for DOS protection."},
201 KV{.key =
"dos_guard.max_fetches", .value =
"The maximum number of fetch operations allowed by DOS guard."},
202 KV{.key =
"dos_guard.max_connections",
203 .value =
"The maximum number of concurrent connections for a specific IP address."},
204 KV{.key =
"dos_guard.max_requests", .value =
"The maximum number of requests allowed for a specific IP address."
206 KV{.key =
"dos_guard.sweep_interval", .value =
"Interval in seconds for DOS guard to sweep(clear) its state."},
207 KV{.key =
"workers", .value =
"The number of threads used to process RPC requests."},
208 KV{.key =
"server.ip", .value =
"The IP address of the Clio HTTP server."},
209 KV{.key =
"server.port", .value =
"The port number of the Clio HTTP server."},
210 KV{.key =
"server.max_queue_size",
212 "The maximum size of the server's request queue. If set to `0`, this means there is no queue size limit."
214 KV{.key =
"server.local_admin",
215 .value =
"Indicates if requests from `localhost` are allowed to call Clio admin-only APIs. Note that this "
216 "setting cannot be enabled "
217 "together with [server.admin_password](#serveradmin_password)."},
218 KV{.key =
"server.admin_password",
219 .value =
"The password for Clio admin-only APIs. Note that this setting cannot be enabled together with "
220 "[server.local_admin](#serveradmin_password)."},
221 KV{.key =
"server.processing_policy",
222 .value =
"For the `sequent` policy, requests from a single client connection are processed one by one, with "
223 "the next request read only after the previous one is processed. For the `parallel` policy, Clio "
224 "will accept all requests and process them in parallel, sending a reply for each request as soon "
226 KV{.key =
"server.parallel_requests_limit",
227 .value =
"This is an optional parameter, used only if the `processing_strategy` is `parallel`. It limits "
228 "the number of requests processed in parallel for a single client connection. If not specified, no "
229 "limit is enforced."},
230 KV{.key =
"server.ws_max_sending_queue_size",
231 .value =
"Maximum queue size for sending subscription data to clients. This queue buffers data when a "
232 "client is slow to receive it, ensuring delivery once the client is ready."},
233 KV{.key =
"prometheus.enabled", .value =
"Enables or disables Prometheus metrics."},
234 KV{.key =
"prometheus.compress_reply", .value =
"Enables or disables compression of Prometheus responses."},
235 KV{.key =
"io_threads", .value =
"The number of input/output (I/O) threads. The value cannot be less than `1`."
237 KV{.key =
"subscription_workers",
238 .value =
"The number of worker threads or processes that are responsible for managing and processing "
239 "subscription-based tasks from `rippled`."},
240 KV{.key =
"graceful_period",
241 .value =
"The number of milliseconds the server waits to shutdown gracefully. If Clio does not shutdown "
242 "gracefully after the specified value, it will be killed instead."},
243 KV{.key =
"cache.num_diffs",
244 .value =
"The number of cursors generated is the number of changed (without counting deleted) objects in "
245 "the latest `cache.num_diffs` number of ledgers. Cursors are workers that load the ledger cache "
246 "from the position of markers concurrently. For more information, please read "
247 "[README.md](../src/etl/README.md)."},
248 KV{.key =
"cache.num_markers",
249 .value =
" Specifies how many markers are placed randomly within the cache. These markers define the "
250 "positions on the ledger that will be loaded concurrently by the workers. The higher the number, "
251 "the more places within the cache we potentially cover."},
252 KV{.key =
"cache.num_cursors_from_diff",
253 .value =
"`cache.num_cursors_from_diff` number of cursors are generated by looking at the number of changed "
254 "objects in the most recent ledger. If number of changed objects in current ledger is not enough, "
255 "it will keep reading previous ledgers until it hit `cache.num_cursors_from_diff`. If set to `0`, "
256 "the system defaults to generating cursors based on `cache.num_diffs`."},
257 KV{.key =
"cache.num_cursors_from_account",
258 .value =
"`cache.num_cursors_from_diff` of cursors are generated by reading accounts in `account_tx` table. "
259 "If set to `0`, the system defaults to generating cursors based on `cache.num_diffs`."},
260 KV{.key =
"cache.page_fetch_size", .value =
"The number of ledger objects to fetch concurrently per marker."},
261 KV{.key =
"cache.load", .value =
"The strategy used for Cache loading."},
262 KV{.key =
"log_channels.[].channel", .value =
"The name of the log channel."},
263 KV{.key =
"log_channels.[].log_level", .value =
"The log level for the specific log channel."},
264 KV{.key =
"log_level",
265 .value =
"The general logging level of Clio. This level is applied to all log channels that do not have an "
266 "explicitly defined logging level."},
267 KV{.key =
"log_format",
268 .value =
"The format string for log messages. The format is described here: "
269 "https://www.boost.org/doc/libs/1_83_0/libs/log/doc/html/log/tutorial/formatters.html."},
270 KV{.key =
"log_to_console", .value =
"Enables or disables logging to the console."},
271 KV{.key =
"log_directory", .value =
"The directory path for the log files."},
272 KV{.key =
"log_rotation_size",
273 .value =
"The log rotation size in megabytes. When the log file reaches this particular size, a new log "
275 KV{.key =
"log_directory_max_size", .value =
"The maximum size of the log directory in megabytes."},
276 KV{.key =
"log_rotation_hour_interval",
277 .value =
"Represents the interval (in hours) for log rotation. If the current log file reaches this value "
278 "in logging, a new log file starts."},
279 KV{.key =
"log_tag_style",
281 "Log tags are unique identifiers for log messages. `uint`/`int` starts logging from 0 and increments, "
282 "making it faster. In contrast, `uuid` generates a random unique identifier, which adds overhead."},
283 KV{.key =
"extractor_threads", .value =
"Number of threads used to extract data from ETL source."},
284 KV{.key =
"read_only", .value =
"Indicates if the server is allowed to write data to the database."},
285 KV{.key =
"start_sequence",
286 .value =
"If specified, the ledger index Clio will start writing to the database from."},
287 KV{.key =
"finish_sequence", .value =
"If specified, the final ledger that Clio will write to the database."},
288 KV{.key =
"ssl_cert_file", .value =
"The path to the SSL certificate file."},
289 KV{.key =
"ssl_key_file", .value =
"The path to the SSL key file."},
290 KV{.key =
"api_version.default", .value =
"The default API version that the Clio server will run on."},
291 KV{.key =
"api_version.min", .value =
"The minimum API version allowed to use."},
292 KV{.key =
"api_version.max", .value =
"The maximum API version allowed to use."},
293 KV{.key =
"migration.full_scan_threads", .value =
"The number of threads used to scan the table."},
294 KV{.key =
"migration.full_scan_jobs", .value =
"The number of coroutines used to scan the table."},
295 KV{.key =
"migration.cursors_per_job", .value =
"The number of cursors each job will scan."}
Struct to represent a key-value pair.
Definition ConfigDescription.hpp:48
All the config description are stored and extracted from this class.
Definition ConfigDescription.hpp:45
static std::expected< void, Error > generateConfigDescriptionToFile(std::filesystem::path path)
Generate markdown file of all the clio config descriptions.
Definition ConfigDescription.hpp:81
static constexpr std::string_view get(std::string_view key)
Retrieves the description for a given key.
Definition ConfigDescription.hpp:67
static void writeConfigDescriptionToFile(std::ostream &file)
Writes to Config description to file.
Definition ConfigDescription.hpp:111
constexpr ClioConfigDescription()=default
Constructs a new Clio Config Description based on pre-existing descriptions.