amadeus_node/utils/
system_metrics.rs1#[derive(Debug, Clone)]
3pub struct SystemStats {
4 pub cpu_usage: f32,
5 pub memory_usage: u64,
6 pub total_memory: u64,
7 pub cores_available: usize,
8}
9
10impl Default for SystemStats {
11 fn default() -> Self {
12 Self {
13 cpu_usage: 0.0,
14 memory_usage: 0,
15 total_memory: 16 * 1024 * 1024 * 1024, cores_available: std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1),
17 }
18 }
19}
20
21#[cfg(feature = "system-metrics")]
22mod inner {
23 use std::sync::LazyLock;
24 use std::sync::Mutex;
25 use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
26 use sysinfo::{ProcessesToUpdate, System};
27 use tokio::time::{Duration, interval};
28
29 use super::*;
30
31 static SYSTEM_MONITOR: LazyLock<Mutex<System>> = LazyLock::new(|| {
33 let mut system = System::new_all();
34 system.refresh_all();
35 Mutex::new(system)
36 });
37
38 static CACHED_CPU_USAGE: AtomicU32 = AtomicU32::new(0); static CACHED_MEMORY_USAGE: AtomicU64 = AtomicU64::new(0);
41 static CACHED_TOTAL_MEMORY: AtomicU64 = AtomicU64::new(0);
42 static STATS_UPDATER_STARTED: std::sync::Once = std::sync::Once::new();
43
44 fn ensure_stats_updater_started() {
46 STATS_UPDATER_STARTED.call_once(|| {
47 tokio::spawn(async {
48 let mut interval = interval(Duration::from_secs(1));
49
50 loop {
51 interval.tick().await;
52
53 if let Ok(current_pid) = sysinfo::get_current_pid() {
54 if let Ok(mut system) = SYSTEM_MONITOR.lock() {
55 system.refresh_processes(ProcessesToUpdate::Some(&[current_pid]), true);
56 system.refresh_memory(); if let Some(process) = system.process(current_pid) {
59 let cpu_usage = process.cpu_usage();
60 let memory_usage = process.memory();
61
62 CACHED_CPU_USAGE.store((cpu_usage * 100.0) as u32, Ordering::Relaxed);
64 CACHED_MEMORY_USAGE.store(memory_usage, Ordering::Relaxed);
65 }
66
67 let total_memory = system.total_memory();
69 CACHED_TOTAL_MEMORY.store(total_memory, Ordering::Relaxed);
70 }
71 }
72 }
73 });
74 });
75 }
76
77 pub fn get_system_stats() -> SystemStats {
79 ensure_stats_updater_started();
80
81 let cpu_usage = CACHED_CPU_USAGE.load(Ordering::Relaxed) as f32 / 100.0;
82 let memory_usage = CACHED_MEMORY_USAGE.load(Ordering::Relaxed);
83 let total_memory = CACHED_TOTAL_MEMORY.load(Ordering::Relaxed);
84 let cores_available = std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1);
85
86 SystemStats { cpu_usage, memory_usage, total_memory, cores_available }
87 }
88}
89
90pub fn get_system_stats() -> SystemStats {
93 #[cfg(feature = "system-metrics")]
94 {
95 inner::get_system_stats()
96 }
97 #[cfg(not(feature = "system-metrics"))]
98 {
99 SystemStats::default()
100 }
101}