-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathconfig.rs
More file actions
146 lines (128 loc) · 4.43 KB
/
Copy pathconfig.rs
File metadata and controls
146 lines (128 loc) · 4.43 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! Prometheus configuration domain model
//!
//! Defines the configuration for Prometheus metrics scraping.
use std::num::NonZeroU32;
use serde::{Deserialize, Serialize};
/// Default scrape interval in seconds
///
/// This is the recommended interval for most use cases, balancing
/// monitoring frequency with resource usage.
const DEFAULT_SCRAPE_INTERVAL_SECS: u32 = 15;
/// Prometheus metrics collection configuration
///
/// Configures how Prometheus scrapes metrics from the tracker.
/// When present in environment configuration, Prometheus service is enabled.
/// When absent, Prometheus service is disabled.
///
/// # Example
///
/// ```rust
/// use std::num::NonZeroU32;
/// use torrust_tracker_deployer_lib::domain::prometheus::PrometheusConfig;
///
/// let interval = NonZeroU32::new(15).expect("15 is non-zero");
/// let config = PrometheusConfig::new(interval);
/// ```
///
/// # Default Behavior
///
/// - Default scrape interval: 15 seconds
/// - Minimum: 1 second (to avoid zero or negative values)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct PrometheusConfig {
/// Scrape interval in seconds
///
/// Guaranteed to be non-zero at the type level.
/// The Prometheus template will append 's' suffix.
/// Examples: 15 → "15s", 30 → "30s", 60 → "60s" (1 minute)
scrape_interval_in_secs: NonZeroU32,
}
impl PrometheusConfig {
/// Creates a new Prometheus configuration with the specified scrape interval
///
/// # Arguments
///
/// * `scrape_interval_in_secs` - Non-zero interval in seconds
///
/// # Examples
///
/// ```rust
/// use std::num::NonZeroU32;
/// use torrust_tracker_deployer_lib::domain::prometheus::PrometheusConfig;
///
/// let interval = NonZeroU32::new(30).expect("30 is non-zero");
/// let config = PrometheusConfig::new(interval);
/// assert_eq!(config.scrape_interval_in_secs(), 30);
/// ```
#[must_use]
pub const fn new(scrape_interval_in_secs: NonZeroU32) -> Self {
Self {
scrape_interval_in_secs,
}
}
/// Returns the scrape interval in seconds
///
/// The value is guaranteed to be non-zero.
#[must_use]
pub fn scrape_interval_in_secs(&self) -> u32 {
self.scrape_interval_in_secs.get()
}
}
impl Default for PrometheusConfig {
fn default() -> Self {
Self {
// SAFETY: DEFAULT_SCRAPE_INTERVAL_SECS is non-zero
scrape_interval_in_secs: NonZeroU32::new(DEFAULT_SCRAPE_INTERVAL_SECS)
.expect("DEFAULT_SCRAPE_INTERVAL_SECS is non-zero"),
}
}
}
#[cfg(test)]
mod tests {
use std::num::NonZeroU32;
use super::*;
#[test]
fn it_should_create_prometheus_config_with_default_values() {
let config = PrometheusConfig::default();
assert_eq!(
config.scrape_interval_in_secs(),
DEFAULT_SCRAPE_INTERVAL_SECS
);
}
#[test]
fn it_should_create_prometheus_config_with_custom_interval() {
let interval = NonZeroU32::new(30).expect("30 is non-zero");
let config = PrometheusConfig::new(interval);
assert_eq!(config.scrape_interval_in_secs(), 30);
}
#[test]
fn it_should_serialize_to_json() {
let interval = NonZeroU32::new(20).expect("20 is non-zero");
let config = PrometheusConfig::new(interval);
let json = serde_json::to_value(&config).unwrap();
assert_eq!(json["scrape_interval_in_secs"], 20);
}
#[test]
fn it_should_deserialize_from_json() {
let json = serde_json::json!({
"scrape_interval_in_secs": 25
});
let config: PrometheusConfig = serde_json::from_value(json).unwrap();
assert_eq!(config.scrape_interval_in_secs(), 25);
}
#[test]
fn it_should_support_different_scrape_intervals() {
let fast = PrometheusConfig::new(NonZeroU32::new(5).expect("5 is non-zero"));
let medium = PrometheusConfig::new(NonZeroU32::new(15).expect("15 is non-zero"));
let slow = PrometheusConfig::new(NonZeroU32::new(300).expect("300 is non-zero"));
assert_eq!(fast.scrape_interval_in_secs(), 5);
assert_eq!(medium.scrape_interval_in_secs(), 15);
assert_eq!(slow.scrape_interval_in_secs(), 300);
}
#[test]
fn it_should_reject_zero_interval_at_type_level() {
// Cannot construct NonZeroU32 with 0
let result = NonZeroU32::new(0);
assert!(result.is_none());
}
}