retrieve system stats

This commit is contained in:
beckerinj
2022-11-09 01:28:33 -05:00
parent f679fa2c0c
commit 6728507914
3 changed files with 109 additions and 15 deletions

View File

@@ -280,6 +280,30 @@ pub struct UserCredentials {
pub password: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SystemStats {
pub cpu: f32, // in %
pub mem_used: f64, // in MB
pub mem_total: f64, // in MB
pub disk: DiskUsage,
pub networks: Vec<SystemNetwork>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DiskUsage {
pub used: f64, // in GB
pub total: f64, // in GB
pub read: f64, // in kB
pub write: f64, // in kB
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SystemNetwork {
pub name: String,
pub recieved: f64, // in kB
pub transmitted: f64, // in kB
}
#[derive(Serialize, Deserialize, Debug, Display, EnumString, PartialEq, Hash, Eq, Clone, Copy)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]

View File

@@ -1,24 +1,92 @@
use std::sync::Arc;
use std::{
path::Path,
sync::{Arc, RwLock},
};
use axum::{Router, Extension};
use axum::{routing::get, Extension, Json, Router};
use sysinfo::{CpuExt, DiskExt, NetworkExt, ProcessExt, ProcessRefreshKind, SystemExt};
use types::{DiskUsage, SystemNetwork, SystemStats};
pub fn router() -> Router {
Router::new()
.layer(StatsClient::extension())
Router::new()
.route(
"/system",
get(|Extension(sys): StatsExtension| async move {
let stats = sys.write().unwrap().get_stats();
Json(stats)
}),
)
.layer(StatsClient::extension())
}
type StatsExtension = Extension<Arc<StatsClient>>;
type StatsExtension = Extension<Arc<RwLock<StatsClient>>>;
struct StatsClient {
client: sysinfo::System,
sys: sysinfo::System,
}
const BYTES_PER_GB: f64 = 1073741824.0;
const BYTES_PER_KB: f64 = 1024.0;
impl StatsClient {
pub fn extension() -> StatsExtension {
let client = StatsClient {
client: sysinfo::System::default(),
};
Extension(Arc::new(client))
}
}
pub fn extension() -> StatsExtension {
let client = StatsClient {
sys: sysinfo::System::new_all(),
};
Extension(Arc::new(RwLock::new(client)))
}
pub fn get_stats(&mut self) -> SystemStats {
self.sys.refresh_cpu();
self.sys.refresh_memory();
SystemStats {
cpu: self.sys.global_cpu_info().cpu_usage(),
mem_used: self.sys.used_memory() as f64 / BYTES_PER_GB,
mem_total: self.sys.total_memory() as f64 / BYTES_PER_GB,
disk: self.get_disk_usage(),
networks: self.get_networks(),
}
}
fn get_networks(&mut self) -> Vec<SystemNetwork> {
self.sys.refresh_networks();
self.sys
.networks()
.into_iter()
.map(|(name, n)| SystemNetwork {
name: name.clone(),
recieved: n.received() as f64 / BYTES_PER_KB,
transmitted: n.transmitted() as f64 / BYTES_PER_KB,
})
.filter(|n| n.recieved > 0.0 || n.transmitted > 0.0)
.collect()
}
fn get_disk_usage(&mut self) -> DiskUsage {
self.sys.refresh_disks();
let mut free = 0.0;
let mut total = 0.0;
for disk in self.sys.disks() {
if disk.mount_point() == Path::new("/") {
total += disk.total_space() as f64 / BYTES_PER_GB;
free += disk.available_space() as f64 / BYTES_PER_GB;
}
}
let used = total - free;
self.sys
.refresh_processes_specifics(ProcessRefreshKind::new().with_disk_usage());
let mut read = 0.0;
let mut write = 0.0;
for (_, process) in self.sys.processes() {
let disk_usage = process.disk_usage();
read += disk_usage.read_bytes as f64 / BYTES_PER_KB;
write += disk_usage.written_bytes as f64 / BYTES_PER_KB;
}
DiskUsage {
used,
total,
read,
write,
}
}
}

View File

@@ -14,7 +14,9 @@ use api::*;
async fn main() {
let (port, secrets) = config::load();
let app = Router::new().nest("/container", container::router());
let app = Router::new()
.nest("/container", container::router())
.nest("/stats", stats::router());
println!("starting montior periphery on port {port}");