|
| 1 | +use sysinfo::Components; |
| 2 | +use vector_lib::metric_tags; |
| 3 | + |
| 4 | +use super::HostMetrics; |
| 5 | + |
| 6 | +const COMPONENT: &str = "component"; |
| 7 | +const TEMPERATURE_CELSIUS: &str = "temperature_celsius"; |
| 8 | +const TEMPERATURE_MAX_CELSIUS: &str = "temperature_max_celsius"; |
| 9 | +const TEMPERATURE_CRITICAL_CELSIUS: &str = "temperature_critical_celsius"; |
| 10 | + |
| 11 | +impl HostMetrics { |
| 12 | + pub async fn temperature_metrics(&self, output: &mut super::MetricsBuffer) { |
| 13 | + output.name = "temperature"; |
| 14 | + let components = Components::new_with_refreshed_list(); |
| 15 | + for component in &components { |
| 16 | + let label = component.label(); |
| 17 | + let tags = || metric_tags!(COMPONENT => label); |
| 18 | + if let Some(temperature) = component.temperature() { |
| 19 | + output.gauge(TEMPERATURE_CELSIUS, temperature as f64, tags()); |
| 20 | + } |
| 21 | + if let Some(max) = component.max() { |
| 22 | + output.gauge(TEMPERATURE_MAX_CELSIUS, max as f64, tags()); |
| 23 | + } |
| 24 | + if let Some(critical) = component.critical() { |
| 25 | + output.gauge(TEMPERATURE_CRITICAL_CELSIUS, critical as f64, tags()); |
| 26 | + } |
| 27 | + } |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +#[cfg(test)] |
| 32 | +mod tests { |
| 33 | + use super::{ |
| 34 | + super::{HostMetrics, HostMetricsConfig, MetricsBuffer, tests::all_gauges}, |
| 35 | + COMPONENT, |
| 36 | + }; |
| 37 | + |
| 38 | + #[tokio::test] |
| 39 | + async fn generates_temperature_metrics() { |
| 40 | + let mut buffer = MetricsBuffer::new(None); |
| 41 | + HostMetrics::new(HostMetricsConfig::default()) |
| 42 | + .temperature_metrics(&mut buffer) |
| 43 | + .await; |
| 44 | + let metrics = buffer.metrics; |
| 45 | + |
| 46 | + // Temperature sensors are not exposed in many environments (containers, |
| 47 | + // virtual machines, CI runners), so the component list can legitimately |
| 48 | + // be empty. When metrics are produced, they must all be gauges named |
| 49 | + // `temperature*` and carry the `component` tag. |
| 50 | + assert!(all_gauges(&metrics)); |
| 51 | + for metric in &metrics { |
| 52 | + assert!( |
| 53 | + metric.name().starts_with("temperature"), |
| 54 | + "unexpected metric name: {}", |
| 55 | + metric.name() |
| 56 | + ); |
| 57 | + assert!( |
| 58 | + metric |
| 59 | + .tags() |
| 60 | + .expect("temperature metric is missing tags") |
| 61 | + .contains_key(COMPONENT), |
| 62 | + "temperature metric is missing the `component` tag" |
| 63 | + ); |
| 64 | + } |
| 65 | + } |
| 66 | +} |
0 commit comments