Skip to content

Commit d7bf682

Browse files
committed
feat(host_metrics source): collect inode metrics
1 parent aa4e264 commit d7bf682

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ byteorder = "1.5.0"
443443
windows-service = "0.8.0"
444444

445445
[target.'cfg(unix)'.dependencies]
446-
nix = { version = "0.26.2", default-features = false, features = ["socket", "signal"] }
446+
nix = { version = "0.26.2", default-features = false, features = ["socket", "signal", "fs"] }
447447

448448
[target.'cfg(target_os = "linux")'.dependencies]
449449
netlink-packet-utils = "0.5.2"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
added inode metrics to the `host_metrics` source filesystem collector on unix systems: `filesystem_inodes_total`, `filesystem_inodes_free`, and `filesystem_inodes_used`.
2+
3+
authors: mushrowan

src/sources/host_metrics/filesystem.rs

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use futures::StreamExt;
22
use heim::units::information::byte;
33
#[cfg(not(windows))]
44
use heim::units::ratio::ratio;
5+
#[cfg(unix)]
6+
use nix::sys::statvfs::statvfs;
57
use vector_lib::{configurable::configurable_component, metric_tags};
68

79
use super::{FilterList, HostMetrics, default_all_devices, example_devices, filter_result};
@@ -128,8 +130,28 @@ impl HostMetrics {
128130
output.gauge(
129131
"filesystem_used_ratio",
130132
usage.ratio().get::<ratio>() as f64,
131-
tags,
133+
tags.clone(),
132134
);
135+
136+
// Inode metrics (Unix only)
137+
#[cfg(unix)]
138+
if let Ok(stat) = statvfs(partition.mount_point()) {
139+
let inodes_total = stat.files() as f64;
140+
let inodes_free = stat.files_free() as f64;
141+
let inodes_used = inodes_total - inodes_free;
142+
let inodes_used_ratio = if inodes_total > 0.0 {
143+
inodes_used / inodes_total
144+
} else {
145+
0.0
146+
};
147+
148+
output.gauge("filesystem_inodes_total", inodes_total, tags.clone());
149+
output.gauge("filesystem_inodes_free", inodes_free, tags.clone());
150+
output.gauge("filesystem_inodes_used", inodes_used, tags.clone());
151+
output.gauge("filesystem_inodes_used_ratio", inodes_used_ratio, tags);
152+
}
153+
#[cfg(windows)]
154+
drop(tags);
133155
}
134156
}
135157
Err(error) => {
@@ -161,17 +183,40 @@ mod tests {
161183
.await;
162184
let metrics = buffer.metrics;
163185
assert!(!metrics.is_empty());
164-
assert!(metrics.len().is_multiple_of(4));
165186
assert!(all_gauges(&metrics));
166187

167-
// There are exactly three filesystem_* names
168-
for name in &[
188+
// Base metrics (these are always present)
189+
let base_metrics = [
169190
"filesystem_free_bytes",
170191
"filesystem_total_bytes",
171192
"filesystem_used_bytes",
172193
"filesystem_used_ratio",
173-
] {
174-
assert_eq!(count_name(&metrics, name), metrics.len() / 4, "name={name}");
194+
];
195+
196+
// Each filesystem should have all 4 base metrics
197+
let num_filesystems = count_name(&metrics, "filesystem_free_bytes");
198+
assert!(num_filesystems > 0);
199+
for name in &base_metrics {
200+
assert_eq!(count_name(&metrics, name), num_filesystems, "name={name}");
201+
}
202+
203+
// Inode metrics are present for filesystems that support statvfs
204+
// (some virtual filesystems like /proc, /sys might not)
205+
let inode_metrics = [
206+
"filesystem_inodes_total",
207+
"filesystem_inodes_free",
208+
"filesystem_inodes_used",
209+
"filesystem_inodes_used_ratio",
210+
];
211+
let num_inode_total = count_name(&metrics, "filesystem_inodes_total");
212+
assert!(
213+
num_inode_total > 0,
214+
"Expected at least one filesystem to report inode metrics"
215+
);
216+
217+
// For filesystems that report inodes, all 4 inode metrics should be present
218+
for name in &inode_metrics {
219+
assert_eq!(count_name(&metrics, name), num_inode_total, "name={name}");
175220
}
176221

177222
// They should all have "filesystem" and "mountpoint" tags

0 commit comments

Comments
 (0)