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