mirror of
https://codeberg.org/icewind/palantir.git
synced 2026-06-03 18:24:08 +02:00
prepare for windows impl
This commit is contained in:
parent
f363cac81d
commit
d12b70d11e
16 changed files with 550 additions and 279 deletions
131
src/data.rs
Normal file
131
src/data.rs
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
use crate::SensorData;
|
||||
use std::array::IntoIter;
|
||||
use std::fmt::Write;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Temperatures {
|
||||
pub cpu: f32,
|
||||
pub gpu: f32,
|
||||
}
|
||||
|
||||
impl IntoIterator for Temperatures {
|
||||
type Item = (&'static str, f32);
|
||||
type IntoIter = IntoIter<Self::Item, 2>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
[("cpu", self.cpu), ("gpu", self.gpu)].into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl SensorData for Temperatures {
|
||||
fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
for (label, temp) in self.clone() {
|
||||
if temp != 0.0 {
|
||||
writeln!(
|
||||
&mut w,
|
||||
"temperature{{host=\"{}\", sensor=\"{}\"}} {:.1}",
|
||||
hostname, label, temp
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Memory {
|
||||
pub total: u64,
|
||||
pub free: u64,
|
||||
pub available: u64,
|
||||
}
|
||||
|
||||
impl SensorData for Memory {
|
||||
fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
writeln!(
|
||||
&mut w,
|
||||
"memory_total{{host=\"{}\"}} {}",
|
||||
hostname, self.total
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
&mut w,
|
||||
"memory_available{{host=\"{}\"}} {}",
|
||||
hostname, self.available
|
||||
)
|
||||
.ok();
|
||||
writeln!(&mut w, "memory_free{{host=\"{}\"}} {}", hostname, self.free).ok();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct GpuMemory {
|
||||
pub total: u64,
|
||||
pub free: u64,
|
||||
}
|
||||
|
||||
impl SensorData for GpuMemory {
|
||||
fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
writeln!(
|
||||
&mut w,
|
||||
"gpu_memory_total{{host=\"{}\"}} {}",
|
||||
hostname, self.total
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
&mut w,
|
||||
"gpu_memory_free{{host=\"{}\"}} {}",
|
||||
hostname, self.free
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CpuTime(pub f32);
|
||||
|
||||
impl SensorData for CpuTime {
|
||||
fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
writeln!(w, "cpu_time{{host=\"{}\"}} {:.3}", hostname, self.0).ok();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct NetStats {
|
||||
pub interface: String,
|
||||
pub bytes_sent: u64,
|
||||
pub bytes_received: u64,
|
||||
}
|
||||
|
||||
impl SensorData for NetStats {
|
||||
fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
if self.bytes_received > 0 || self.bytes_sent > 0 {
|
||||
writeln!(
|
||||
&mut w,
|
||||
"net_sent{{host=\"{}\", network=\"{}\"}} {}",
|
||||
hostname, self.interface, self.bytes_sent
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
&mut w,
|
||||
"net_received{{host=\"{}\", network=\"{}\"}} {}",
|
||||
hostname, self.interface, self.bytes_received
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GpuUsage {
|
||||
pub system: &'static str,
|
||||
pub usage: u32,
|
||||
}
|
||||
|
||||
impl GpuUsage {
|
||||
pub fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
writeln!(
|
||||
&mut w,
|
||||
r#"gpu_usage{{host="{}", system="{}"}} {:.3}"#,
|
||||
hostname, self.system, self.usage,
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
129
src/lib.rs
129
src/lib.rs
|
|
@ -1,27 +1,28 @@
|
|||
pub mod disk;
|
||||
pub mod docker;
|
||||
pub mod gpu;
|
||||
pub mod hwmon;
|
||||
pub mod power;
|
||||
pub mod sensors;
|
||||
|
||||
use crate::disk::zfs::pools;
|
||||
use crate::disk::*;
|
||||
use crate::sensors::*;
|
||||
use std::ffi::NulError;
|
||||
use std::fmt::Write;
|
||||
use std::io;
|
||||
use std::num::{ParseFloatError, ParseIntError};
|
||||
use std::str::Utf8Error;
|
||||
use std::sync::Mutex;
|
||||
use sysconf::SysconfError;
|
||||
use std::string::FromUtf8Error;
|
||||
|
||||
pub mod data;
|
||||
pub mod docker;
|
||||
|
||||
#[cfg(not(feature = "sysinfo"))]
|
||||
mod linux;
|
||||
#[cfg(feature = "sysinfo")]
|
||||
mod sys;
|
||||
|
||||
#[cfg(not(feature = "sysinfo"))]
|
||||
pub use linux::{get_metrics, Sensors};
|
||||
#[cfg(feature = "sysinfo")]
|
||||
pub use sys::{get_metrics, Sensors};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
#[error("Unsupported sysconf")]
|
||||
Sysconf(SysconfError),
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("{0}")]
|
||||
Other(String),
|
||||
#[error("Non UTF8 hostname")]
|
||||
InvalidHostName,
|
||||
#[error(transparent)]
|
||||
|
|
@ -36,98 +37,14 @@ pub enum Error {
|
|||
StatVfs,
|
||||
}
|
||||
|
||||
impl From<SysconfError> for Error {
|
||||
fn from(value: SysconfError) -> Self {
|
||||
Error::Sysconf(value)
|
||||
impl From<FromUtf8Error> for Error {
|
||||
fn from(err: FromUtf8Error) -> Self {
|
||||
Self::InvalidStringData(err.utf8_error())
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
||||
pub struct Sensors {
|
||||
pub hostname: String,
|
||||
cpu: Mutex<CpuTimeSource>,
|
||||
temp: Mutex<TemperatureSource>,
|
||||
net: Mutex<NetworkSource>,
|
||||
mem: Mutex<MemorySource>,
|
||||
disk_stats: Mutex<DiskStatSource>,
|
||||
disk_usage: Mutex<DiskUsageSource>,
|
||||
}
|
||||
|
||||
impl Sensors {
|
||||
pub fn new() -> Result<Sensors> {
|
||||
Ok(Sensors {
|
||||
hostname: hostname()?,
|
||||
cpu: Mutex::new(CpuTimeSource::new()?),
|
||||
temp: Mutex::new(TemperatureSource::new()?),
|
||||
net: Mutex::new(NetworkSource::new()?),
|
||||
mem: Mutex::new(MemorySource::new()?),
|
||||
disk_stats: Mutex::new(DiskStatSource::new()?),
|
||||
disk_usage: Mutex::new(DiskUsageSource::new()?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_metrics(sensors: &Sensors) -> Result<String> {
|
||||
let hostname = &sensors.hostname;
|
||||
let mut disk_source = sensors.disk_stats.lock().unwrap();
|
||||
let mut disk_usage_source = sensors.disk_usage.lock().unwrap();
|
||||
let disks = disk_source.read()?;
|
||||
let disk_usage = disk_usage_source.read()?;
|
||||
let cpu = sensors.cpu.lock().unwrap().read()?;
|
||||
let memory = sensors.mem.lock().unwrap().read()?;
|
||||
let temperatures = sensors.temp.lock().unwrap().read()?;
|
||||
let mut net = sensors.net.lock().unwrap();
|
||||
let networks = net.read()?;
|
||||
let pools = pools();
|
||||
let mut result = String::with_capacity(256);
|
||||
|
||||
cpu.write(&mut result, &hostname);
|
||||
memory.write(&mut result, &hostname);
|
||||
|
||||
for pool in pools {
|
||||
writeln!(
|
||||
&mut result,
|
||||
"zfs_pool_size{{host=\"{}\", pool=\"{}\"}} {}",
|
||||
hostname, pool.name, pool.size
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
&mut result,
|
||||
"zfs_pool_free{{host=\"{}\", pool=\"{}\"}} {}",
|
||||
hostname, pool.name, pool.free
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
for network in networks {
|
||||
if let Ok(network) = network {
|
||||
network.write(&mut result, &hostname);
|
||||
}
|
||||
}
|
||||
for disk in disks {
|
||||
if let Ok(disk) = disk {
|
||||
disk.write(&mut result, hostname);
|
||||
}
|
||||
}
|
||||
|
||||
for disk in disk_usage {
|
||||
if let Ok(disk) = disk {
|
||||
disk.write(&mut result, hostname);
|
||||
}
|
||||
}
|
||||
for (label, temp) in temperatures {
|
||||
if temp != 0.0 {
|
||||
writeln!(
|
||||
&mut result,
|
||||
"temperature{{host=\"{}\", sensor=\"{}\"}} {:.1}",
|
||||
hostname, label, temp
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub trait SensorData {
|
||||
/// Write sensor data in prometheus compatible format
|
||||
fn write<W: Write>(&self, w: W, hostname: &str);
|
||||
|
|
@ -147,3 +64,9 @@ pub trait MultiSensorSource {
|
|||
|
||||
fn read(&mut self) -> Result<Self::Iter<'_>>;
|
||||
}
|
||||
|
||||
pub fn hostname() -> Result<String> {
|
||||
hostname::get()?
|
||||
.into_string()
|
||||
.map_err(|_| Error::InvalidHostName)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::disk::DiskUsage;
|
||||
use color_eyre::Result;
|
||||
use crate::linux::disk::DiskUsage;
|
||||
use crate::Result;
|
||||
use std::fmt::Write;
|
||||
use std::fs::read_to_string;
|
||||
use std::process::Command;
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
use crate::hwmon::FileSource;
|
||||
use crate::sensors::Memory;
|
||||
use std::fmt::Write;
|
||||
use crate::data::{GpuMemory, GpuUsage};
|
||||
use crate::linux::hwmon::FileSource;
|
||||
use std::fs::read_to_string;
|
||||
use std::str::FromStr;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
|
@ -10,61 +9,23 @@ use std::time::{Duration, Instant};
|
|||
|
||||
pub mod nvidia;
|
||||
|
||||
pub fn gpu_metrics<W: Write>(mut out: W, hostname: &str) {
|
||||
if let Some(memory) = memory() {
|
||||
writeln!(
|
||||
&mut out,
|
||||
"gpu_memory_total{{host=\"{}\"}} {}",
|
||||
hostname, memory.total
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
&mut out,
|
||||
"gpu_memory_free{{host=\"{}\"}} {}",
|
||||
hostname, memory.free
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
|
||||
for usage in utilization() {
|
||||
usage.write(&mut out, hostname);
|
||||
}
|
||||
}
|
||||
|
||||
fn read_num<T: FromStr>(path: &str) -> Option<T> {
|
||||
read_to_string(path).ok()?.trim().parse().ok()
|
||||
}
|
||||
|
||||
pub fn memory() -> Option<Memory> {
|
||||
pub fn memory() -> Option<GpuMemory> {
|
||||
if let Some(nv_mem) = nvidia::memory() {
|
||||
return Some(nv_mem);
|
||||
}
|
||||
// 1 gpu should be enough for everyone
|
||||
let used = read_num::<u64>("/sys/class/drm/card0/device/mem_info_vram_used")?;
|
||||
let total = read_num("/sys/class/drm/card0/device/mem_info_vram_total")?;
|
||||
Some(Memory {
|
||||
Some(GpuMemory {
|
||||
total,
|
||||
free: total - used,
|
||||
available: total - used,
|
||||
})
|
||||
}
|
||||
|
||||
pub struct GpuUsage {
|
||||
pub system: &'static str,
|
||||
pub usage: u32,
|
||||
}
|
||||
|
||||
impl GpuUsage {
|
||||
pub fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
writeln!(
|
||||
&mut w,
|
||||
r#"gpu_usage{{host="{}", system="{}"}} {:.3}"#,
|
||||
hostname, self.system, self.usage,
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn utilization() -> impl Iterator<Item = GpuUsage> {
|
||||
let nv_usage = nvidia::utilization();
|
||||
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
use crate::gpu::GpuUsage;
|
||||
use crate::sensors::Memory;
|
||||
use crate::data::{GpuMemory, GpuUsage};
|
||||
use nvml_wrapper::enum_wrappers::device::TemperatureSensor;
|
||||
use nvml_wrapper::{Device, Nvml};
|
||||
use once_cell::sync::Lazy;
|
||||
|
|
@ -22,12 +21,11 @@ pub fn power() -> Option<u64> {
|
|||
.map(|mj| mj * 1_000)
|
||||
}
|
||||
|
||||
pub fn memory() -> Option<Memory> {
|
||||
pub fn memory() -> Option<GpuMemory> {
|
||||
let mem = device()?.memory_info().ok()?;
|
||||
Some(Memory {
|
||||
Some(GpuMemory {
|
||||
total: mem.total,
|
||||
free: mem.free,
|
||||
available: mem.free,
|
||||
})
|
||||
}
|
||||
|
||||
123
src/linux/mod.rs
Normal file
123
src/linux/mod.rs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
pub mod disk;
|
||||
pub mod gpu;
|
||||
pub mod hwmon;
|
||||
pub mod power;
|
||||
pub mod sensors;
|
||||
|
||||
use self::disk::zfs::pools;
|
||||
use self::disk::*;
|
||||
use self::sensors::*;
|
||||
use crate::linux::disk::zfs::arcstats;
|
||||
use crate::linux::gpu::{update_gpu_power, utilization};
|
||||
use crate::linux::power::power_usage;
|
||||
use crate::{hostname, Error, MultiSensorSource, Result, SensorData, SensorSource};
|
||||
use std::fmt::Write;
|
||||
use std::sync::Mutex;
|
||||
use sysconf::SysconfError;
|
||||
|
||||
impl From<SysconfError> for Error {
|
||||
fn from(_: SysconfError) -> Self {
|
||||
Error::Other("Unsupported sysconf".into())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Sensors {
|
||||
pub hostname: String,
|
||||
cpu: Mutex<CpuTimeSource>,
|
||||
temp: Mutex<TemperatureSource>,
|
||||
net: Mutex<NetworkSource>,
|
||||
mem: Mutex<MemorySource>,
|
||||
disk_stats: Mutex<DiskStatSource>,
|
||||
disk_usage: Mutex<DiskUsageSource>,
|
||||
}
|
||||
|
||||
impl Sensors {
|
||||
pub fn new() -> Result<Sensors> {
|
||||
std::thread::spawn(update_gpu_power);
|
||||
|
||||
Ok(Sensors {
|
||||
hostname: hostname()?,
|
||||
cpu: Mutex::new(CpuTimeSource::new()?),
|
||||
temp: Mutex::new(TemperatureSource::new()?),
|
||||
net: Mutex::new(NetworkSource::new()?),
|
||||
mem: Mutex::new(MemorySource::new()?),
|
||||
disk_stats: Mutex::new(DiskStatSource::new()?),
|
||||
disk_usage: Mutex::new(DiskUsageSource::new()?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_metrics(sensors: &Sensors) -> Result<String> {
|
||||
let hostname = &sensors.hostname;
|
||||
let mut disk_source = sensors.disk_stats.lock().unwrap();
|
||||
let mut disk_usage_source = sensors.disk_usage.lock().unwrap();
|
||||
let disks = disk_source.read()?;
|
||||
let disk_usage = disk_usage_source.read()?;
|
||||
let cpu = sensors.cpu.lock().unwrap().read()?;
|
||||
let memory = sensors.mem.lock().unwrap().read()?;
|
||||
let temperatures = sensors.temp.lock().unwrap().read()?;
|
||||
let mut net = sensors.net.lock().unwrap();
|
||||
let networks = net.read()?;
|
||||
let pools = pools();
|
||||
let mut result = String::with_capacity(256);
|
||||
|
||||
cpu.write(&mut result, &hostname);
|
||||
memory.write(&mut result, &hostname);
|
||||
|
||||
for pool in pools {
|
||||
writeln!(
|
||||
&mut result,
|
||||
"zfs_pool_size{{host=\"{}\", pool=\"{}\"}} {}",
|
||||
hostname, pool.name, pool.size
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
&mut result,
|
||||
"zfs_pool_free{{host=\"{}\", pool=\"{}\"}} {}",
|
||||
hostname, pool.name, pool.free
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
for network in networks {
|
||||
if let Ok(network) = network {
|
||||
network.write(&mut result, &hostname);
|
||||
}
|
||||
}
|
||||
for disk in disks {
|
||||
if let Ok(disk) = disk {
|
||||
disk.write(&mut result, hostname);
|
||||
}
|
||||
}
|
||||
|
||||
for disk in disk_usage {
|
||||
if let Ok(disk) = disk {
|
||||
disk.write(&mut result, hostname);
|
||||
}
|
||||
}
|
||||
for (label, temp) in temperatures {
|
||||
if temp != 0.0 {
|
||||
writeln!(
|
||||
&mut result,
|
||||
"temperature{{host=\"{}\", sensor=\"{}\"}} {:.1}",
|
||||
hostname, label, temp
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(power) = power_usage()? {
|
||||
power.write(&mut result, &sensors.hostname);
|
||||
}
|
||||
if let Some(arc) = arcstats()? {
|
||||
arc.write(&mut result, &sensors.hostname);
|
||||
}
|
||||
if let Some(memory) = gpu::memory() {
|
||||
memory.write(&mut result, &sensors.hostname)
|
||||
}
|
||||
|
||||
for usage in utilization() {
|
||||
usage.write(&mut result, &sensors.hostname);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::gpu::gpu_power;
|
||||
use color_eyre::{Report, Result};
|
||||
use crate::linux::gpu::gpu_power;
|
||||
use crate::{Error, Result};
|
||||
use std::fmt::Write;
|
||||
use std::fs::{read_dir, read_to_string};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
|
@ -63,7 +63,7 @@ pub fn power_usage() -> Result<Option<PowerUsage>> {
|
|||
if package
|
||||
.file_name()
|
||||
.to_str()
|
||||
.ok_or_else(|| Report::msg("Invalid name"))?
|
||||
.ok_or_else(|| Error::Other("Invalid name".into()))?
|
||||
.starts_with("intel-rapl")
|
||||
{
|
||||
let mut package_path = package.path();
|
||||
|
|
@ -86,7 +86,7 @@ pub fn power_usage() -> Result<Option<PowerUsage>> {
|
|||
}
|
||||
|
||||
usage.gpu_uj = gpu_power();
|
||||
if let Some(nvidia_power) = crate::gpu::nvidia::power() {
|
||||
if let Some(nvidia_power) = crate::linux::gpu::nvidia::power() {
|
||||
usage.gpu_uj = nvidia_power;
|
||||
}
|
||||
|
||||
|
|
@ -1,67 +1,11 @@
|
|||
use crate::hwmon::{Device, FileSource};
|
||||
use crate::{Error, MultiSensorSource, Result, SensorData, SensorSource};
|
||||
use std::array::IntoIter;
|
||||
use std::fmt::Write;
|
||||
use crate::data::{CpuTime, Memory, NetStats, Temperatures};
|
||||
use crate::linux::hwmon::{Device, FileSource};
|
||||
use crate::{Error, MultiSensorSource, Result, SensorSource};
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{BufRead, BufReader, ErrorKind, Read, Seek};
|
||||
use sysconf::{sysconf, SysconfVariable};
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Temperatures {
|
||||
cpu: f32,
|
||||
gpu: f32,
|
||||
}
|
||||
|
||||
impl IntoIterator for Temperatures {
|
||||
type Item = (&'static str, f32);
|
||||
type IntoIter = IntoIter<Self::Item, 2>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
[("cpu", self.cpu), ("gpu", self.gpu)].into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl SensorData for Temperatures {
|
||||
fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
for (label, temp) in self.clone() {
|
||||
if temp != 0.0 {
|
||||
writeln!(
|
||||
&mut w,
|
||||
"temperature{{host=\"{}\", sensor=\"{}\"}} {:.1}",
|
||||
hostname, label, temp
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Memory {
|
||||
pub total: u64,
|
||||
pub free: u64,
|
||||
pub available: u64,
|
||||
}
|
||||
|
||||
impl SensorData for Memory {
|
||||
fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
writeln!(
|
||||
&mut w,
|
||||
"memory_total{{host=\"{}\"}} {}",
|
||||
hostname, self.total
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
&mut w,
|
||||
"memory_available{{host=\"{}\"}} {}",
|
||||
hostname, self.available
|
||||
)
|
||||
.ok();
|
||||
writeln!(&mut w, "memory_free{{host=\"{}\"}} {}", hostname, self.free).ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TemperatureSource {
|
||||
cpu_sensors: Vec<FileSource>,
|
||||
gpu_sensors: Vec<FileSource>,
|
||||
|
|
@ -117,10 +61,16 @@ impl SensorSource for TemperatureSource {
|
|||
type Data = Temperatures;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Data> {
|
||||
Ok(Temperatures {
|
||||
let mut result = Temperatures {
|
||||
cpu: average_sensors(&mut self.cpu_sensors) / 1000.0,
|
||||
gpu: average_sensors(&mut self.gpu_sensors) / 1000.0,
|
||||
})
|
||||
};
|
||||
|
||||
if let Some(gpu) = super::gpu::nvidia::temperature() {
|
||||
result.gpu = gpu;
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,14 +115,6 @@ impl SensorSource for MemorySource {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct CpuTime(f32);
|
||||
|
||||
impl SensorData for CpuTime {
|
||||
fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
writeln!(w, "cpu_time{{host=\"{}\"}} {:.3}", hostname, self.0).ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CpuTimeSource {
|
||||
source: BufReader<File>,
|
||||
buff: Vec<u8>,
|
||||
|
|
@ -216,32 +158,6 @@ impl SensorSource for CpuTimeSource {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct NetStats {
|
||||
pub interface: String,
|
||||
pub bytes_sent: u64,
|
||||
pub bytes_received: u64,
|
||||
}
|
||||
|
||||
impl SensorData for NetStats {
|
||||
fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||
if self.bytes_received > 0 || self.bytes_sent > 0 {
|
||||
writeln!(
|
||||
&mut w,
|
||||
"net_sent{{host=\"{}\", network=\"{}\"}} {}",
|
||||
hostname, self.interface, self.bytes_sent
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
&mut w,
|
||||
"net_received{{host=\"{}\", network=\"{}\"}} {}",
|
||||
hostname, self.interface, self.bytes_received
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NetworkSource {
|
||||
source: File,
|
||||
buff: String,
|
||||
|
|
@ -326,9 +242,3 @@ impl<'a> Iterator for NetworkStatParser<'a> {
|
|||
Some(NetworkSource::parse_line(line))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hostname() -> Result<String> {
|
||||
hostname::get()?
|
||||
.into_string()
|
||||
.map_err(|_| Error::InvalidHostName)
|
||||
}
|
||||
12
src/main.rs
12
src/main.rs
|
|
@ -3,10 +3,7 @@ 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::gpu::{gpu_metrics, update_gpu_power};
|
||||
use palantir::power::power_usage;
|
||||
use palantir::{get_metrics, Sensors};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
|
@ -39,13 +36,6 @@ async fn serve_inner(docker: Option<Docker>, sensors: &Sensors) -> Result<String
|
|||
container.write(&mut metrics, &sensors.hostname);
|
||||
}
|
||||
}
|
||||
if let Some(power) = power_usage()? {
|
||||
power.write(&mut metrics, &sensors.hostname);
|
||||
}
|
||||
if let Some(arc) = arcstats()? {
|
||||
arc.write(&mut metrics, &sensors.hostname);
|
||||
}
|
||||
gpu_metrics(&mut metrics, &sensors.hostname);
|
||||
|
||||
Ok(metrics)
|
||||
}
|
||||
|
|
@ -86,8 +76,6 @@ async fn main() -> Result<()> {
|
|||
));
|
||||
}
|
||||
|
||||
std::thread::spawn(update_gpu_power);
|
||||
|
||||
let metrics = warp::path!("metrics")
|
||||
.and(docker)
|
||||
.and(sensors)
|
||||
|
|
|
|||
33
src/sys/mod.rs
Normal file
33
src/sys/mod.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
use crate::data::Temperatures;
|
||||
use crate::hostname;
|
||||
use crate::Result;
|
||||
use std::fmt::Write;
|
||||
use sysinfo::{ComponentExt, System, SystemExt};
|
||||
|
||||
pub struct Sensors {
|
||||
pub hostname: String,
|
||||
}
|
||||
|
||||
impl Sensors {
|
||||
pub fn new() -> Result<Sensors> {
|
||||
let s = System::new_all();
|
||||
for component in s.components() {
|
||||
println!("{} :{}°C", component.label(), component.temperature());
|
||||
}
|
||||
|
||||
Ok(Sensors {
|
||||
hostname: hostname()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn temps() -> Temperatures {
|
||||
Temperatures { cpu: 0.0, gpu: 0.0 }
|
||||
}
|
||||
|
||||
pub fn get_metrics(sensors: &Sensors) -> Result<String> {
|
||||
let hostname = &sensors.hostname;
|
||||
let mut result = String::with_capacity(256);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue