mirror of
https://codeberg.org/icewind/palantir.git
synced 2026-06-03 18:24:08 +02:00
io error context
This commit is contained in:
parent
a9356910c9
commit
8f3d2beb87
6 changed files with 65 additions and 33 deletions
21
src/lib.rs
21
src/lib.rs
|
|
@ -21,8 +21,8 @@ pub use win::{get_metrics, Sensors};
|
|||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("{1}: {0}")]
|
||||
Io(std::io::Error, &'static str),
|
||||
#[error("{1}: {0}")]
|
||||
Os(std::io::Error, &'static str),
|
||||
#[error("{0}")]
|
||||
|
|
@ -55,6 +55,10 @@ impl Error {
|
|||
let err = std::io::Error::last_os_error();
|
||||
Error::Os(err, context)
|
||||
}
|
||||
|
||||
pub fn io(context: &'static str, err: std::io::Error) -> Error {
|
||||
Error::Io(err, context)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FromUtf8Error> for Error {
|
||||
|
|
@ -86,7 +90,18 @@ pub trait MultiSensorSource {
|
|||
}
|
||||
|
||||
pub fn hostname() -> Result<String> {
|
||||
hostname::get()?
|
||||
hostname::get()
|
||||
.context("error getting hostname")?
|
||||
.into_string()
|
||||
.map_err(|_| Error::InvalidHostName)
|
||||
}
|
||||
|
||||
pub trait IoResultExt<T> {
|
||||
fn context(self, context: &'static str) -> Result<T, Error>;
|
||||
}
|
||||
|
||||
impl<T> IoResultExt<T> for Result<T, std::io::Error> {
|
||||
fn context(self, context: &'static str) -> Result<T, Error> {
|
||||
self.map_err(|e| Error::io(context, e))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::data::{DiskStats, DiskUsage};
|
||||
use crate::{Error, MultiSensorSource, Result};
|
||||
use crate::{Error, IoResultExt, MultiSensorSource, Result};
|
||||
use ahash::{AHashSet, AHasher};
|
||||
use regex::Regex;
|
||||
use std::ffi::CString;
|
||||
|
|
@ -20,7 +20,7 @@ pub struct DiskStatSource {
|
|||
impl DiskStatSource {
|
||||
pub fn new() -> Result<DiskStatSource> {
|
||||
Ok(DiskStatSource {
|
||||
source: File::open("/proc/diskstats")?,
|
||||
source: File::open("/proc/diskstats").context("error getting disk stats")?,
|
||||
buff: String::new(),
|
||||
regex: Regex::new(r" ([sv]d[a-z]+|nvme[0-9]n[0-9]|mmcblk[0-9]) ").unwrap(),
|
||||
})
|
||||
|
|
@ -33,8 +33,10 @@ impl MultiSensorSource for DiskStatSource {
|
|||
|
||||
fn read(&mut self) -> Result<Self::Iter<'_>> {
|
||||
self.buff.clear();
|
||||
self.source.rewind()?;
|
||||
self.source.read_to_string(&mut self.buff)?;
|
||||
self.source.rewind().context("error rewinding disk stats")?;
|
||||
self.source
|
||||
.read_to_string(&mut self.buff)
|
||||
.context("error reading disk stats")?;
|
||||
|
||||
Ok(DiskStatParser {
|
||||
lines: self.buff.lines(),
|
||||
|
|
@ -83,7 +85,7 @@ pub struct DiskUsageSource {
|
|||
impl DiskUsageSource {
|
||||
pub fn new() -> Result<DiskUsageSource> {
|
||||
Ok(DiskUsageSource {
|
||||
source: File::open("/proc/mounts")?,
|
||||
source: File::open("/proc/mounts").context("error opening mounts")?,
|
||||
buff: String::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -95,8 +97,10 @@ impl MultiSensorSource for DiskUsageSource {
|
|||
|
||||
fn read(&mut self) -> Result<Self::Iter<'_>> {
|
||||
self.buff.clear();
|
||||
self.source.rewind()?;
|
||||
self.source.read_to_string(&mut self.buff)?;
|
||||
self.source.rewind().context("error rewinding mounts")?;
|
||||
self.source
|
||||
.read_to_string(&mut self.buff)
|
||||
.context("error reading mounts")?;
|
||||
|
||||
Ok(DiskUsageParser {
|
||||
lines: self.buff.lines(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::linux::disk::DiskUsage;
|
||||
use crate::Result;
|
||||
use crate::{IoResultExt, Result};
|
||||
use std::fmt::Write;
|
||||
use std::fs::read_to_string;
|
||||
use std::process::Command;
|
||||
|
|
@ -23,7 +23,7 @@ pub fn pools() -> impl Iterator<Item = DiskUsage> {
|
|||
fn zpool_command() -> Result<String> {
|
||||
let mut z = Command::new("zpool");
|
||||
z.args(["list", "-p", "-H", "-o", "name,size,free"]);
|
||||
let out = z.output()?;
|
||||
let out = z.output().context("error getting zpool list")?;
|
||||
if out.status.success() {
|
||||
Ok(String::from_utf8(out.stdout)?)
|
||||
} else {
|
||||
|
|
@ -111,10 +111,10 @@ impl ArcStats {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn arcstats() -> Result<Option<ArcStats>> {
|
||||
pub fn arcstats() -> Option<ArcStats> {
|
||||
let content = match read_to_string("/proc/spl/kstat/zfs/arcstats") {
|
||||
Ok(c) => c,
|
||||
Err(_) => return Ok(None),
|
||||
Err(_) => return None,
|
||||
};
|
||||
let mut stats = ArcStats::default();
|
||||
|
||||
|
|
@ -150,5 +150,5 @@ pub fn arcstats() -> Result<Option<ArcStats>> {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(Some(stats))
|
||||
Some(stats)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ pub fn get_metrics(sensors: &Sensors) -> Result<String> {
|
|||
|
||||
cpu_power.write(&mut result, &sensors.hostname);
|
||||
gpu_power.write(&mut result, &sensors.hostname);
|
||||
if let Some(arc) = arcstats()? {
|
||||
if let Some(arc) = arcstats() {
|
||||
arc.write(&mut result, &sensors.hostname);
|
||||
}
|
||||
if let Some(memory) = gpu::memory() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::data::{CpuPowerUsage, GpuPowerUsage};
|
||||
use crate::linux::gpu::gpu_power;
|
||||
use crate::linux::hwmon::FileSource;
|
||||
use crate::{Result, SensorSource};
|
||||
use crate::{IoResultExt, Result, SensorSource};
|
||||
use std::fs::read_dir;
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -11,7 +11,8 @@ pub struct CpuPowerSource {
|
|||
|
||||
impl CpuPowerSource {
|
||||
pub fn new() -> Result<CpuPowerSource> {
|
||||
let sources: Vec<_> = read_dir("/sys/devices/virtual/powercap/intel-rapl")?
|
||||
let sources: Vec<_> = read_dir("/sys/devices/virtual/powercap/intel-rapl")
|
||||
.context("error listing power devices")?
|
||||
.flatten()
|
||||
.filter(|path| {
|
||||
path.file_name()
|
||||
|
|
@ -37,7 +38,7 @@ impl SensorSource for CpuPowerSource {
|
|||
fn read(&mut self) -> Result<Self::Data> {
|
||||
let mut usage = CpuPowerUsage::default();
|
||||
for source in self.sources.iter_mut() {
|
||||
let package_usage = source.read()?;
|
||||
let package_usage = source.read().context("error reading power source")?;
|
||||
usage.cpu_uj += package_usage;
|
||||
usage.cpu_packages_uj.push(package_usage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::data::{CpuTime, Memory, NetStats, Temperatures};
|
||||
use crate::linux::hwmon::{Device, FileSource};
|
||||
use crate::{Error, MultiSensorSource, Result, SensorSource};
|
||||
use crate::{Error, IoResultExt, MultiSensorSource, Result, SensorSource};
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{BufRead, BufReader, ErrorKind, Read, Seek};
|
||||
|
|
@ -23,7 +23,7 @@ impl TemperatureSource {
|
|||
{
|
||||
for sensor in device.sensors().flatten() {
|
||||
if sensor.name() == "Tdie" || sensor.name().starts_with("Core ") {
|
||||
cpu_sensors.push(sensor.reader()?);
|
||||
cpu_sensors.push(sensor.reader().context("error opening cpu temp sensor")?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ impl TemperatureSource {
|
|||
if device.name() == "amdgpu" || device.name() == "gpu_thermal" {
|
||||
for sensor in device.sensors().flatten() {
|
||||
if sensor.name() == "edge" {
|
||||
gpu_sensors.push(sensor.reader()?);
|
||||
gpu_sensors.push(sensor.reader().context("error opening gpu temp sensor")?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ pub struct MemorySource {
|
|||
impl MemorySource {
|
||||
pub fn new() -> Result<MemorySource> {
|
||||
Ok(MemorySource {
|
||||
source: File::open("/proc/meminfo")?,
|
||||
source: File::open("/proc/meminfo").context("error opening meminfo")?,
|
||||
buff: String::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -96,8 +96,10 @@ impl SensorSource for MemorySource {
|
|||
|
||||
fn read(&mut self) -> Result<Self::Data> {
|
||||
self.buff.clear();
|
||||
self.source.rewind()?;
|
||||
self.source.read_to_string(&mut self.buff)?;
|
||||
self.source.rewind().context("error rewdinging meminfo")?;
|
||||
self.source
|
||||
.read_to_string(&mut self.buff)
|
||||
.context("error reading meminfo")?;
|
||||
|
||||
let mut mem = Memory::default();
|
||||
for line in self.buff.lines() {
|
||||
|
|
@ -127,7 +129,7 @@ pub struct CpuTimeSource {
|
|||
impl CpuTimeSource {
|
||||
pub fn new() -> Result<CpuTimeSource> {
|
||||
Ok(CpuTimeSource {
|
||||
source: BufReader::new(File::open("/proc/stat")?),
|
||||
source: BufReader::new(File::open("/proc/stat").context("error opening proc stats")?),
|
||||
buff: Vec::new(),
|
||||
cpu_count: sysconf(SysconfVariable::ScNprocessorsOnln)? as f32,
|
||||
})
|
||||
|
|
@ -139,9 +141,11 @@ impl SensorSource for CpuTimeSource {
|
|||
|
||||
fn read(&mut self) -> Result<Self::Data> {
|
||||
self.buff.clear();
|
||||
self.source.rewind()?;
|
||||
self.source.rewind().context("error rewinding proc")?;
|
||||
|
||||
self.source.read_until(b'\n', &mut self.buff)?;
|
||||
self.source
|
||||
.read_until(b'\n', &mut self.buff)
|
||||
.context("error reading proc")?;
|
||||
|
||||
let line = std::str::from_utf8(&self.buff)?;
|
||||
|
||||
|
|
@ -156,7 +160,10 @@ impl SensorSource for CpuTimeSource {
|
|||
(user + system) / (clock_ticks as f32) / self.cpu_count,
|
||||
))
|
||||
} else {
|
||||
Err(io::Error::from(ErrorKind::InvalidData).into())
|
||||
Err(Error::io(
|
||||
"invalid proc data",
|
||||
io::Error::from(ErrorKind::InvalidData),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -169,7 +176,7 @@ pub struct NetworkSource {
|
|||
impl NetworkSource {
|
||||
pub fn new() -> Result<NetworkSource> {
|
||||
Ok(NetworkSource {
|
||||
source: File::open("/proc/net/dev")?,
|
||||
source: File::open("/proc/net/dev").context("error opening netdev")?,
|
||||
buff: String::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -205,7 +212,10 @@ impl NetworkSource {
|
|||
bytes_received: bytes_received.parse()?,
|
||||
})
|
||||
} else {
|
||||
Err(Error::Io(ErrorKind::InvalidData.into()))
|
||||
Err(Error::io(
|
||||
"error reading netdev",
|
||||
ErrorKind::InvalidData.into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -216,8 +226,10 @@ impl MultiSensorSource for NetworkSource {
|
|||
|
||||
fn read(&mut self) -> Result<Self::Iter<'_>> {
|
||||
self.buff.clear();
|
||||
self.source.rewind()?;
|
||||
self.source.read_to_string(&mut self.buff)?;
|
||||
self.source.rewind().context("error rewinding netdev")?;
|
||||
self.source
|
||||
.read_to_string(&mut self.buff)
|
||||
.context("error reading netdev")?;
|
||||
|
||||
Ok(NetworkStatParser {
|
||||
lines: self.buff.lines(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue