systemstat/platform/
common.rs

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