//! System statistics retrieval functions and associated data types. use std::result::Result; #[cfg(feature = "miniserde_support")] use miniserde::{Deserialize, Serialize}; #[cfg(feature = "serde_support")] use serde::{Deserialize, Serialize}; use probes::{cpu, disk_usage, load, memory}; use systemstat::{Platform, System}; use crate::error::StatsError; /// CPU statistics. #[derive(Debug)] #[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct CpuStat { /// Time spent running user space (application) code. pub user: u64, /// Time spent running kernel code. pub system: u64, /// Time spent doing nothing. pub idle: u64, /// Time spent running user space processes which have been niced. pub nice: u64, } /// CPU statistics as percentages. #[derive(Debug)] #[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct CpuStatPercentages { /// Time spent running user space (application) code. pub user: f32, /// Time spent running kernel code. pub system: f32, /// Time spent doing nothing. pub idle: f32, /// Time spent running user space processes which have been niced. pub nice: f32, } /// Disk usage statistics. #[derive(Debug)] #[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct DiskUsage { /// Filesystem device path. pub filesystem: Option, /// Total amount of disk space as a number of 1,000 kilobyte blocks. pub one_k_blocks: u64, /// Total amount of used disk space as a number of 1,000 kilobyte blocks. pub one_k_blocks_used: u64, /// Total amount of free / available disk space as a number of 1,000 kilobyte blocks. pub one_k_blocks_free: u64, /// Total amount of used disk space as a percentage. pub used_percentage: u32, /// Mountpoint of the disk / partition. pub mountpoint: String, } /// Load average statistics. #[derive(Debug)] #[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct LoadAverage { /// Average computational work performed over the past minute. pub one: f32, /// Average computational work performed over the past five minutes. pub five: f32, /// Average computational work performed over the past fifteen minutes. pub fifteen: f32, } /// Memory statistics. #[derive(Debug)] #[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct MemStat { /// Total amount of physical memory in kilobytes. pub total: u64, /// Total amount of free / available physical memory in kilobytes. pub free: u64, /// Total amount of used physical memory in kilobytes. pub used: u64, } /// Retrieve the current CPU statistics. pub fn cpu_stats() -> Result { let cpu_stats = cpu::proc::read().map_err(StatsError::CpuStat)?; let s = cpu_stats.stat; let cpu = CpuStat { user: s.user, system: s.system, nice: s.nice, idle: s.idle, }; Ok(cpu) } /// Retrieve the current CPU statistics as percentages. pub fn cpu_stats_percent() -> Result { let cpu_stats = cpu::proc::read().map_err(StatsError::CpuStat)?; let s = cpu_stats.stat.in_percentages(); let cpu = CpuStatPercentages { user: s.user, system: s.system, nice: s.nice, idle: s.idle, }; Ok(cpu) } /// Retrieve the current disk usage statistics for each available disk / partition. pub fn disk_usage() -> Result, StatsError> { let disks = disk_usage::read().map_err(StatsError::DiskUsage)?; let mut disk_usages = Vec::new(); for d in disks { let disk = DiskUsage { filesystem: d.filesystem, one_k_blocks: d.one_k_blocks, one_k_blocks_used: d.one_k_blocks_used, one_k_blocks_free: d.one_k_blocks_free, used_percentage: d.used_percentage, mountpoint: d.mountpoint, }; disk_usages.push(disk); } Ok(disk_usages) } /// Retrieve the current load average statistics. pub fn load_average() -> Result { let l = load::read().map_err(StatsError::LoadAvg)?; let load_avg = LoadAverage { one: l.one, five: l.five, fifteen: l.fifteen, }; Ok(load_avg) } /// Retrieve the current memory usage statistics. pub fn mem_stats() -> Result { let m = memory::read().map_err(StatsError::MemStat)?; let mem = MemStat { total: m.total(), free: m.free(), used: m.used(), }; Ok(mem) } /// Retrieve the system uptime in seconds. pub fn uptime() -> Result { let sys = System::new(); let uptime = sys.uptime().map_err(StatsError::Uptime)?; let uptime_secs = uptime.as_secs(); Ok(uptime_secs) }