mirror of
https://codeberg.org/icewind/palantir.git
synced 2026-06-03 18:24:08 +02:00
split of disk module
This commit is contained in:
parent
70bba8ed2c
commit
89375a13bb
6 changed files with 117 additions and 109 deletions
26
flake.lock
generated
26
flake.lock
generated
|
|
@ -5,11 +5,11 @@
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1659610603,
|
"lastModified": 1671096816,
|
||||||
"narHash": "sha256-LYgASYSPYo7O71WfeUOaEUzYfzuXm8c8eavJcel+pfI=",
|
"narHash": "sha256-ezQCsNgmpUHdZANDCILm3RvtO1xH8uujk/+EqNvzIOg=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "naersk",
|
"repo": "naersk",
|
||||||
"rev": "c6a45e4277fa58abd524681466d3450f896dc094",
|
"rev": "d998160d6a076cfe8f9741e56aeec7e267e3e114",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -20,9 +20,10 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 0,
|
"lastModified": 1674407282,
|
||||||
"narHash": "sha256-ogcrJszrCg23/mIcLEOUCMKgdWlqMJ4QqezvX0V2ZQk=",
|
"narHash": "sha256-2qwc8mrPINSFdWffPK+ji6nQ9aGnnZyHSItVcYDZDlk=",
|
||||||
"path": "/nix/store/f6y01zll9swq7rvf82ya4r3hjs9j93py-source",
|
"path": "/nix/store/47v7isgz6w8zgb1224d46lwvwkdd69bm-source",
|
||||||
|
"rev": "ab1254087f4cdf4af74b552d7fc95175d9bdbb49",
|
||||||
"type": "path"
|
"type": "path"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -32,9 +33,10 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 0,
|
"lastModified": 1674407282,
|
||||||
"narHash": "sha256-ogcrJszrCg23/mIcLEOUCMKgdWlqMJ4QqezvX0V2ZQk=",
|
"narHash": "sha256-2qwc8mrPINSFdWffPK+ji6nQ9aGnnZyHSItVcYDZDlk=",
|
||||||
"path": "/nix/store/f6y01zll9swq7rvf82ya4r3hjs9j93py-source",
|
"path": "/nix/store/47v7isgz6w8zgb1224d46lwvwkdd69bm-source",
|
||||||
|
"rev": "ab1254087f4cdf4af74b552d7fc95175d9bdbb49",
|
||||||
"type": "path"
|
"type": "path"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -51,11 +53,11 @@
|
||||||
},
|
},
|
||||||
"utils": {
|
"utils": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1659877975,
|
"lastModified": 1667395993,
|
||||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
95
src/disk/mod.rs
Normal file
95
src/disk/mod.rs
Normal 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()
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::sensors::DiskUsage;
|
use crate::disk::DiskUsage;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
|
pub mod disk;
|
||||||
pub mod docker;
|
pub mod docker;
|
||||||
pub mod nvidia;
|
pub mod nvidia;
|
||||||
pub mod power;
|
pub mod power;
|
||||||
pub mod sensors;
|
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::sensors::*;
|
||||||
use crate::zfs::pools;
|
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@ use color_eyre::{Report, Result};
|
||||||
use futures_util::pin_mut;
|
use futures_util::pin_mut;
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use libmdns::Responder;
|
use libmdns::Responder;
|
||||||
|
use palantir::disk::zfs::arcstats;
|
||||||
use palantir::docker::{get_docker, stat, Container};
|
use palantir::docker::{get_docker, stat, Container};
|
||||||
use palantir::get_metrics;
|
use palantir::get_metrics;
|
||||||
use palantir::power::power_usage;
|
use palantir::power::power_usage;
|
||||||
use palantir::zfs::arcstats;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::runtime::Handle;
|
use tokio::runtime::Handle;
|
||||||
use tokio::spawn;
|
use tokio::spawn;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use tracing::{info, warn};
|
use tracing::warn;
|
||||||
use warp::reject::Reject;
|
use warp::reject::Reject;
|
||||||
use warp::{Filter, Rejection};
|
use warp::{Filter, Rejection};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,8 @@
|
||||||
use ahash::{AHasher, RandomState};
|
use crate::disk::IoStats;
|
||||||
use color_eyre::{Report, Result};
|
use color_eyre::{Report, Result};
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use regex::Regex;
|
|
||||||
use std::array::IntoIter;
|
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::fs::{read, read_dir, read_to_string, File};
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::mem::MaybeUninit;
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
|
@ -33,20 +27,6 @@ pub struct Memory {
|
||||||
pub available: u64,
|
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> {
|
pub fn temperatures() -> Result<Temperatures> {
|
||||||
let mut temps = Temperatures::default();
|
let mut temps = Temperatures::default();
|
||||||
|
|
||||||
|
|
@ -209,58 +189,6 @@ pub fn hostname() -> Result<String> {
|
||||||
.map_err(|_| Report::msg("non utf8 hostname"))
|
.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> {
|
pub fn clock_ticks() -> Result<u64> {
|
||||||
let result = unsafe { libc::sysconf(libc::_SC_CLK_TCK) };
|
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> {
|
fn cpu_count() -> Result<u64> {
|
||||||
let result = unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) };
|
let result = unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) };
|
||||||
|
|
||||||
|
|
@ -292,9 +208,3 @@ fn cpu_count() -> Result<u64> {
|
||||||
Ok(result as u64)
|
Ok(result as u64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_str(s: &str) -> u64 {
|
|
||||||
let mut hasher = AHasher::default();
|
|
||||||
s.hash(&mut hasher);
|
|
||||||
hasher.finish()
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue