vector/sources/host_metrics/
process.rs1use std::ffi::OsStr;
2
3use sysinfo::{ProcessRefreshKind, ProcessesToUpdate, UpdateKind};
4use vector_lib::configurable::configurable_component;
5#[cfg(target_os = "linux")]
6use vector_lib::metric_tags;
7
8use super::{FilterList, HostMetrics, default_all_processes, example_processes};
9
10#[configurable_component]
12#[derive(Clone, Debug, Default)]
13pub struct ProcessConfig {
14 #[serde(default = "default_all_processes")]
16 #[configurable(metadata(docs::examples = "example_processes()"))]
17 processes: FilterList,
18}
19
20const RUNTIME: &str = "process_runtime";
21const CPU_USAGE: &str = "process_cpu_usage";
22const MEMORY_USAGE: &str = "process_memory_usage";
23const MEMORY_VIRTUAL_USAGE: &str = "process_memory_virtual_usage";
24
25impl HostMetrics {
26 pub async fn process_metrics(&mut self, output: &mut super::MetricsBuffer) {
27 self.system.refresh_processes_specifics(
28 ProcessesToUpdate::All,
29 true,
30 ProcessRefreshKind::default()
31 .with_memory()
32 .with_cpu()
33 .with_cmd(UpdateKind::OnlyIfNotSet),
34 );
35 output.name = "process";
36 let sep = OsStr::new(" ");
37 for (pid, process) in self.system.processes().iter().filter(|&(_, proc)| {
38 self.config
39 .process
40 .processes
41 .contains_str(proc.name().to_str())
42 }) {
43 let tags = || {
44 metric_tags!(
45 "pid" => pid.as_u32().to_string(),
46 "name" => process.name().to_str().unwrap_or("unknown"),
47 "command" => process.cmd().join(sep).to_str().unwrap_or(""))
48 };
49 output.gauge(CPU_USAGE, process.cpu_usage().into(), tags());
50 output.gauge(MEMORY_USAGE, process.memory() as f64, tags());
51 output.gauge(
52 MEMORY_VIRTUAL_USAGE,
53 process.virtual_memory() as f64,
54 tags(),
55 );
56 output.counter(RUNTIME, process.run_time() as f64, tags());
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::super::{HostMetrics, HostMetricsConfig, MetricsBuffer};
64 use crate::sources::host_metrics::tests::count_tag;
65
66 #[tokio::test]
67 async fn generates_process_metrics() {
68 let mut buffer = MetricsBuffer::new(None);
69 HostMetrics::new(HostMetricsConfig::default())
70 .process_metrics(&mut buffer)
71 .await;
72 let metrics = buffer.metrics;
73 assert!(!metrics.is_empty());
74
75 assert!(
77 !metrics
78 .iter()
79 .any(|metric| !metric.name().starts_with("process_"))
80 );
81
82 assert_eq!(count_tag(&metrics, "pid"), metrics.len());
84 assert_eq!(count_tag(&metrics, "name"), metrics.len());
85 assert_eq!(count_tag(&metrics, "command"), metrics.len());
86 }
87}