mirror of
https://codeberg.org/icewind/palantir.git
synced 2026-06-03 18:24:08 +02:00
sync memory and temperatures
This commit is contained in:
parent
5544b9984a
commit
14817cf422
4 changed files with 80 additions and 40 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
use iai::black_box;
|
use iai::black_box;
|
||||||
use palantir::get_metrics;
|
use palantir::get_metrics;
|
||||||
use palantir::heim::temperatures;
|
use palantir::sensors::temperatures;
|
||||||
use palantir::zfs::pools;
|
use palantir::zfs::pools;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
|
|
@ -14,8 +14,7 @@ fn iai_zfs_pool() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iai_temperatures() {
|
fn iai_temperatures() {
|
||||||
let rt = Runtime::new().unwrap();
|
black_box(temperatures()).unwrap();
|
||||||
rt.block_on(async { black_box(temperatures().await).unwrap() });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iai::main!(iai_get_metrics, iai_zfs_pool, iai_temperatures);
|
iai::main!(iai_get_metrics, iai_zfs_pool, iai_temperatures);
|
||||||
|
|
|
||||||
11
src/lib.rs
11
src/lib.rs
|
|
@ -1,7 +1,8 @@
|
||||||
pub mod heim;
|
pub mod sensors;
|
||||||
pub mod zfs;
|
pub mod zfs;
|
||||||
|
|
||||||
use crate::heim::*;
|
use crate::sensors::temperatures;
|
||||||
|
use crate::sensors::*;
|
||||||
use crate::zfs::pools;
|
use crate::zfs::pools;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use futures_util::stream::StreamExt;
|
use futures_util::stream::StreamExt;
|
||||||
|
|
@ -10,15 +11,15 @@ 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 (hostname, cpu, memory, network, temperatures, disks, disk_usage) = try_join! {
|
let (hostname, cpu, network, disks, disk_usage) = try_join! {
|
||||||
hostname(),
|
hostname(),
|
||||||
cpu_time(),
|
cpu_time(),
|
||||||
memory(),
|
|
||||||
network_stats(),
|
network_stats(),
|
||||||
temperatures(),
|
|
||||||
disk_stats(),
|
disk_stats(),
|
||||||
disk_usage(),
|
disk_usage(),
|
||||||
}?;
|
}?;
|
||||||
|
let memory = memory()?;
|
||||||
|
let temperatures = temperatures()?;
|
||||||
let pools = pools();
|
let pools = pools();
|
||||||
pin_mut!(network);
|
pin_mut!(network);
|
||||||
pin_mut!(disks);
|
pin_mut!(disks);
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
use color_eyre::eyre::WrapErr;
|
|
||||||
use color_eyre::Result;
|
use color_eyre::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::cpu::time;
|
||||||
use heim::disk::{FileSystem, Partition};
|
use heim::disk::{FileSystem, Partition};
|
||||||
use heim::sensors::TemperatureSensor;
|
use heim::units::{information, time};
|
||||||
use heim::units::{information, thermodynamic_temperature, time};
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use parse_display::Display;
|
use parse_display::Display;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fs::{read, read_dir, read_to_string, DirEntry, File};
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, Display)]
|
#[derive(Debug, Clone, Hash, Eq, PartialEq, Display)]
|
||||||
#[display(style = "lowercase")]
|
#[display(style = "lowercase")]
|
||||||
|
|
@ -17,7 +18,7 @@ pub enum TemperatureLabel {
|
||||||
CPU,
|
CPU,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct Memory {
|
pub struct Memory {
|
||||||
pub total: u64,
|
pub total: u64,
|
||||||
pub free: u64,
|
pub free: u64,
|
||||||
|
|
@ -38,36 +39,75 @@ pub struct DiskUsage {
|
||||||
pub free: u64,
|
pub free: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn temperatures() -> Result<HashMap<TemperatureLabel, f32>> {
|
pub fn temperatures() -> Result<HashMap<TemperatureLabel, f32>> {
|
||||||
// ugly workaround problems between async-fs and tokio
|
Ok(read_dir("/sys/class/hwmon")?
|
||||||
let results = tokio::task::spawn_blocking(|| {
|
.filter_map(Result::ok)
|
||||||
futures_lite::future::block_on(
|
.filter_map(|dir: DirEntry| {
|
||||||
heim::sensors::temperatures().collect::<Vec<Result<TemperatureSensor, heim::Error>>>(),
|
let name = read(dir.path().join("name")).ok()?;
|
||||||
|
match name.as_slice() {
|
||||||
|
b"k10temp\n" => Some((name, dir)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.flat_map(|(name, dir)| {
|
||||||
|
read_dir(dir.path())
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(|dir| dir)
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.filter_map(move |item: DirEntry| {
|
||||||
|
let file_name = item.file_name();
|
||||||
|
let bytes = file_name.as_bytes();
|
||||||
|
if bytes.starts_with(b"temp") && bytes.ends_with(b"_label") {
|
||||||
|
let label = read(item.path()).ok()?;
|
||||||
|
Some((name.clone(), label, item))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.filter_map(
|
||||||
|
|(name, label, item)| match (name.as_slice(), label.as_slice()) {
|
||||||
|
(b"k10temp\n", b"Tdie\n") => Some((TemperatureLabel::CPU, item)),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
})
|
.filter_map(|(label, item)| {
|
||||||
.await
|
let path = item.path().into_os_string();
|
||||||
.wrap_err("Failed to resolve future")?
|
Some((label, path.into_string().ok()?))
|
||||||
.into_iter()
|
})
|
||||||
.filter_map(|result| result.ok())
|
.filter_map(|(label, mut path)| {
|
||||||
.filter_map(|sensor| match (sensor.unit(), sensor.label()) {
|
path.truncate(path.len() - "label".len());
|
||||||
("k10temp", Some("Tdie")) => Some((
|
path.push_str("input");
|
||||||
TemperatureLabel::CPU,
|
let value = read_to_string(path).ok()?;
|
||||||
sensor
|
let parsed: u32 = value.trim().parse().ok()?;
|
||||||
.current()
|
Some((label, parsed as f32 / 1000.0))
|
||||||
.get::<thermodynamic_temperature::degree_celsius>(),
|
})
|
||||||
)),
|
.collect())
|
||||||
_ => None,
|
|
||||||
});
|
|
||||||
Ok(results.collect())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn memory() -> Result<Memory> {
|
pub fn memory() -> Result<Memory> {
|
||||||
let memory = heim::memory::memory().await?;
|
let mut meminfo = BufReader::new(File::open("/proc/meminfo")?);
|
||||||
Ok(Memory {
|
let mut mem = Memory::default();
|
||||||
total: memory.total().get::<information::byte>(),
|
let mut line = String::new();
|
||||||
free: memory.free().get::<information::byte>(),
|
loop {
|
||||||
available: memory.available().get::<information::byte>(),
|
line.clear();
|
||||||
})
|
meminfo.read_line(&mut line)?;
|
||||||
|
if line.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if let Some(line) = line.strip_suffix(" kB") {
|
||||||
|
if let Some(line_total) = line.strip_prefix("MemTotal: ") {
|
||||||
|
mem.total = line_total.trim().parse()?;
|
||||||
|
}
|
||||||
|
if let Some(line_free) = line.strip_prefix("MemFree: ") {
|
||||||
|
mem.free = line_free.trim().parse()?;
|
||||||
|
}
|
||||||
|
if let Some(line_available) = line.strip_prefix("MemAvailable: ") {
|
||||||
|
mem.available = line_available.trim().parse()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(mem)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cpu_time() -> Result<f64> {
|
pub async fn cpu_time() -> Result<f64> {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::heim::DiskUsage;
|
use crate::sensors::DiskUsage;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue