mz_clusterd/
usage_metrics.rs1use std::path::PathBuf;
16
17use serde::Serialize;
18use tracing::error;
19
20pub(crate) struct Collector {
22 pub disk_root: Option<PathBuf>,
23}
24
25impl Collector {
26 pub fn collect(&self) -> Usage {
28 Usage {
29 disk_bytes: self.collect_disk_usage(),
30 swap_bytes: self.collect_swap_usage(),
31 }
32 }
33
34 fn collect_disk_usage(&self) -> Option<u64> {
35 let Some(root) = &self.disk_root else {
36 return None;
37 };
38
39 let stat = match nix::sys::statvfs::statvfs(root) {
40 Ok(stat) => stat,
41 Err(err) => {
42 error!("statvfs error: {err}");
43 return None;
44 }
45 };
46
47 #[allow(clippy::useless_conversion)]
49 let used_blocks = u64::from(stat.blocks() - stat.blocks_available());
50 let used_bytes = used_blocks * stat.fragment_size();
51
52 Some(used_bytes)
53 }
54
55 #[cfg(target_os = "linux")]
56 fn collect_swap_usage(&self) -> Option<u64> {
57 use mz_compute::memory_limiter::ProcStatus;
58 use mz_ore::cast::CastInto;
59
60 match ProcStatus::from_proc() {
61 Ok(status) => {
62 let bytes = status.vm_swap.cast_into();
63 Some(bytes)
64 }
65 Err(err) => {
66 error!("error reading /proc/self/status: {err}");
67 None
68 }
69 }
70 }
71
72 #[cfg(not(target_os = "linux"))]
73 fn collect_swap_usage(&self) -> Option<u64> {
74 None
75 }
76}
77
78#[derive(Serialize)]
80pub(crate) struct Usage {
81 disk_bytes: Option<u64>,
82 swap_bytes: Option<u64>,
83}