vector_core/config/
metrics_expiration.rs1use vector_config::configurable_component;
2
3#[configurable_component]
5#[derive(Clone, Debug, PartialEq, Default)]
6pub struct PerMetricSetExpiration {
7 #[serde(default, skip_serializing_if = "crate::serde::is_default")]
9 pub name: Option<MetricNameMatcherConfig>,
10 #[serde(default, skip_serializing_if = "crate::serde::is_default")]
12 #[configurable(metadata(
13 docs::enum_tag_field = "type",
14 docs::enum_tagging = "internal",
15 docs::enum_tag_description = "Metric label matcher type."
16 ))]
17 pub labels: Option<MetricLabelMatcherConfig>,
18 #[configurable(metadata(docs::examples = 60.0))]
24 pub expire_secs: f64,
25}
26
27#[configurable_component]
29#[derive(Clone, Debug, PartialEq)]
30#[serde(tag = "type", rename_all = "snake_case")]
31#[configurable(metadata(docs::enum_tag_description = "Metric name matcher type."))]
32pub enum MetricNameMatcherConfig {
33 Exact {
35 value: String,
37 },
38 Regex {
40 pattern: String,
42 },
43}
44
45#[configurable_component]
47#[derive(Clone, Debug, PartialEq)]
48#[serde(tag = "type", rename_all = "snake_case")]
49#[configurable(metadata(docs::enum_tag_description = "Metric label matcher type."))]
50pub enum MetricLabelMatcher {
51 Exact {
53 key: String,
55 value: String,
57 },
58 Regex {
60 key: String,
62 value_pattern: String,
64 },
65}
66
67#[configurable_component]
69#[derive(Clone, Debug, PartialEq)]
70#[serde(tag = "type", rename_all = "snake_case")]
71#[configurable(metadata(docs::enum_tag_description = "Metric label group matcher type."))]
72pub enum MetricLabelMatcherConfig {
73 Any {
75 matchers: Vec<MetricLabelMatcher>,
77 },
78 All {
80 matchers: Vec<MetricLabelMatcher>,
82 },
83}
84
85#[cfg(test)]
87mod tests {
88 use vrl::prelude::indoc;
89
90 use super::*;
91
92 #[test]
93 fn just_expiration_config() {
94 let config = serde_yaml::from_str::<PerMetricSetExpiration>(indoc! {r"
97 expire_secs: 10.0
98 "})
99 .unwrap();
100
101 assert!(config.name.is_none());
102 assert!(config.labels.is_none());
103 assert_eq!(10.0, config.expire_secs);
104 }
105
106 #[test]
107 fn simple_name_config() {
108 let config = serde_yaml::from_str::<PerMetricSetExpiration>(indoc! {r#"
109 name:
110 type: "exact"
111 value: "test_metric"
112 expire_secs: 1.0
113 "#})
114 .unwrap();
115
116 if let Some(MetricNameMatcherConfig::Exact { value }) = config.name {
117 assert_eq!("test_metric", value);
118 } else {
119 panic!("Expected exact name matcher");
120 }
121 assert!(config.labels.is_none());
122 assert_eq!(1.0, config.expire_secs);
123 }
124
125 #[test]
126 fn simple_labels_config() {
127 let config = serde_yaml::from_str::<PerMetricSetExpiration>(indoc! {r#"
128 labels:
129 type: "all"
130 matchers :
131 - type: "exact"
132 key: "test_metric_label"
133 value: "test_value"
134 expire_secs: 1.0
135 "#})
136 .unwrap();
137
138 if let Some(MetricLabelMatcherConfig::All { matchers }) = config.labels {
139 if let MetricLabelMatcher::Exact { key, value } = &matchers[0] {
140 assert_eq!("test_metric_label", key);
141 assert_eq!("test_value", value);
142 } else {
143 panic!("Expected exact metric matcher");
144 }
145 } else {
146 panic!("Expected all matcher");
147 }
148 assert!(config.name.is_none());
149 assert_eq!(1.0, config.expire_secs);
150 }
151
152 #[test]
153 fn complex_config() {
154 let config = serde_yaml::from_str::<PerMetricSetExpiration>(indoc! {r#"
155 name:
156 type: "regex"
157 pattern: "test_metric.*"
158 labels:
159 type: "all"
160 matchers:
161 - type: "exact"
162 key: "component_kind"
163 value: "sink"
164 - type: "exact"
165 key: "component_kind"
166 value: "source"
167 expire_secs: 1.0
168 "#})
169 .unwrap();
170
171 if let Some(MetricNameMatcherConfig::Regex { ref pattern }) = config.name {
172 assert_eq!("test_metric.*", pattern);
173 } else {
174 panic!("Expected regex name matcher");
175 }
176
177 let Some(MetricLabelMatcherConfig::All {
178 matchers: all_matchers,
179 }) = config.labels
180 else {
181 panic!("Expected all label matcher");
182 };
183 assert_eq!(2, all_matchers.len());
184
185 let MetricLabelMatcher::Exact { key, value } = &all_matchers[0] else {
186 panic!("Expected first label matcher to be exact matcher");
187 };
188 assert_eq!("component_kind", key);
189 assert_eq!("sink", value);
190 let MetricLabelMatcher::Exact { key, value } = &all_matchers[1] else {
191 panic!("Expected second label matcher to be exact matcher");
192 };
193 assert_eq!("component_kind", key);
194 assert_eq!("source", value);
195 }
196}