mirror of
https://codeberg.org/icewind/palantir.git
synced 2026-06-03 10:14:09 +02:00
network sensor
This commit is contained in:
parent
5dd7380e2b
commit
f06b8ab698
5 changed files with 495 additions and 423 deletions
749
Cargo.lock
generated
749
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
# `nix develop`
|
# `nix develop`
|
||||||
devShell = pkgs.mkShell {
|
devShell = pkgs.mkShell {
|
||||||
nativeBuildInputs = with pkgs; [rustc cargo bacon];
|
nativeBuildInputs = with pkgs; [cargo bacon];
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
// {
|
// {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Result, SensorData};
|
||||||
use ahash::{AHashSet, AHasher};
|
use ahash::{AHashSet, AHasher};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::fmt::Write;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
|
|
@ -17,6 +18,25 @@ pub struct IoStats {
|
||||||
pub bytes_received: u64,
|
pub bytes_received: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SensorData for IoStats {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DiskUsage {
|
pub struct DiskUsage {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
||||||
27
src/lib.rs
27
src/lib.rs
|
|
@ -53,8 +53,9 @@ pub fn get_metrics() -> Result<String> {
|
||||||
let memory = memory()?;
|
let memory = memory()?;
|
||||||
let mut temp_source = TemperatureSource::new()?;
|
let mut temp_source = TemperatureSource::new()?;
|
||||||
let temperatures = temp_source.read()?;
|
let temperatures = temp_source.read()?;
|
||||||
|
let mut net_source = NetworkSource::new()?;
|
||||||
|
let networks = net_source.read()?;
|
||||||
let pools = pools();
|
let pools = pools();
|
||||||
let networks = network_stats()?;
|
|
||||||
let mut result = String::with_capacity(256);
|
let mut result = String::with_capacity(256);
|
||||||
|
|
||||||
cpu.write(&mut result, &hostname);
|
cpu.write(&mut result, &hostname);
|
||||||
|
|
@ -75,19 +76,8 @@ pub fn get_metrics() -> Result<String> {
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
for network in networks {
|
for network in networks {
|
||||||
if network.bytes_received > 0 || network.bytes_sent > 0 {
|
if let Ok(network) = network {
|
||||||
writeln!(
|
network.write(&mut result, &hostname);
|
||||||
&mut result,
|
|
||||||
"net_sent{{host=\"{}\", network=\"{}\"}} {}",
|
|
||||||
hostname, network.interface, network.bytes_sent
|
|
||||||
)
|
|
||||||
.ok();
|
|
||||||
writeln!(
|
|
||||||
&mut result,
|
|
||||||
"net_received{{host=\"{}\", network=\"{}\"}} {}",
|
|
||||||
hostname, network.interface, network.bytes_received
|
|
||||||
)
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for disk in disks {
|
for disk in disks {
|
||||||
|
|
@ -146,3 +136,12 @@ pub trait SensorSource {
|
||||||
|
|
||||||
fn read(&mut self) -> Result<Self::Data>;
|
fn read(&mut self) -> Result<Self::Data>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait MultiSensorSource {
|
||||||
|
type Data: SensorData;
|
||||||
|
type Iter<'a>: Iterator<Item = Result<Self::Data>>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
fn read(&mut self) -> Result<Self::Iter<'_>>;
|
||||||
|
}
|
||||||
|
|
|
||||||
126
src/sensors.rs
126
src/sensors.rs
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::disk::IoStats;
|
use crate::disk::IoStats;
|
||||||
use crate::hwmon::{Device, FileSource};
|
use crate::hwmon::{Device, FileSource};
|
||||||
use crate::{Error, Result, SensorData, SensorSource};
|
use crate::{Error, MultiSensorSource, Result, SensorData, SensorSource};
|
||||||
use std::array::IntoIter;
|
use std::array::IntoIter;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{BufRead, BufReader, ErrorKind, Seek};
|
use std::io::{BufRead, BufReader, ErrorKind, Read, Seek};
|
||||||
use sysconf::{sysconf, SysconfVariable};
|
use sysconf::{sysconf, SysconfVariable};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
|
@ -201,49 +201,89 @@ impl SensorSource for CpuTimeSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn network_stats() -> Result<impl Iterator<Item = IoStats>> {
|
pub struct NetworkSource {
|
||||||
let stat = BufReader::new(File::open("/proc/net/dev")?);
|
source: File,
|
||||||
Ok(stat
|
buff: String,
|
||||||
.lines()
|
}
|
||||||
.filter_map(Result::ok)
|
|
||||||
.filter(|line: &String| {
|
impl NetworkSource {
|
||||||
let trimmed = line.trim_start();
|
pub fn new() -> Result<NetworkSource> {
|
||||||
trimmed.starts_with("en") || trimmed.starts_with("eth")
|
Ok(NetworkSource {
|
||||||
|
source: File::open("/proc/net/dev")?,
|
||||||
|
buff: String::new(),
|
||||||
})
|
})
|
||||||
.filter_map(|line: String| {
|
}
|
||||||
let mut parts = line.trim_start().split_ascii_whitespace();
|
|
||||||
if let (
|
fn parse_line(line: &str) -> Result<IoStats> {
|
||||||
Some(interface),
|
let mut parts = line.trim_start().split_ascii_whitespace();
|
||||||
Some(bytes_received),
|
if let (
|
||||||
_packets,
|
Some(interface),
|
||||||
_err,
|
Some(bytes_received),
|
||||||
_drop,
|
_packets,
|
||||||
_fifo,
|
_err,
|
||||||
_frame,
|
_drop,
|
||||||
_compressed,
|
_fifo,
|
||||||
_multicast,
|
_frame,
|
||||||
Some(bytes_sent),
|
_compressed,
|
||||||
) = (
|
_multicast,
|
||||||
parts.next(),
|
Some(bytes_sent),
|
||||||
parts.next(),
|
) = (
|
||||||
parts.next(),
|
parts.next(),
|
||||||
parts.next(),
|
parts.next(),
|
||||||
parts.next(),
|
parts.next(),
|
||||||
parts.next(),
|
parts.next(),
|
||||||
parts.next(),
|
parts.next(),
|
||||||
parts.next(),
|
parts.next(),
|
||||||
parts.next(),
|
parts.next(),
|
||||||
parts.next(),
|
parts.next(),
|
||||||
) {
|
parts.next(),
|
||||||
Some(IoStats {
|
parts.next(),
|
||||||
interface: interface.trim_end_matches(':').into(),
|
) {
|
||||||
bytes_sent: bytes_sent.parse().ok()?,
|
Ok(IoStats {
|
||||||
bytes_received: bytes_received.parse().ok()?,
|
interface: interface.trim_end_matches(':').into(),
|
||||||
})
|
bytes_sent: bytes_sent.parse()?,
|
||||||
} else {
|
bytes_received: bytes_received.parse()?,
|
||||||
None
|
})
|
||||||
|
} else {
|
||||||
|
Err(Error::Io(ErrorKind::InvalidData.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MultiSensorSource for NetworkSource {
|
||||||
|
type Data = IoStats;
|
||||||
|
type Iter<'a> = NetworkStatParser<'a>;
|
||||||
|
|
||||||
|
fn read(&mut self) -> Result<Self::Iter<'_>> {
|
||||||
|
self.buff.clear();
|
||||||
|
self.source.rewind()?;
|
||||||
|
self.source.read_to_string(&mut self.buff)?;
|
||||||
|
|
||||||
|
Ok(NetworkStatParser {
|
||||||
|
lines: self.buff.lines(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NetworkStatParser<'a> {
|
||||||
|
lines: std::str::Lines<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for NetworkStatParser<'a> {
|
||||||
|
type Item = Result<IoStats>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let line = loop {
|
||||||
|
let line = self.lines.next()?;
|
||||||
|
let trimmed = line.trim_start();
|
||||||
|
if trimmed.starts_with("en") || trimmed.starts_with("eth") || trimmed.starts_with("wlp")
|
||||||
|
{
|
||||||
|
break trimmed;
|
||||||
}
|
}
|
||||||
}))
|
};
|
||||||
|
|
||||||
|
Some(NetworkSource::parse_line(line))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hostname() -> Result<String> {
|
pub fn hostname() -> Result<String> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue