performance improvements and formatting cleanup
This commit is contained in:
parent
c3f81eef25
commit
d69a4104fc
@ -24,7 +24,7 @@ use crate::types::Metrics;
|
|||||||
use crate::ui::cpu::{
|
use crate::ui::cpu::{
|
||||||
draw_cpu_avg_graph, draw_per_core_bars, per_core_clamp, per_core_content_area,
|
draw_cpu_avg_graph, draw_per_core_bars, per_core_clamp, per_core_content_area,
|
||||||
per_core_handle_key, per_core_handle_mouse, per_core_handle_scrollbar_mouse,
|
per_core_handle_key, per_core_handle_mouse, per_core_handle_scrollbar_mouse,
|
||||||
PerCoreScrollDrag,
|
PerCoreScrollDrag
|
||||||
};
|
};
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
disks::draw_disks,
|
disks::draw_disks,
|
||||||
@ -32,7 +32,7 @@ use crate::ui::{
|
|||||||
mem::draw_mem,
|
mem::draw_mem,
|
||||||
net::draw_net_spark,
|
net::draw_net_spark,
|
||||||
processes::draw_top_processes,
|
processes::draw_top_processes,
|
||||||
swap::draw_swap,
|
swap::draw_swap
|
||||||
};
|
};
|
||||||
use crate::ui::gpu::draw_gpu;
|
use crate::ui::gpu::draw_gpu;
|
||||||
use crate::ws::{connect, request_metrics};
|
use crate::ws::{connect, request_metrics};
|
||||||
@ -74,7 +74,7 @@ impl App {
|
|||||||
tx_peak: 0,
|
tx_peak: 0,
|
||||||
should_quit: false,
|
should_quit: false,
|
||||||
per_core_scroll: 0,
|
per_core_scroll: 0,
|
||||||
per_core_drag: None,
|
per_core_drag: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ impl App {
|
|||||||
Constraint::Ratio(1, 3),
|
Constraint::Ratio(1, 3),
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
Constraint::Min(10),
|
Constraint::Min(10)
|
||||||
])
|
])
|
||||||
.split(area);
|
.split(area);
|
||||||
let top = ratatui::layout::Layout::default()
|
let top = ratatui::layout::Layout::default()
|
||||||
@ -154,7 +154,7 @@ impl App {
|
|||||||
Constraint::Ratio(1, 3),
|
Constraint::Ratio(1, 3),
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
Constraint::Min(10),
|
Constraint::Min(10)
|
||||||
])
|
])
|
||||||
.split(area);
|
.split(area);
|
||||||
let top = ratatui::layout::Layout::default()
|
let top = ratatui::layout::Layout::default()
|
||||||
@ -256,7 +256,7 @@ impl App {
|
|||||||
Constraint::Ratio(1, 3), // top row
|
Constraint::Ratio(1, 3), // top row
|
||||||
Constraint::Length(3), // memory (left) + GPU (right, part 1)
|
Constraint::Length(3), // memory (left) + GPU (right, part 1)
|
||||||
Constraint::Length(3), // swap (left) + GPU (right, part 2)
|
Constraint::Length(3), // swap (left) + GPU (right, part 2)
|
||||||
Constraint::Min(10), // bottom: disks + net (left), top procs (right)
|
Constraint::Min(10) // bottom: disks + net (left), top procs (right)
|
||||||
])
|
])
|
||||||
.split(area);
|
.split(area);
|
||||||
|
|
||||||
@ -313,7 +313,7 @@ impl App {
|
|||||||
.constraints([
|
.constraints([
|
||||||
Constraint::Min(7), // Disks grow
|
Constraint::Min(7), // Disks grow
|
||||||
Constraint::Length(3), // Download
|
Constraint::Length(3), // Download
|
||||||
Constraint::Length(3), // Upload
|
Constraint::Length(3) // Upload
|
||||||
])
|
])
|
||||||
.split(bottom_lr[0]);
|
.split(bottom_lr[0]);
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ impl Default for App {
|
|||||||
tx_peak: 0,
|
tx_peak: 0,
|
||||||
should_quit: false,
|
should_quit: false,
|
||||||
per_core_scroll: 0,
|
per_core_scroll: 0,
|
||||||
per_core_drag: None,
|
per_core_drag: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,7 +100,7 @@ pub fn per_core_handle_scrollbar_mouse(
|
|||||||
drag: &mut Option<PerCoreScrollDrag>,
|
drag: &mut Option<PerCoreScrollDrag>,
|
||||||
mouse: MouseEvent,
|
mouse: MouseEvent,
|
||||||
per_core_area: Rect,
|
per_core_area: Rect,
|
||||||
total_rows: usize,
|
total_rows: usize
|
||||||
) {
|
) {
|
||||||
// Geometry
|
// Geometry
|
||||||
let inner = Rect {
|
let inner = Rect {
|
||||||
@ -265,7 +265,7 @@ pub fn draw_per_core_bars(
|
|||||||
area: Rect,
|
area: Rect,
|
||||||
m: Option<&Metrics>,
|
m: Option<&Metrics>,
|
||||||
per_core_hist: &PerCoreHistory,
|
per_core_hist: &PerCoreHistory,
|
||||||
scroll_offset: usize,
|
scroll_offset: usize
|
||||||
) {
|
) {
|
||||||
f.render_widget(
|
f.render_widget(
|
||||||
Block::default().borders(Borders::ALL).title("Per-core"),
|
Block::default().borders(Borders::ALL).title("Per-core"),
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use ratatui::{
|
|||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
style::{Color, Style},
|
style::{Color, Style},
|
||||||
text::Span,
|
text::Span,
|
||||||
widgets::{Block, Borders, Gauge, Paragraph},
|
widgets::{Block, Borders, Gauge, Paragraph}
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::types::Metrics;
|
use crate::types::Metrics;
|
||||||
@ -110,7 +110,7 @@ pub fn draw_gpu(f: &mut ratatui::Frame<'_>, area: Rect, m: Option<&Metrics>) {
|
|||||||
f.render_widget(
|
f.render_widget(
|
||||||
Paragraph::new(Span::raw(format!("vram: {used_s}/{total_s} ({mem_pct}%)")))
|
Paragraph::new(Span::raw(format!("vram: {used_s}/{total_s} ({mem_pct}%)")))
|
||||||
.style(Style::default().fg(Color::Gray)),
|
.style(Style::default().fg(Color::Gray)),
|
||||||
mem_cols[1],
|
mem_cols[1]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,7 +3,7 @@
|
|||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::Rect,
|
layout::Rect,
|
||||||
style::{Color, Style},
|
style::{Color, Style},
|
||||||
widgets::{Block, Borders, Sparkline},
|
widgets::{Block, Borders, Sparkline}
|
||||||
};
|
};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ pub fn draw_net_spark(
|
|||||||
area: Rect,
|
area: Rect,
|
||||||
title: &str,
|
title: &str,
|
||||||
hist: &VecDeque<u64>,
|
hist: &VecDeque<u64>,
|
||||||
color: Color,
|
color: Color
|
||||||
) {
|
) {
|
||||||
let max_points = area.width.saturating_sub(2) as usize;
|
let max_points = area.width.saturating_sub(2) as usize;
|
||||||
let start = hist.len().saturating_sub(max_points);
|
let start = hist.len().saturating_sub(max_points);
|
||||||
|
|||||||
@ -6,7 +6,7 @@ pub struct GpuMetrics {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub utilization_gpu_pct: u32, // 0..100
|
pub utilization_gpu_pct: u32, // 0..100
|
||||||
pub mem_used_bytes: u64,
|
pub mem_used_bytes: u64,
|
||||||
pub mem_total_bytes: u64,
|
pub mem_total_bytes: u64
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collect_all_gpus() -> Result<Vec<GpuMetrics>, Box<dyn std::error::Error>> {
|
pub fn collect_all_gpus() -> Result<Vec<GpuMetrics>, Box<dyn std::error::Error>> {
|
||||||
@ -17,7 +17,7 @@ pub fn collect_all_gpus() -> Result<Vec<GpuMetrics>, Box<dyn std::error::Error>>
|
|||||||
name: gpu.model().to_string(),
|
name: gpu.model().to_string(),
|
||||||
utilization_gpu_pct: info.load_pct() as u32,
|
utilization_gpu_pct: info.load_pct() as u32,
|
||||||
mem_used_bytes: info.used_vram(),
|
mem_used_bytes: info.used_vram(),
|
||||||
mem_total_bytes: info.total_vram(),
|
mem_total_bytes: info.total_vram()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vec![metrics])
|
Ok(vec![metrics])
|
||||||
|
|||||||
@ -54,12 +54,15 @@ async fn main() {
|
|||||||
let state = AppState {
|
let state = AppState {
|
||||||
sys: Arc::new(Mutex::new(sys)),
|
sys: Arc::new(Mutex::new(sys)),
|
||||||
last_json: Arc::new(RwLock::new(String::new())),
|
last_json: Arc::new(RwLock::new(String::new())),
|
||||||
|
components: Arc::new(Mutex::new(components)),
|
||||||
|
disks: Arc::new(Mutex::new(disks)),
|
||||||
|
networks: Arc::new(Mutex::new(nets)),
|
||||||
// new: adaptive sampling controls
|
// new: adaptive sampling controls
|
||||||
client_count: Arc::new(AtomicUsize::new(0)),
|
client_count: Arc::new(AtomicUsize::new(0)),
|
||||||
wake_sampler: Arc::new(Notify::new()),
|
wake_sampler: Arc::new(Notify::new()),
|
||||||
auth_token: std::env::var("SOCKTOP_TOKEN")
|
auth_token: std::env::var("SOCKTOP_TOKEN")
|
||||||
.ok()
|
.ok()
|
||||||
.filter(|s| !s.is_empty()),
|
.filter(|s| !s.is_empty())
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start background sampler (adjust cadence as needed)
|
// Start background sampler (adjust cadence as needed)
|
||||||
|
|||||||
@ -4,19 +4,23 @@ use crate::gpu::collect_all_gpus;
|
|||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
use crate::types::{DiskInfo, Metrics, NetworkInfo, ProcessInfo};
|
use crate::types::{DiskInfo, Metrics, NetworkInfo, ProcessInfo};
|
||||||
|
|
||||||
use sysinfo::{Components, Disks, Networks, System};
|
use std::cmp::Ordering;
|
||||||
|
use sysinfo::{ProcessesToUpdate, System};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
pub async fn collect_metrics(state: &AppState) -> Metrics {
|
pub async fn collect_metrics(state: &AppState) -> Metrics {
|
||||||
let mut sys = state.sys.lock().await;
|
let mut sys = state.sys.lock().await;
|
||||||
|
|
||||||
|
// Targeted refresh: CPU/mem/processes only
|
||||||
if let Err(e) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
if let Err(e) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||||
sys.refresh_all();
|
sys.refresh_cpu_usage();
|
||||||
|
sys.refresh_memory();
|
||||||
|
sys.refresh_processes(ProcessesToUpdate::All, true);
|
||||||
})) {
|
})) {
|
||||||
warn!("sysinfo refresh panicked: {e:?}");
|
warn!("sysinfo selective refresh panicked: {e:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hostname (associated fn on System in 0.37)
|
// Hostname
|
||||||
let hostname = System::host_name().unwrap_or_else(|| "unknown".to_string());
|
let hostname = System::host_name().unwrap_or_else(|| "unknown".to_string());
|
||||||
|
|
||||||
// CPU usage
|
// CPU usage
|
||||||
@ -29,52 +33,82 @@ pub async fn collect_metrics(state: &AppState) -> Metrics {
|
|||||||
let swap_total = sys.total_swap();
|
let swap_total = sys.total_swap();
|
||||||
let swap_used = sys.used_swap();
|
let swap_used = sys.used_swap();
|
||||||
|
|
||||||
// Temperature (via Components container)
|
drop(sys); // release quickly before touching other locks
|
||||||
let components = Components::new_with_refreshed_list();
|
|
||||||
let cpu_temp_c = components.iter().find_map(|c| {
|
// Components (cached): just refresh temps
|
||||||
|
let cpu_temp_c = {
|
||||||
|
let mut components = state.components.lock().await;
|
||||||
|
components.refresh(true);
|
||||||
|
components.iter().find_map(|c| {
|
||||||
let l = c.label().to_ascii_lowercase();
|
let l = c.label().to_ascii_lowercase();
|
||||||
if l.contains("cpu") || l.contains("package") || l.contains("tctl") || l.contains("tdie") {
|
if l.contains("cpu") || l.contains("package") || l.contains("tctl") || l.contains("tdie") {
|
||||||
c.temperature()
|
c.temperature()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
};
|
||||||
|
|
||||||
// Disks (via Disks container)
|
// Disks (cached): refresh sizes/usage, reuse enumeration
|
||||||
let disks_list = Disks::new_with_refreshed_list();
|
let disks: Vec<DiskInfo> = {
|
||||||
let disks: Vec<DiskInfo> = disks_list
|
let mut disks_list = state.disks.lock().await;
|
||||||
|
disks_list.refresh(true);
|
||||||
|
disks_list
|
||||||
.iter()
|
.iter()
|
||||||
.map(|d| DiskInfo {
|
.map(|d| DiskInfo {
|
||||||
name: d.name().to_string_lossy().into_owned(),
|
name: d.name().to_string_lossy().into_owned(),
|
||||||
total: d.total_space(),
|
total: d.total_space(),
|
||||||
available: d.available_space(),
|
available: d.available_space(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
// Networks (via Networks container) – include interface name
|
// Networks (cached): refresh counters
|
||||||
let nets = Networks::new_with_refreshed_list();
|
let networks: Vec<NetworkInfo> = {
|
||||||
let networks: Vec<NetworkInfo> = nets
|
let mut nets = state.networks.lock().await;
|
||||||
.iter()
|
nets.refresh(true);
|
||||||
|
nets.iter()
|
||||||
.map(|(name, data)| NetworkInfo {
|
.map(|(name, data)| NetworkInfo {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
received: data.total_received(),
|
received: data.total_received(),
|
||||||
transmitted: data.total_transmitted(),
|
transmitted: data.total_transmitted()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
// Processes (top N by CPU)
|
// Processes: only collect fields we use (pid, name, cpu, mem), keep top K efficiently
|
||||||
let mut procs: Vec<ProcessInfo> = sys
|
const TOP_K: usize = 30;
|
||||||
.processes()
|
let mut procs: Vec<ProcessInfo> = {
|
||||||
|
let sys = state.sys.lock().await; // re-lock briefly to read processes
|
||||||
|
sys.processes()
|
||||||
.values()
|
.values()
|
||||||
.map(|p| ProcessInfo {
|
.map(|p| ProcessInfo {
|
||||||
pid: p.pid().as_u32(),
|
pid: p.pid().as_u32(),
|
||||||
name: p.name().to_string_lossy().into_owned(),
|
name: p.name().to_string_lossy().into_owned(),
|
||||||
cpu_usage: p.cpu_usage(),
|
cpu_usage: p.cpu_usage(),
|
||||||
mem_bytes: p.memory(),
|
mem_bytes: p.memory()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect()
|
||||||
procs.sort_by(|a, b| b.cpu_usage.partial_cmp(&a.cpu_usage).unwrap_or(std::cmp::Ordering::Equal));
|
};
|
||||||
procs.truncate(30);
|
|
||||||
|
if procs.len() > TOP_K {
|
||||||
|
procs.select_nth_unstable_by(TOP_K, |a, b| {
|
||||||
|
b.cpu_usage
|
||||||
|
.partial_cmp(&a.cpu_usage)
|
||||||
|
.unwrap_or(Ordering::Equal)
|
||||||
|
});
|
||||||
|
procs.truncate(TOP_K);
|
||||||
|
}
|
||||||
|
procs.sort_by(|a, b| {
|
||||||
|
b.cpu_usage
|
||||||
|
.partial_cmp(&a.cpu_usage)
|
||||||
|
.unwrap_or(Ordering::Equal)
|
||||||
|
});
|
||||||
|
|
||||||
|
let process_count = {
|
||||||
|
let sys = state.sys.lock().await;
|
||||||
|
sys.processes().len()
|
||||||
|
};
|
||||||
|
|
||||||
// GPU(s)
|
// GPU(s)
|
||||||
let gpus = match collect_all_gpus() {
|
let gpus = match collect_all_gpus() {
|
||||||
@ -93,12 +127,12 @@ pub async fn collect_metrics(state: &AppState) -> Metrics {
|
|||||||
mem_used,
|
mem_used,
|
||||||
swap_total,
|
swap_total,
|
||||||
swap_used,
|
swap_used,
|
||||||
process_count: sys.processes().len(),
|
process_count,
|
||||||
hostname,
|
hostname,
|
||||||
cpu_temp_c,
|
cpu_temp_c,
|
||||||
disks,
|
disks,
|
||||||
networks,
|
networks,
|
||||||
top_processes: procs,
|
top_processes: procs,
|
||||||
gpus,
|
gpus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,13 +13,13 @@ pub struct Metrics {
|
|||||||
pub swap_total_mb: u64,
|
pub swap_total_mb: u64,
|
||||||
pub swap_used_mb: u64,
|
pub swap_used_mb: u64,
|
||||||
pub net_aggregate: NetTotals,
|
pub net_aggregate: NetTotals,
|
||||||
pub top_processes: Vec<Proc>,
|
pub top_processes: Vec<Proc>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct NetTotals {
|
pub struct NetTotals {
|
||||||
pub rx_bytes: u64,
|
pub rx_bytes: u64,
|
||||||
pub tx_bytes: u64,
|
pub tx_bytes: u64
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@ -28,5 +28,5 @@ pub struct Proc {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub cpu: f32,
|
pub cpu: f32,
|
||||||
pub mem_mb: u64,
|
pub mem_mb: u64,
|
||||||
pub status: String,
|
pub status: String
|
||||||
}
|
}
|
||||||
@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use sysinfo::System;
|
use sysinfo::{Components, Disks, Networks, System};
|
||||||
use tokio::sync::{Mutex, Notify, RwLock};
|
use tokio::sync::{Mutex, Notify, RwLock};
|
||||||
|
|
||||||
pub type SharedSystem = Arc<Mutex<System>>;
|
pub type SharedSystem = Arc<Mutex<System>>;
|
||||||
|
pub type SharedComponents = Arc<Mutex<Components>>;
|
||||||
|
pub type SharedDisks = Arc<Mutex<Disks>>;
|
||||||
|
pub type SharedNetworks = Arc<Mutex<Networks>>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
@ -19,4 +22,30 @@ pub struct AppState {
|
|||||||
pub client_count: Arc<AtomicUsize>,
|
pub client_count: Arc<AtomicUsize>,
|
||||||
pub wake_sampler: Arc<Notify>,
|
pub wake_sampler: Arc<Notify>,
|
||||||
pub auth_token: Option<String>,
|
pub auth_token: Option<String>,
|
||||||
|
|
||||||
|
// Cached containers (enumerated once; refreshed per tick)
|
||||||
|
pub components: SharedComponents,
|
||||||
|
pub disks: SharedDisks,
|
||||||
|
pub networks: SharedNetworks
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppState {
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let sys = System::new(); // targeted refreshes per tick
|
||||||
|
let components = Components::new_with_refreshed_list(); // enumerate once
|
||||||
|
let disks = Disks::new_with_refreshed_list();
|
||||||
|
let networks = Networks::new_with_refreshed_list();
|
||||||
|
Self {
|
||||||
|
sys: Arc::new(Mutex::new(sys)),
|
||||||
|
components: Arc::new(Mutex::new(components)),
|
||||||
|
disks: Arc::new(Mutex::new(disks)),
|
||||||
|
networks: Arc::new(Mutex::new(networks)),
|
||||||
|
last_json: Arc::new(RwLock::new(String::new())),
|
||||||
|
client_count: Arc::new(AtomicUsize::new(0)),
|
||||||
|
wake_sampler: Arc::new(Notify::new()),
|
||||||
|
auth_token: std::env::var("SOCKTOP_TOKEN").ok().filter(|s| !s.is_empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,14 +9,14 @@ pub struct ProcessInfo {
|
|||||||
pub pid: u32,
|
pub pid: u32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub cpu_usage: f32,
|
pub cpu_usage: f32,
|
||||||
pub mem_bytes: u64,
|
pub mem_bytes: u64
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Clone)]
|
#[derive(Debug, Serialize, Clone)]
|
||||||
pub struct DiskInfo {
|
pub struct DiskInfo {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub total: u64,
|
pub total: u64,
|
||||||
pub available: u64,
|
pub available: u64
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Clone)]
|
#[derive(Debug, Serialize, Clone)]
|
||||||
@ -24,7 +24,7 @@ pub struct NetworkInfo {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
// cumulative totals since the agent started (client should diff to get rates)
|
// cumulative totals since the agent started (client should diff to get rates)
|
||||||
pub received: u64,
|
pub received: u64,
|
||||||
pub transmitted: u64,
|
pub transmitted: u64
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -41,5 +41,5 @@ pub struct Metrics {
|
|||||||
pub disks: Vec<DiskInfo>,
|
pub disks: Vec<DiskInfo>,
|
||||||
pub networks: Vec<NetworkInfo>,
|
pub networks: Vec<NetworkInfo>,
|
||||||
pub top_processes: Vec<ProcessInfo>,
|
pub top_processes: Vec<ProcessInfo>,
|
||||||
pub gpus: Option<Vec<GpuMetrics>>, // new
|
pub gpus: Option<Vec<GpuMetrics>>
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user