split of disk module

This commit is contained in:
Robin Appelman 2023-05-02 21:24:52 +02:00
commit 89375a13bb
6 changed files with 117 additions and 109 deletions

95
src/disk/mod.rs Normal file
View file

@ -0,0 +1,95 @@
use ahash::{AHashSet, AHasher};
use color_eyre::{Report, Result};
use once_cell::sync::Lazy;
use regex::Regex;
use std::ffi::CString;
use std::fs::File;
use std::hash::{Hash, Hasher};
use std::io::{BufRead, BufReader};
use std::mem::MaybeUninit;
pub mod zfs;
#[derive(Debug, Clone, Default)]
pub struct IoStats {
pub interface: String,
pub bytes_sent: u64,
pub bytes_received: u64,
}
#[derive(Clone, Debug)]
pub struct DiskUsage {
pub name: String,
pub size: u64,
pub free: u64,
}
pub fn disk_stats() -> Result<impl Iterator<Item = IoStats>> {
static DISK_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r" ([sv]d[a-z]+|nvme[0-9]n[0-9]|mmcblk[0-9]) ").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_sectors = parts.next()?.parse::<u64>().ok()?;
let mut parts = parts.skip(1);
let _write_count = parts.next();
let _write_merged_count = parts.next();
let write_sectors = parts.next()?.parse::<u64>().ok()?;
Some(IoStats {
interface: name,
bytes_sent: write_sectors * 512,
bytes_received: read_sectors * 512,
})
}))
}
pub fn disk_usage() -> Result<impl Iterator<Item = DiskUsage>> {
let stat = BufReader::new(File::open("/proc/mounts")?);
let mut found_disks = AHashSet::with_capacity(8);
Ok(stat
.lines()
.filter_map(Result::ok)
.filter(|line| line.starts_with('/'))
.filter(|line| !line.contains("/dev/loop"))
.filter_map(move |line: String| {
let mut parts = line.split_ascii_whitespace();
let disk = parts.next()?;
if !found_disks.insert(hash_str(disk)) {
return None;
}
let mount_point = parts.next()?;
let stat = statvfs(&mount_point).ok()?;
Some(DiskUsage {
name: mount_point.to_string(),
size: stat.f_blocks * stat.f_frsize as u64,
free: stat.f_bavail * stat.f_frsize as u64,
})
}))
}
fn statvfs(path: &str) -> Result<libc::statvfs> {
let path = CString::new(path)?;
let mut vfs = MaybeUninit::<libc::statvfs>::uninit();
let result = unsafe { libc::statvfs(path.as_ptr(), vfs.as_mut_ptr()) };
if result == 0 {
let vfs = unsafe { vfs.assume_init() };
Ok(vfs)
} else {
Err(Report::msg("Failed to stat vfs"))
}
}
fn hash_str(s: &str) -> u64 {
let mut hasher = AHasher::default();
s.hash(&mut hasher);
hasher.finish()
}

View file

@ -1,4 +1,4 @@
use crate::sensors::DiskUsage;
use crate::disk::DiskUsage;
use color_eyre::Result;
use std::fmt::Write;
use std::fs::read_to_string;

View file

@ -1,12 +1,13 @@
pub mod disk;
pub mod docker;
pub mod nvidia;
pub mod power;
pub mod sensors;
pub mod zfs;
use crate::sensors::temperatures;
use crate::disk::disk_usage;
use crate::disk::zfs::pools;
use crate::disk::*;
use crate::sensors::*;
use crate::zfs::pools;
use color_eyre::Result;
use std::fmt::Write;

View file

@ -3,15 +3,15 @@ use color_eyre::{Report, Result};
use futures_util::pin_mut;
use futures_util::StreamExt;
use libmdns::Responder;
use palantir::disk::zfs::arcstats;
use palantir::docker::{get_docker, stat, Container};
use palantir::get_metrics;
use palantir::power::power_usage;
use palantir::zfs::arcstats;
use std::time::Duration;
use tokio::runtime::Handle;
use tokio::spawn;
use tokio::time::sleep;
use tracing::{info, warn};
use tracing::warn;
use warp::reject::Reject;
use warp::{Filter, Rejection};

View file

@ -1,14 +1,8 @@
use ahash::{AHasher, RandomState};
use crate::disk::IoStats;
use color_eyre::{Report, Result};
use once_cell::sync::Lazy;
use regex::Regex;
use std::array::IntoIter;
use std::collections::HashSet;
use std::ffi::{CStr, CString};
use std::fs::{read, read_dir, read_to_string, File};
use std::hash::{Hash, Hasher};
use std::io::{BufRead, BufReader};
use std::mem::MaybeUninit;
use std::os::unix::ffi::OsStrExt;
#[derive(Debug, Clone, Default)]
@ -33,20 +27,6 @@ pub struct Memory {
pub available: u64,
}
#[derive(Debug, Clone, Default)]
pub struct IoStats {
pub interface: String,
pub bytes_sent: u64,
pub bytes_received: u64,
}
#[derive(Clone, Debug)]
pub struct DiskUsage {
pub name: String,
pub size: u64,
pub free: u64,
}
pub fn temperatures() -> Result<Temperatures> {
let mut temps = Temperatures::default();
@ -209,58 +189,6 @@ pub fn hostname() -> Result<String> {
.map_err(|_| Report::msg("non utf8 hostname"))
}
pub fn disk_stats() -> Result<impl Iterator<Item = IoStats>> {
static DISK_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r" ([sv]d[a-z]+|nvme[0-9]n[0-9]|mmcblk[0-9]) ").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_sectors = parts.next()?.parse::<u64>().ok()?;
let mut parts = parts.skip(1);
let _write_count = parts.next();
let _write_merged_count = parts.next();
let write_sectors = parts.next()?.parse::<u64>().ok()?;
Some(IoStats {
interface: name,
bytes_sent: write_sectors * 512,
bytes_received: read_sectors * 512,
})
}))
}
pub fn disk_usage() -> Result<impl Iterator<Item = DiskUsage>> {
let stat = BufReader::new(File::open("/proc/mounts")?);
let mut found_disks = HashSet::with_capacity_and_hasher(8, RandomState::new());
Ok(stat
.lines()
.filter_map(Result::ok)
.filter(|line| line.starts_with('/'))
.filter(|line| !line.contains("/dev/loop"))
.filter_map(move |line: String| {
let mut parts = line.split_ascii_whitespace();
let disk = parts.next()?;
if !found_disks.insert(hash_str(disk)) {
return None;
}
let mount_point = parts.next()?;
let mount_point = CString::new(mount_point).ok()?;
let stat = statvfs(&mount_point).ok()?;
Some(DiskUsage {
name: mount_point.into_string().unwrap(),
size: stat.f_blocks * stat.f_frsize as u64,
free: stat.f_bavail * stat.f_frsize as u64,
})
}))
}
pub fn clock_ticks() -> Result<u64> {
let result = unsafe { libc::sysconf(libc::_SC_CLK_TCK) };
@ -271,18 +199,6 @@ pub fn clock_ticks() -> Result<u64> {
}
}
fn statvfs(path: &CStr) -> Result<libc::statvfs> {
let mut vfs = MaybeUninit::<libc::statvfs>::uninit();
let result = unsafe { libc::statvfs(path.as_ptr(), vfs.as_mut_ptr()) };
if result == 0 {
let vfs = unsafe { vfs.assume_init() };
Ok(vfs)
} else {
Err(Report::msg("Failed to stat vfs"))
}
}
fn cpu_count() -> Result<u64> {
let result = unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) };
@ -292,9 +208,3 @@ fn cpu_count() -> Result<u64> {
Ok(result as u64)
}
}
fn hash_str(s: &str) -> u64 {
let mut hasher = AHasher::default();
s.hash(&mut hasher);
hasher.finish()
}