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

View file

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