diff options
Diffstat (limited to 'src/data_collection/disks/freebsd.rs')
-rw-r--r-- | src/data_collection/disks/freebsd.rs | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/data_collection/disks/freebsd.rs b/src/data_collection/disks/freebsd.rs new file mode 100644 index 00000000..bb44e1ad --- /dev/null +++ b/src/data_collection/disks/freebsd.rs @@ -0,0 +1,94 @@ +//! Disk stats for FreeBSD. + +use std::io; + +use serde::Deserialize; + +use super::{keep_disk_entry, DiskHarvest, IoHarvest}; + +use crate::{ + data_collection::deserialize_xo, data_collection::disks::IoData, + data_collection::DataCollector, utils::error, +}; +use hashbrown::HashMap; + +#[derive(Deserialize, Debug, Default)] +#[serde(rename_all = "kebab-case")] +struct StorageSystemInformation { + filesystem: Vec<FileSystem>, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +struct FileSystem { + name: String, + total_blocks: u64, + used_blocks: u64, + available_blocks: u64, + mounted_on: String, +} + +pub fn get_io_usage() -> error::Result<IoHarvest> { + // TODO: Should this (and other I/O collectors) fail fast? In general, should collection ever fail fast? + #[allow(unused_mut)] + let mut io_harvest: HashMap<String, Option<IoData>> = + get_disk_info().map(|storage_system_information| { + storage_system_information + .filesystem + .into_iter() + .map(|disk| (disk.name, None)) + .collect() + })?; + + #[cfg(feature = "zfs")] + { + use crate::data_collection::disks::zfs_io_counters; + if let Ok(zfs_io) = zfs_io_counters::zfs_io_stats() { + for io in zfs_io.into_iter() { + let mount_point = io.device_name().to_string_lossy(); + io_harvest.insert( + mount_point.to_string(), + Some(IoData { + read_bytes: io.read_bytes(), + write_bytes: io.write_bytes(), + }), + ); + } + } + } + Ok(io_harvest) +} + +pub fn get_disk_usage(collector: &DataCollector) -> error::Result<Vec<DiskHarvest>> { + let disk_filter = &collector.filters.disk_filter; + let mount_filter = &collector.filters.mount_filter; + let vec_disks: Vec<DiskHarvest> = get_disk_info().map(|storage_system_information| { + storage_system_information + .filesystem + .into_iter() + .filter_map(|disk| { + if keep_disk_entry(&disk.name, &disk.mounted_on, disk_filter, mount_filter) { + Some(DiskHarvest { + free_space: Some(disk.available_blocks * 1024), + used_space: Some(disk.used_blocks * 1024), + total_space: Some(disk.total_blocks * 1024), + mount_point: disk.mounted_on, + name: disk.name, + }) + } else { + None + } + }) + .collect() + })?; + + Ok(vec_disks) +} + +fn get_disk_info() -> io::Result<StorageSystemInformation> { + // TODO: Ideally we don't have to shell out to a new program. + let output = std::process::Command::new("df") + .args(["--libxo", "json", "-k", "-t", "ufs,msdosfs,zfs"]) + .output()?; + deserialize_xo("storage-system-information", &output.stdout) +} |