sync cpu time

This commit is contained in:
Robin Appelman 2021-03-27 23:48:58 +01:00
commit ad5ae35ecf
4 changed files with 31 additions and 7 deletions

1
Cargo.lock generated
View file

@ -1059,6 +1059,7 @@ dependencies = [
"heim", "heim",
"hostname", "hostname",
"iai", "iai",
"libc",
"once_cell", "once_cell",
"parse-display", "parse-display",
"regex", "regex",

View file

@ -17,6 +17,7 @@ parse-display = "0.4"
regex = { version = "1", default-features = false } regex = { version = "1", default-features = false }
once_cell = "1" once_cell = "1"
hostname = "0.3" hostname = "0.3"
libc = "0.2"
[dev-dependencies] [dev-dependencies]
iai = "0.1" iai = "0.1"

View file

@ -11,12 +11,12 @@ use std::collections::HashSet;
use std::fmt::Write; use std::fmt::Write;
pub async fn get_metrics() -> Result<String> { pub async fn get_metrics() -> Result<String> {
let (cpu, network, disks, disk_usage) = try_join! { let (network, disks, disk_usage) = try_join! {
cpu_time(),
network_stats(), network_stats(),
disk_stats(), disk_stats(),
disk_usage(), disk_usage(),
}?; }?;
let cpu = cpu_time()?;
let hostname = hostname()?; let hostname = hostname()?;
let memory = memory()?; let memory = memory()?;
let temperatures = temperatures()?; let temperatures = temperatures()?;

View file

@ -1,9 +1,8 @@
use color_eyre::{Report, Result}; use color_eyre::{Report, Result};
use futures_util::future; use futures_util::future;
use futures_util::stream::{Stream, StreamExt}; use futures_util::stream::{Stream, StreamExt};
use heim::cpu::time;
use heim::disk::{FileSystem, Partition}; use heim::disk::{FileSystem, Partition};
use heim::units::{information, time}; use heim::units::information;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use parse_display::Display; use parse_display::Display;
use regex::Regex; use regex::Regex;
@ -110,9 +109,22 @@ pub fn memory() -> Result<Memory> {
Ok(mem) Ok(mem)
} }
pub async fn cpu_time() -> Result<f64> { pub fn cpu_time() -> Result<u64> {
let time = time().await?; let stat = BufReader::new(File::open("/proc/stat")?);
Ok(time.user().get::<time::second>() + time.system().get::<time::second>()) let line = stat
.lines()
.next()
.ok_or(Report::msg("Invalid /proc/stat"))??;
let mut parts = line.split_ascii_whitespace();
if let (_cpu, Some(user), _nice, Some(system)) =
(parts.next(), parts.next(), parts.next(), parts.next())
{
let user: u64 = user.parse()?;
let system: u64 = system.parse()?;
Ok((user + system) * clock_ticks()?)
} else {
Err(Report::msg("Invalid /proc/stat"))
}
} }
pub async fn network_stats() -> Result<impl Stream<Item = IOStats>> { pub async fn network_stats() -> Result<impl Stream<Item = IOStats>> {
@ -173,3 +185,13 @@ pub async fn disk_usage() -> Result<impl Stream<Item = DiskUsage>> {
free: usage.free().get::<information::byte>(), free: usage.free().get::<information::byte>(),
})) }))
} }
fn clock_ticks() -> Result<u64> {
let result = unsafe { libc::sysconf(libc::_SC_CLK_TCK) };
if result > 0 {
Ok(result as u64)
} else {
Err(Report::msg("Failed to get clock ticks"))
}
}