170 lines
5.1 KiB
Rust
170 lines
5.1 KiB
Rust
//! 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<String>,
|
|
/// 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<CpuStat, StatsError> {
|
|
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<CpuStatPercentages, StatsError> {
|
|
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<Vec<DiskUsage>, 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<LoadAverage, StatsError> {
|
|
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<MemStat, StatsError> {
|
|
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<u64, StatsError> {
|
|
let sys = System::new();
|
|
let uptime = sys.uptime().map_err(StatsError::Uptime)?;
|
|
let uptime_secs = uptime.as_secs();
|
|
|
|
Ok(uptime_secs)
|
|
}
|