systemstat/platform/common.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
use std::{io, path, convert::{TryFrom, TryInto}};
use crate::data::*;
/// The Platform trait declares all the functions for getting system information.
///
/// NOTE: any impl MUST override one of `uptime` or `boot_time`.
pub trait Platform {
fn new() -> Self;
/// Returns a delayed vector of CPU load statistics, one object per CPU (core).
///
/// You need to wait some time (about a second is good) before unwrapping the
/// `DelayedMeasurement` with `.done()`.
fn cpu_load(&self) -> io::Result<DelayedMeasurement<Vec<CPULoad>>>;
/// Returns a delayed CPU load statistics object, average over all CPUs (cores).
///
/// You need to wait some time (about a second is good) before unwrapping the
/// `DelayedMeasurement` with `.done()`.
fn cpu_load_aggregate(&self) -> io::Result<DelayedMeasurement<CPULoad>> {
let measurement = self.cpu_load()?;
Ok(DelayedMeasurement::new(
Box::new(move || measurement.done().map(|ls| {
let mut it = ls.iter();
let first = it.next().unwrap().clone(); // has to be a variable, rust moves the iterator otherwise
it.fold(first, |acc, l| acc.avg_add(l))
}))))
}
/// Returns a load average object.
fn load_average(&self) -> io::Result<LoadAverage>;
/// Returns a memory information object.
fn memory(&self) -> io::Result<Memory>;
/// Returns a swap memory information object.
fn swap(&self) -> io::Result<Swap>;
/// Returns a swap and a memory information object.
/// On some platforms this is more efficient than calling memory() and swap() separately
/// If memory() or swap() are not implemented for a platform, this function will fail.
fn memory_and_swap(&self) -> io::Result<(Memory, Swap)> {
// Do swap first, in order to fail fast if it's not implemented
let swap = self.swap()?;
let memory = self.memory()?;
Ok((memory, swap))
}
/// Returns the system uptime.
fn uptime(&self) -> io::Result<Duration> {
self.boot_time().and_then(|bt| {
(OffsetDateTime::now_utc() - bt)
.try_into()
.map_err(|_| io::Error::new(io::ErrorKind::Other, "Could not process time"))
})
}
/// Returns the system boot time.
fn boot_time(&self) -> io::Result<OffsetDateTime> {
self.uptime().and_then(|ut| {
Ok(OffsetDateTime::now_utc()
- time::Duration::try_from(ut)
.map_err(|_| io::Error::new(io::ErrorKind::Other, "Could not process time"))?)
})
}
/// Returns a battery life information object.
fn battery_life(&self) -> io::Result<BatteryLife>;
/// Returns whether AC power is plugged in.
fn on_ac_power(&self) -> io::Result<bool>;
/// Returns a vector of filesystem mount information objects.
fn mounts(&self) -> io::Result<Vec<Filesystem>>;
/// Returns a filesystem mount information object for the filesystem at a given path.
fn mount_at<P: AsRef<path::Path>>(&self, path: P) -> io::Result<Filesystem> {
self.mounts()
.and_then(|mounts| {
mounts
.into_iter()
.find(|mount| path::Path::new(&mount.fs_mounted_on) == path.as_ref())
.ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "No such mount"))
})
}
/// Returns a map of block device statistics objects
fn block_device_statistics(&self) -> io::Result<BTreeMap<String, BlockDeviceStats>>;
/// Returns a map of network intefrace information objects.
///
/// It's a map because most operating systems return an object per IP address, not per
/// interface, and we're doing deduplication and packing everything into one object per
/// interface. You can use the .values() iterator if you need to iterate over all of them.
fn networks(&self) -> io::Result<BTreeMap<String, Network>>;
/// Returns statistics for a given interface (bytes/packets sent/received)
fn network_stats(&self, interface: &str) -> io::Result<NetworkStats>;
/// Returns the current CPU temperature in degrees Celsius.
///
/// Depending on the platform, this might be core 0, package, etc.
fn cpu_temp(&self) -> io::Result<f32>;
/// Returns information about the number of sockets in use
fn socket_stats(&self) -> io::Result<SocketStats>;
}