sync disk stats

This commit is contained in:
Robin Appelman 2021-03-28 21:31:52 +02:00
commit 6613249857
2 changed files with 29 additions and 28 deletions

View file

@ -5,24 +5,20 @@ use crate::sensors::temperatures;
use crate::sensors::*;
use crate::zfs::pools;
use color_eyre::Result;
use futures_util::pin_mut;
use futures_util::stream::StreamExt;
use futures_util::{pin_mut, try_join};
use std::collections::HashSet;
use std::fmt::Write;
pub async fn get_metrics() -> Result<String> {
let (disks, disk_usage) = try_join! {
disk_stats(),
disk_usage(),
}?;
let disk_usage = disk_usage().await?;
let disks = disk_stats()?;
let cpu = cpu_time()?;
let hostname = hostname()?;
let memory = memory()?;
let temperatures = temperatures()?;
let pools = pools();
let network = network_stats()?;
pin_mut!(network);
pin_mut!(disks);
let networks = network_stats()?;
pin_mut!(disk_usage);
let mut result = String::with_capacity(256);
writeln!(&mut result, "cpu_time{{host=\"{}\"}} {:.1}", hostname, cpu).ok();
@ -58,7 +54,7 @@ pub async fn get_metrics() -> Result<String> {
)
.ok();
}
while let Some(network) = network.next() {
for network in networks {
let network: IOStats = network;
if network.bytes_received > 0 || network.bytes_sent > 0 {
writeln!(
@ -75,7 +71,7 @@ pub async fn get_metrics() -> Result<String> {
.ok();
}
}
while let Some(disk) = disks.next().await {
for disk in disks {
let disk: IOStats = disk;
if disk.bytes_received > 0 && disk.bytes_sent > 0 {
writeln!(

View file

@ -173,25 +173,30 @@ pub fn hostname() -> Result<String> {
.map_err(|_| Report::msg("non utf8 hostname"))
}
pub async fn disk_stats() -> Result<impl Stream<Item = IOStats>> {
pub fn disk_stats() -> Result<impl Iterator<Item = IOStats>> {
static DISK_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^([sv]d[a-z]+|nvme\dn\d)$").unwrap());
let disks = heim::disk::io_counters().await?;
Ok(disks
.filter_map(|disk| future::ready(disk.ok()))
.filter_map(|disk| {
future::ready(
disk.device_name()
.to_str()
.map(str::to_string)
.map(|name| (disk, name)),
)
})
.filter(|(_disk, name)| future::ready(DISK_REGEX.is_match(&name)))
.map(|(disk, name)| IOStats {
Lazy::new(|| Regex::new(r" ([sv]d[a-z]+|nvme\dn\d) ").unwrap());
let stat = BufReader::new(File::open("/proc/diskstats")?);
Ok(stat
.lines()
.filter_map(Result::ok)
.filter(|line| DISK_REGEX.is_match(line))
.filter_map(|line: String| {
let mut parts = line.split_whitespace().skip(2);
let name: String = parts.next()?.into();
let _read_count = parts.next();
let _read_merged_count = parts.next();
let read_bytes = parts.next()?.parse().ok()?;
let mut parts = parts.skip(1);
let _write_count = parts.next();
let _write_merged_count = parts.next();
let write_bytes = parts.next()?.parse().ok()?;
Some(IOStats {
interface: name,
bytes_sent: disk.write_bytes().get::<information::byte>(),
bytes_received: disk.read_bytes().get::<information::byte>(),
bytes_sent: write_bytes,
bytes_received: read_bytes,
})
}))
}