1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Prometheus metrics export configuration (`[metrics]` TOML section).
//!
//! Controls whether the agent exposes a `/metrics` endpoint on the gateway HTTP server
//! and how frequently the internal `MetricsSnapshot` is synchronised to Prometheus counters
//! and gauges.
//!
//! # Example (TOML)
//!
//! ```toml
//! [metrics]
//! enabled = true
//! path = "/metrics"
//! sync_interval_secs = 5
//! ```
use serde::{Deserialize, Serialize};
fn default_metrics_path() -> String {
"/metrics".into()
}
fn default_sync_interval_secs() -> u64 {
5
}
/// Prometheus metrics export configuration.
///
/// When `enabled = true` and the binary is compiled with `--features prometheus`, the gateway
/// HTTP server mounts a `/metrics` (or configured `path`) route that returns `OpenMetrics` 1.0.0
/// text suitable for scraping by Prometheus.
///
/// Requires `[gateway] enabled = true`; if the gateway is disabled, metrics export is skipped
/// with a warning.
///
/// # Example (TOML)
///
/// ```toml
/// [metrics]
/// enabled = true
/// path = "/metrics"
/// sync_interval_secs = 5
/// ```
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct MetricsConfig {
/// Whether Prometheus metrics export is active.
///
/// When `false` (the default), no sync task is started and the `/metrics` route is not
/// mounted even if the `prometheus` feature is compiled in.
#[serde(default)]
pub enabled: bool,
/// HTTP path on which the `/metrics` endpoint is mounted.
///
/// Must begin with `/`. Defaults to `"/metrics"`.
#[serde(default = "default_metrics_path")]
pub path: String,
/// How often (in seconds) the `MetricsSnapshot` watch channel is read and synced to the
/// Prometheus registry.
///
/// Zero is clamped to `1` at runtime. Defaults to `5`.
#[serde(default = "default_sync_interval_secs")]
pub sync_interval_secs: u64,
}
impl Default for MetricsConfig {
fn default() -> Self {
Self {
enabled: false,
path: default_metrics_path(),
sync_interval_secs: default_sync_interval_secs(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_metrics_config_defaults() {
let config: MetricsConfig = toml::from_str("").unwrap();
assert!(!config.enabled);
assert_eq!(config.path, "/metrics");
assert_eq!(config.sync_interval_secs, 5);
}
#[test]
fn test_metrics_config_serde() {
let src = r#"
enabled = true
path = "/custom/metrics"
sync_interval_secs = 10
"#;
let config: MetricsConfig = toml::from_str(src).unwrap();
assert!(config.enabled);
assert_eq!(config.path, "/custom/metrics");
assert_eq!(config.sync_interval_secs, 10);
let serialized = toml::to_string(&config).unwrap();
let roundtrip: MetricsConfig = toml::from_str(&serialized).unwrap();
assert!(roundtrip.enabled);
assert_eq!(roundtrip.path, "/custom/metrics");
assert_eq!(roundtrip.sync_interval_secs, 10);
}
}