diff --git a/elfo-core/Cargo.toml b/elfo-core/Cargo.toml index 331b6cc8..339c5938 100644 --- a/elfo-core/Cargo.toml +++ b/elfo-core/Cargo.toml @@ -60,6 +60,7 @@ humantime-serde = "1" elfo-utils = { version = "0.2.5", path = "../elfo-utils", features = ["test-util"] } tokio = { workspace = true, features = ["full"] } +toml.workspace = true anyhow = "1.0.40" proptest = "1.4.0" diff --git a/elfo-core/src/actor.rs b/elfo-core/src/actor.rs index 087ec0f3..06182af8 100644 --- a/elfo-core/src/actor.rs +++ b/elfo-core/src/actor.rs @@ -10,7 +10,7 @@ use crate::{ envelope::Envelope, errors::{SendError, TrySendError}, group::TerminationPolicy, - mailbox::{Mailbox, MailboxConfig, RecvResult}, + mailbox::{config::MailboxConfig, Mailbox, RecvResult}, messages::{ActorStatusReport, Terminate}, msg, request_table::RequestTable, diff --git a/elfo-core/src/config.rs b/elfo-core/src/config.rs index 929b07d6..580dd460 100644 --- a/elfo-core/src/config.rs +++ b/elfo-core/src/config.rs @@ -1,3 +1,7 @@ +//! Contains useful utilities for working with configuration. +//! +//! Also contains [`system`] to describe system configuration. + use std::{ any::{Any, TypeId}, fmt, mem, @@ -11,6 +15,9 @@ use serde_value::{Value, ValueDeserializer}; use crate::{local::Local, panic}; +/// Represents any user-defined config. +/// +/// It's implemented automatically for any `Deserialize + Send + Sync + Debug`. pub trait Config: for<'de> Deserialize<'de> + Send + Sync + fmt::Debug + 'static {} impl Config for C where C: for<'de> Deserialize<'de> + Send + Sync + fmt::Debug + 'static {} @@ -18,6 +25,24 @@ assert_impl_all!((): Config); // === AnyConfig === +/// Holds user-defined config. +/// +/// Usually not created directly outside tests sending [`ValidateConfig`] or +/// [`UpdateConfig`] messages. +/// +/// [`ValidateConfig`]: crate::messages::ValidateConfig +/// [`UpdateConfig`]: crate::messages::UpdateConfig +/// +/// # Example +/// In tests it can be used in the following way: +/// ``` +/// # use serde::Deserialize; +/// # use toml::toml; +/// # use elfo_core::config::AnyConfig; +/// AnyConfig::deserialize(toml! { +/// some_param = 10 +/// }); +/// ``` #[derive(Clone)] pub struct AnyConfig { raw: Arc, @@ -164,18 +189,73 @@ impl<'de> Deserializer<'de> for AnyConfig { // === SystemConfig === -#[derive(Debug, Default, Deserialize)] -#[serde(default)] -pub(crate) struct SystemConfig { - pub(crate) mailbox: crate::mailbox::MailboxConfig, - pub(crate) logging: crate::logging::LoggingConfig, - pub(crate) dumping: crate::dumping::DumpingConfig, - pub(crate) telemetry: crate::telemetry::TelemetryConfig, - pub(crate) restart_policy: crate::restarting::RestartPolicyConfig, +pub mod system { + //! System (`system.*` in TOML) configuration. [Config]. + //! + //! Note: all types here are exported only for documentation purposes + //! and are not subject to stable guarantees. However, the config + //! structure (usually encoded in TOML) follows stable guarantees. + //! + //! [Config]: SystemConfig + + use super::*; + + pub use crate::{ + dumping::config as dumping, logging::config as logging, mailbox::config as mailbox, + restarting::config as restart_policy, telemetry::config as telemetry, + }; + + /// The `system.*` section in configs. + /// + /// # Example + /// ```toml + /// [some_group] + /// system.mailbox.capacity = 1000 + /// system.logging.max_level = "Warn" + /// system.dumping.max_rate = 10_000 + /// system.telemetry.per_actor_key = true + /// system.restart_policy.when = "Never" + /// ``` + #[derive(Debug, Default, Deserialize)] + #[serde(default)] + pub struct SystemConfig { + /// Mailbox configuration. + pub mailbox: mailbox::MailboxConfig, + /// Logging configuration. + pub logging: logging::LoggingConfig, + /// Dumping configuration. + pub dumping: dumping::DumpingConfig, + /// Telemetry configuration. + pub telemetry: telemetry::TelemetryConfig, + /// Restarting configuration. + pub restart_policy: restart_policy::RestartPolicyConfig, + } } +pub(crate) use system::SystemConfig; + // === Secret === +/// A secret value that is not printed in logs or debug output. +/// So, it's useful for storing sensitive data like credentials. +/// +/// * `Debug` and `Display` instances prints `` instead of real value. +/// * `Deserialize` expects a real value. +/// * `Serialize` depends on the current [serde mode]: +/// * In the `Network` mode it's serialized as the real value. +/// * In the `Dumping` and `Normal` modes it's serialized as `""`. +/// +/// [serde mode]: crate::scope::with_serde_mode +/// +/// # Example +/// ``` +/// # use serde::Deserialize; +/// # use elfo_core::config::Secret; +/// #[derive(Deserialize)] +/// struct MyConfig { +/// credentials: Secret, +/// } +/// ``` #[derive(Clone, Copy, PartialEq, Eq, Default, From)] pub struct Secret(T); diff --git a/elfo-core/src/dumping/config.rs b/elfo-core/src/dumping/config.rs index f8503c41..36c202de 100644 --- a/elfo-core/src/dumping/config.rs +++ b/elfo-core/src/dumping/config.rs @@ -1,10 +1,29 @@ +//! [Config]. +//! +//! [Config]: DumpingConfig + use serde::Deserialize; +/// Dumping configuration. +/// +/// # Example +/// ```toml +/// [some_group] +/// system.dumping.disabled = false +/// system.dumping.max_rate = 1_000 +/// ``` #[derive(Debug, Clone, Deserialize)] #[serde(default)] -pub(crate) struct DumpingConfig { - pub(crate) disabled: bool, - pub(crate) max_rate: u64, +pub struct DumpingConfig { + /// Whether dumping is disabled. + /// + /// `false` by default. + pub disabled: bool, + /// Maximum rate of dumping. + /// Exceeding this rate will cause messages to not be dumped. + /// + /// `100_000` by default. + pub max_rate: u64, // TODO: per class overrides. } diff --git a/elfo-core/src/dumping/mod.rs b/elfo-core/src/dumping/mod.rs index 44adc208..f12aa567 100644 --- a/elfo-core/src/dumping/mod.rs +++ b/elfo-core/src/dumping/mod.rs @@ -24,13 +24,12 @@ pub(crate) use self::{ sequence_no::SequenceNo, }; -pub(crate) use self::config::DumpingConfig; - #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))] #[stability::unstable] pub const INTERNAL_CLASS: &str = "internal"; -mod config; +pub mod config; + mod control; mod dump; mod dumper; diff --git a/elfo-core/src/logging/config.rs b/elfo-core/src/logging/config.rs index 070f0fee..85033e56 100644 --- a/elfo-core/src/logging/config.rs +++ b/elfo-core/src/logging/config.rs @@ -1,12 +1,30 @@ +//! [Config]. +//! +//! [Config]: LoggingConfig + use serde::{Deserialize, Deserializer}; use tracing::level_filters::LevelFilter; +/// Logging configuration. +/// +/// # Example +/// ```toml +/// [some_group] +/// system.logging.max_level = "Warn" +/// system.logging.max_rate_per_level = 1_000 +/// ``` #[derive(Debug, Deserialize)] #[serde(default)] -pub(crate) struct LoggingConfig { +pub struct LoggingConfig { + /// Maximum level of logging. + /// + /// `Info` by default. #[serde(deserialize_with = "deserialize_level_filter")] - pub(crate) max_level: LevelFilter, - pub(crate) max_rate_per_level: u64, + pub max_level: LevelFilter, + /// Maximum rate of logging per level. + /// + /// `1_000` by default. + pub max_rate_per_level: u64, } impl Default for LoggingConfig { diff --git a/elfo-core/src/logging/mod.rs b/elfo-core/src/logging/mod.rs index ebf2eca2..bb30d4b7 100644 --- a/elfo-core/src/logging/mod.rs +++ b/elfo-core/src/logging/mod.rs @@ -1,6 +1,5 @@ -pub(crate) use self::config::LoggingConfig; +pub mod config; -mod config; mod control; // TODO: use `stability` instead. diff --git a/elfo-core/src/mailbox.rs b/elfo-core/src/mailbox.rs index 1a405c01..1c3af409 100644 --- a/elfo-core/src/mailbox.rs +++ b/elfo-core/src/mailbox.rs @@ -44,15 +44,35 @@ use crate::{ // === MailboxConfig === -#[derive(Debug, PartialEq, serde::Deserialize)] -#[serde(default)] -pub(crate) struct MailboxConfig { - pub(crate) capacity: usize, -} +pub mod config { + //! [Config] + //! + //! [Config]: MailboxConfig + + /// Mailbox configuration. + /// + /// # Example + /// ```toml + /// [some_group] + /// system.mailbox.capacity = 1000 + /// ``` + #[derive(Debug, PartialEq, serde::Deserialize)] + #[serde(default)] + pub struct MailboxConfig { + /// The maximum number of messages that can be stored in the mailbox. + /// + /// Can be overriden by actor using [`Context::set_mailbox_capacity()`]. + /// + /// `100` by default. + /// + /// [`Context::set_mailbox_capacity()`]: crate::Context::set_mailbox_capacity + pub capacity: usize, + } -impl Default for MailboxConfig { - fn default() -> Self { - Self { capacity: 100 } + impl Default for MailboxConfig { + fn default() -> Self { + Self { capacity: 100 } + } } } @@ -118,7 +138,7 @@ struct Control { } impl Mailbox { - pub(crate) fn new(config: &MailboxConfig) -> Self { + pub(crate) fn new(config: &config::MailboxConfig) -> Self { let capacity = clamp_capacity(config.capacity); Self { diff --git a/elfo-core/src/restarting/config.rs b/elfo-core/src/restarting/config.rs index bf58a147..60e62163 100644 --- a/elfo-core/src/restarting/config.rs +++ b/elfo-core/src/restarting/config.rs @@ -1,29 +1,69 @@ +//! [Config]. +//! +//! [Config]: RestartPolicyConfig + use std::{num::NonZeroU64, time::Duration}; use serde::Deserialize; use crate::restarting::restart_policy::{RestartParams, RestartPolicy}; +/// Restart policy configuration, `Never` by default. +/// +/// Overrides [`ActorGroup::restart_policy()`]. +/// Can be overriden by actor using [`Context::set_restart_policy()`]. +/// +/// See [The Actoromicon] for details. +/// +/// # Example +/// ```toml +/// [some_group] +/// system.restart_policy.when = "OnFailure" +/// system.restart_policy.min_backoff = "5s" +/// system.restart_policy.max_backoff = "30s" +/// ``` +/// +/// [`ActorGroup::restart_policy()`]: crate::ActorGroup::restart_policy +/// [`Context::set_restart_policy()`]: crate::Context::set_restart_policy +/// [The Actoromicon]: https://actoromicon.rs/ch04-02-supervision.html#restart #[derive(Debug, Clone, Default, Deserialize)] -pub(crate) struct RestartPolicyConfig(Option); +pub struct RestartPolicyConfig(pub Option); +/// Restart policies. #[derive(Debug, Clone, Deserialize)] #[serde(tag = "when")] -enum WhenConfig { +pub enum WhenConfig { + /// Restart both on failures and terminations. Always(RestartParamsConfig), + /// Restart only on failures. OnFailure(RestartParamsConfig), + /// Never restart actors. Never, } +/// Restart policy parameters. #[derive(Debug, Clone, Deserialize)] -struct RestartParamsConfig { +pub struct RestartParamsConfig { + /// Minimal restart time limit. #[serde(with = "humantime_serde")] min_backoff: Duration, + /// Maximum restart time limit. #[serde(with = "humantime_serde")] max_backoff: Duration, + /// The duration of an actor's lifecycle sufficient to deem the actor + /// healthy. + /// + /// The default value is `min_backoff`. #[serde(with = "humantime_serde", default)] auto_reset: Option, + /// The limit on retry attempts, after which the actor stops attempts to + /// restart. + /// + /// Unlimited by default. max_retries: Option, + /// The value to multiply the current delay with for each retry attempt. + /// + /// Default value is 2.0. factor: Option, } diff --git a/elfo-core/src/restarting/mod.rs b/elfo-core/src/restarting/mod.rs index 0e38d8d6..67e66e92 100644 --- a/elfo-core/src/restarting/mod.rs +++ b/elfo-core/src/restarting/mod.rs @@ -1,6 +1,7 @@ +pub mod config; + mod backoff; -mod config; mod restart_policy; -pub(crate) use self::{backoff::RestartBackoff, config::RestartPolicyConfig}; +pub(crate) use self::backoff::RestartBackoff; pub use restart_policy::{RestartParams, RestartPolicy}; diff --git a/elfo-core/src/scope.rs b/elfo-core/src/scope.rs index 012b582c..67c6c19b 100644 --- a/elfo-core/src/scope.rs +++ b/elfo-core/src/scope.rs @@ -15,7 +15,7 @@ use crate::{ dumping::DumpingControl, logging::_priv::LoggingControl, permissions::{AtomicPermissions, Permissions}, - telemetry::TelemetryConfig, + telemetry::config::TelemetryConfig, tracing::TraceId, Addr, }; diff --git a/elfo-core/src/telemetry/config.rs b/elfo-core/src/telemetry/config.rs index 5780f11c..762dd989 100644 --- a/elfo-core/src/telemetry/config.rs +++ b/elfo-core/src/telemetry/config.rs @@ -1,3 +1,7 @@ +//! [Config]. +//! +//! [Config]: TelemetryConfig + use std::fmt; use regex::Regex; @@ -6,15 +10,41 @@ use serde::{ Deserialize, }; +/// Telemetry configuration. +/// +/// # Example +/// ```toml +/// [some_group] +/// system.telemetry.per_actor_group = false +/// system.teleemtry.per_actor_key = true +/// ``` #[derive(Debug, Deserialize)] #[serde(default)] -pub(crate) struct TelemetryConfig { - pub(crate) per_actor_group: bool, - pub(crate) per_actor_key: PerActorKey, +pub struct TelemetryConfig { + /// Whether to enable per-actor-group telemetry. + /// + /// `true` by default. + pub per_actor_group: bool, + /// Whether to enable per-actor-key telemetry. + /// + /// Can be either `true` to produce metrics for all keys + /// or regex pattern to combine keys into "groups". + /// + /// `false` by default. + /// + /// # Example + /// ```toml + /// per_actor_key = true # emit metrics keywise + /// per_actor_key = [".*:(.*?)", "${1}"] # group keys + /// ``` + pub per_actor_key: PerActorKey, } -pub(crate) enum PerActorKey { +/// How to produce metrics for actor keys. +pub enum PerActorKey { + /// Produce metrics for all keys. Bool(bool), + /// Combine keys into "groups" by pattern. Replacement(Regex, String), } diff --git a/elfo-core/src/telemetry/mod.rs b/elfo-core/src/telemetry/mod.rs index be14029f..ef68c369 100644 --- a/elfo-core/src/telemetry/mod.rs +++ b/elfo-core/src/telemetry/mod.rs @@ -1,3 +1 @@ -pub(crate) use config::TelemetryConfig; - -mod config; +pub mod config; diff --git a/elfo-dumper/src/config.rs b/elfo-dumper/src/config.rs index 31e66775..f52e0f55 100644 --- a/elfo-dumper/src/config.rs +++ b/elfo-dumper/src/config.rs @@ -1,10 +1,10 @@ //! Configuration for the dumper. //! -//! All types are exported only for documentation purposes, they cannot be -//! created or received outside the dumper. +//! Note: all types here are exported only for documentation purposes +//! and are not subject to stable guarantees. However, the config +//! structure (usually encoded in TOML) follows stable guarantees. //! //! The main structure here is [`Config`]. -#![allow(unreachable_pub)] // docsrs use std::time::Duration; use bytesize::ByteSize; @@ -12,9 +12,6 @@ use serde::Deserialize; /// The dumper's config. /// -/// It's exported only for documentation purposes and cannot be created or -/// received outside the dumper. -/// /// # Examples /// Only `path` is required. Thus, a minimal config looks like /// ```toml diff --git a/elfo-dumper/src/lib.rs b/elfo-dumper/src/lib.rs index 3e937e32..96dadf38 100644 --- a/elfo-dumper/src/lib.rs +++ b/elfo-dumper/src/lib.rs @@ -1,10 +1,11 @@ -//! The dumper writes dumps of messages to files. +//! Writes dumps of messages to files. [Configuration]. //! //! Each line is a valid JSON. Lines can be unordered. //! -//! For more details about dumping see [The Actoromicon](https://actoromicon.rs/ch05-03-dumping.html). +//! For more details about dumping see [The Actoromicon]. //! -//! Configuration can be found in [`config::Config`]. +//! [Configuration]: crate::config::Config +//! [The Actoromicon]: https://actoromicon.rs/ch05-03-dumping.html use std::sync::Arc; @@ -26,9 +27,6 @@ mod reporter; mod rule_set; mod serializer; -#[cfg(not(docsrs))] -mod config; -#[cfg(docsrs)] pub mod config; /// Installs a global dump recorder and returns a group to handle dumps. diff --git a/elfo-logger/src/config.rs b/elfo-logger/src/config.rs index 66b8f485..17a66932 100644 --- a/elfo-logger/src/config.rs +++ b/elfo-logger/src/config.rs @@ -1,6 +1,8 @@ //! Configuration for the logger. - -#![allow(unreachable_pub)] // docsrs +//! +//! Note: all types here are exported only for documentation purposes +//! and are not subject to stable guarantees. However, the config +//! structure (usually encoded in TOML) follows stable guarantees. use std::path::PathBuf; @@ -11,6 +13,9 @@ use tracing::metadata::LevelFilter; use bytesize::ByteSize; /// Logger configuration. +/// +/// It's exported only for documentation purposes and cannot be created or +/// received outside the dumper. #[derive(Debug, Deserialize)] pub struct Config { /// Sink for the log output. diff --git a/elfo-logger/src/lib.rs b/elfo-logger/src/lib.rs index 5f15cfee..90373712 100644 --- a/elfo-logger/src/lib.rs +++ b/elfo-logger/src/lib.rs @@ -1,4 +1,6 @@ -//! Registers `tracing` subscriber and logs events. +//! Registers `tracing` subscriber and logs events. [Configuration]. +//! +//! [Configuration]: config::Config #[macro_use] extern crate elfo_utils; @@ -21,9 +23,6 @@ use crate::{actor::Logger, filtering_layer::FilteringLayer, printing_layer::Prin pub use crate::actor::ReopenLogFile; -#[cfg(not(docsrs))] -mod config; -#[cfg(docsrs)] pub mod config; mod actor; diff --git a/elfo-network/src/config.rs b/elfo-network/src/config.rs index cbac8f79..b8885a54 100644 --- a/elfo-network/src/config.rs +++ b/elfo-network/src/config.rs @@ -1,3 +1,9 @@ +//! Configuration for the network actors. +//! +//! Note: all types here are exported only for documentation purposes +//! and are not subject to stable guarantees. However, the config +//! structure (usually encoded in TOML) follows stable guarantees. + #[cfg(unix)] use std::path::PathBuf; use std::{str::FromStr, time::Duration}; @@ -9,26 +15,47 @@ use serde::{ Deserialize, Serialize, }; +/// The network actors' config. +/// +/// # Examples +/// ```toml +/// [system.network] +/// listen = ["tcp://0.0.0.1:8150"] +/// discovery.predefined = [ +/// "tcp://localhost:4242", +/// "uds:///tmp/sock" +/// ] +/// ``` #[derive(Debug, Deserialize)] -pub(crate) struct Config { - pub(crate) listen: Vec, +pub struct Config { + /// A list of addresses to listen on. + pub listen: Vec, + /// How often nodes should ping each other. + /// `5s` by default #[serde(with = "humantime_serde", default = "default_ping_interval")] - pub(crate) ping_interval: Duration, + pub ping_interval: Duration, + /// How to discover other nodes. #[serde(default)] - pub(crate) discovery: DiscoveryConfig, // TODO: optional? + pub discovery: DiscoveryConfig, // TODO: optional? + /// Compression settings. #[serde(default)] - pub(crate) compression: CompressionConfig, + pub compression: CompressionConfig, } +/// Compression settings. #[derive(Debug, Default, Deserialize)] -pub(crate) struct CompressionConfig { +pub struct CompressionConfig { + /// Compression algorithm. #[serde(default)] - pub(crate) algorithm: CompressionAlgorithm, + pub algorithm: CompressionAlgorithm, } +/// Compression algorithms. #[derive(Debug, Default, PartialEq, Eq, Deserialize)] -pub(crate) enum CompressionAlgorithm { +pub enum CompressionAlgorithm { + /// LZ4 with default compression level. Lz4, + /// Compression disabled. #[default] None, } @@ -37,21 +64,29 @@ fn default_ping_interval() -> Duration { Duration::from_secs(5) } +/// How to discover other nodes. #[derive(Debug, Deserialize, Default)] -pub(crate) struct DiscoveryConfig { - pub(crate) predefined: Vec, +pub struct DiscoveryConfig { + /// Predefined list of transports to connect to. + pub predefined: Vec, + /// How often to attempt to connect to other nodes. #[serde(with = "humantime_serde", default = "default_attempt_interval")] - pub(crate) attempt_interval: Duration, + pub attempt_interval: Duration, } fn default_attempt_interval() -> Duration { Duration::from_secs(10) } +/// Transport used for communication between nodes. #[derive(Debug, Clone, Hash, PartialEq, Eq, Display, Serialize)] -pub(crate) enum Transport { +pub enum Transport { + /// TCP transport ("tcp://host:port"). #[display(fmt = "tcp://{}", _0)] Tcp(String), + /// Unix domain socket transport ("uds://path/to/socket"). + /// + /// Used only on UNIX systems, ignored on other platforms. #[cfg(unix)] #[display(fmt = "uds://{}", "_0.display()")] Uds(PathBuf), diff --git a/elfo-network/src/lib.rs b/elfo-network/src/lib.rs index f9c22eaf..e7e5129a 100644 --- a/elfo-network/src/lib.rs +++ b/elfo-network/src/lib.rs @@ -1,4 +1,7 @@ //! Implements the network layer of the distributed elfo system. +//! [Configuration]. +//! +//! [Configuration]: config::Config #[macro_use] extern crate static_assertions; @@ -22,8 +25,9 @@ use crate::{ protocol::{DataConnectionFailed, GroupInfo, HandleConnection}, }; +pub mod config; + mod codec; -mod config; mod discovery; mod frame; mod node_map; diff --git a/elfo-pinger/src/config.rs b/elfo-pinger/src/config.rs index 1014974a..7171a139 100644 --- a/elfo-pinger/src/config.rs +++ b/elfo-pinger/src/config.rs @@ -1,13 +1,32 @@ +//! Configuration for the pinger. +//! +//! Note: all types here are exported only for documentation purposes +//! and are not subject to stable guarantees. However, the config +//! structure (usually encoded in TOML) follows stable guarantees. + use std::time::Duration; use serde::Deserialize; +/// The pinger's config. +/// +/// # Example +/// ```toml +/// [system.pingers] +/// ping_interval = "30s" +/// ``` #[derive(Debug, Deserialize)] -pub(crate) struct Config { +pub struct Config { + /// How often pingers should ping all other actors. + /// + /// `10s` by default. #[serde(with = "humantime_serde", default = "default_ping_interval")] - pub(crate) ping_interval: Duration, + pub ping_interval: Duration, + /// How long to wait for a response before logging a warning. + /// + /// `5s` by default. #[serde(with = "humantime_serde", default = "default_warn_threshold")] - pub(crate) warn_threshold: Duration, + pub warn_threshold: Duration, } fn default_ping_interval() -> Duration { diff --git a/elfo-pinger/src/lib.rs b/elfo-pinger/src/lib.rs index 7f2e59c5..4d578a6e 100644 --- a/elfo-pinger/src/lib.rs +++ b/elfo-pinger/src/lib.rs @@ -1,11 +1,15 @@ //! Periodically pings all actors in the topology to check if they are alive. +//! [Configuration]. +//! +//! [Configuration]: config::Config use std::time::Duration; use elfo_core::{ActorGroup, Blueprint, RestartParams, RestartPolicy, Topology}; +pub mod config; + mod actor; -mod config; /// Creates a blueprint. /// diff --git a/elfo-telemeter/src/config.rs b/elfo-telemeter/src/config.rs index 54c6ae02..ead901f5 100644 --- a/elfo-telemeter/src/config.rs +++ b/elfo-telemeter/src/config.rs @@ -1,37 +1,60 @@ +//! Configuration for the telemeter. +//! +//! Note: all types here are exported only for documentation purposes +//! and are not subject to stable guarantees. However, the config +//! structure (usually encoded in TOML) follows stable guarantees. + use std::{net::SocketAddr, ops::Deref, time::Duration}; use serde::Deserialize; +/// Telemeter configuration. +/// +/// # Example +/// ```toml +/// [system.telemeters] +/// sink = "OpenMetrics" +/// listen = "0.0.0.0:9042" +/// ``` #[derive(Debug, Deserialize)] -pub(crate) struct Config { +pub struct Config { /// The sink's type. - pub(crate) sink: Sink, + pub sink: Sink, /// The address to expose for scraping. #[serde(alias = "address")] - pub(crate) listen: SocketAddr, + pub listen: SocketAddr, /// How long samples should be considered in summaries. #[serde(default)] - pub(crate) retention: Retention, + pub retention: Retention, /// Quantiles to use for aggregating distribution metrics into a summary. + /// + /// The default quantiles are `[0.75, 0.9, 0.95, 0.99]`. #[serde(default = "default_quantiles")] - pub(crate) quantiles: Vec, + pub quantiles: Vec, /// Labels that will be added to all metrics. #[serde(default)] - pub(crate) global_labels: Vec<(String, String)>, + pub global_labels: Vec<(String, String)>, /// The maximum time between compaction ticks. + /// + /// `1.1s` by default. #[serde(with = "humantime_serde", default = "default_compaction_interval")] - pub(crate) compaction_interval: Duration, + pub compaction_interval: Duration, } +/// Sink for the telemeter output. #[derive(Debug, PartialEq, Deserialize)] -pub(crate) enum Sink { +pub enum Sink { + /// Expose metrics in the OpenMetrics/Prometheus format. #[serde(alias = "Prometheus")] OpenMetrics, } +/// Histogram/summary retention policy. #[derive(Debug, PartialEq, Deserialize)] -pub(crate) enum Retention { +pub enum Retention { + /// Keep all samples forever. Forever, + /// Reset all samples on each scrape. ResetOnScrape, // TODO: `SlidingWindow` } @@ -42,9 +65,11 @@ impl Default for Retention { } } +/// A quantile to use for aggregating distribution metrics into a summary +/// with the `quantile` label. Must be in the range [0.0, 1.0]. #[derive(Debug, Clone, Copy, Deserialize)] #[serde(try_from = "f64")] -pub(crate) struct Quantile(f64); +pub struct Quantile(f64); impl Deref for Quantile { type Target = f64; diff --git a/elfo-telemeter/src/lib.rs b/elfo-telemeter/src/lib.rs index bb19a4cc..64e2c1aa 100644 --- a/elfo-telemeter/src/lib.rs +++ b/elfo-telemeter/src/lib.rs @@ -1,4 +1,5 @@ -//! Interaction with the `metrics` crate. +//! Interaction with the `metrics` crate. [Configuration]. +//! //! Records metrics in the OpenMetrics exposition format. //! //! Note that push gateways aren't supported, histogram buckets overrides @@ -8,6 +9,8 @@ //! Such information is added as labels. By default, only the `actor_group` //! label is added, but it's possible to provide `actor_key` on a group basis. //! It's useful, if a group has few actors inside. +//! +//! [Configuration]: config::Config use std::sync::Arc; @@ -17,10 +20,10 @@ use elfo_core::Blueprint; use self::{recorder::Recorder, storage::Storage}; +pub mod config; pub mod protocol; mod actor; -mod config; mod hyper; mod metrics; mod recorder; diff --git a/elfo/src/lib.rs b/elfo/src/lib.rs index 276cd25e..525226de 100644 --- a/elfo/src/lib.rs +++ b/elfo/src/lib.rs @@ -9,27 +9,34 @@ pub use elfo_macros::{message, msg}; #[cfg(feature = "test-util")] #[cfg_attr(docsrs, doc(cfg(feature = "test-util")))] +#[doc(inline)] pub use elfo_test as test; /// A set of actors for common tasks. pub mod batteries { #[cfg(feature = "elfo-configurer")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + #[doc(inline)] pub use elfo_configurer as configurer; #[cfg(feature = "elfo-dumper")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + #[doc(inline)] pub use elfo_dumper as dumper; #[cfg(feature = "elfo-logger")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + #[doc(inline)] pub use elfo_logger as logger; #[cfg(feature = "elfo-network")] // TODO #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + #[doc(inline)] pub use elfo_network as network; #[cfg(feature = "elfo-pinger")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + #[doc(inline)] pub use elfo_pinger as pinger; #[cfg(feature = "elfo-telemeter")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + #[doc(inline)] pub use elfo_telemeter as telemeter; }