Skip to content

Commit 34a3763

Browse files
committed
feat(system-metrics): implement system metrics API and frontend integration for CPU and RAM usage
1 parent 813a073 commit 34a3763

6 files changed

Lines changed: 273 additions & 61 deletions

File tree

Cargo.lock

Lines changed: 143 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ notify-debouncer-full = "0.6.0"
8080
uuid = { version = "1.6", features = ["v4", "serde"] }
8181
base64 = "0.22"
8282

83+
# System information
84+
sysinfo = "0.37.2"
85+
8386
# Testing
8487
mockall = "0.14.0"
8588
proptest = "1.4"

crates/rohas-engine/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ futures-util = "0.3"
3434
regex = "1.11"
3535
base64 = { workspace = true }
3636
async-trait = "0.1"
37+
sysinfo = { workspace = true }
3738

3839
[dev-dependencies]
3940
tokio-test = "0.4"

crates/rohas-engine/src/workbench.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ use serde_json::json;
1111
use std::collections::HashMap;
1212
use std::fs;
1313
use std::path::Path as StdPath;
14+
use std::sync::{Arc, Mutex};
15+
use std::time::{Duration, Instant};
16+
use sysinfo::System;
1417
use tracing::error;
1518

1619
#[derive(Serialize, Deserialize)]
@@ -184,6 +187,7 @@ pub fn workbench_routes() -> Router<ApiState> {
184187
.route("/api/workbench/endpoints", get(get_endpoints))
185188
.route("/api/workbench/types/{type_name}", get(get_type_schema))
186189
.route("/api/workbench/events/{name}/trigger", post(trigger_event))
190+
.route("/api/workbench/system-metrics", get(get_system_metrics))
187191
}
188192

189193
async fn get_snapshot(State(state): State<ApiState>) -> Result<Response, WorkbenchError> {
@@ -1111,6 +1115,69 @@ async fn trigger_event(
11111115
.into_response())
11121116
}
11131117

1118+
#[derive(Serialize, Deserialize)]
1119+
pub struct SystemMetrics {
1120+
pub cpu: f32,
1121+
pub ram: RamMetrics,
1122+
}
1123+
1124+
#[derive(Serialize, Deserialize)]
1125+
pub struct RamMetrics {
1126+
pub used_mb: u64,
1127+
pub total_mb: u64,
1128+
pub percentage: f32,
1129+
}
1130+
1131+
static SYSTEM: std::sync::OnceLock<Arc<Mutex<System>>> = std::sync::OnceLock::new();
1132+
static LAST_UPDATE: std::sync::OnceLock<Arc<Mutex<Instant>>> = std::sync::OnceLock::new();
1133+
1134+
fn get_system() -> Arc<Mutex<System>> {
1135+
SYSTEM.get_or_init(|| Arc::new(Mutex::new(System::new_all()))).clone()
1136+
}
1137+
1138+
fn get_last_update() -> Arc<Mutex<Instant>> {
1139+
LAST_UPDATE.get_or_init(|| Arc::new(Mutex::new(Instant::now()))).clone()
1140+
}
1141+
1142+
async fn get_system_metrics() -> Result<Response, WorkbenchError> {
1143+
let system = get_system();
1144+
let mut system_guard = system.lock().map_err(|e| {
1145+
WorkbenchError::Internal(format!("Failed to acquire system lock: {}", e))
1146+
})?;
1147+
1148+
let last_update = get_last_update();
1149+
let mut last_update_guard = last_update.lock().map_err(|e| {
1150+
WorkbenchError::Internal(format!("Failed to acquire update lock: {}", e))
1151+
})?;
1152+
1153+
if last_update_guard.elapsed() > Duration::from_secs(1) {
1154+
system_guard.refresh_all();
1155+
*last_update_guard = Instant::now();
1156+
}
1157+
let cpu_usage = system_guard.global_cpu_usage();
1158+
1159+
let total_memory = system_guard.total_memory();
1160+
let used_memory = system_guard.used_memory();
1161+
let total_memory_mb = total_memory / (1024 * 1024);
1162+
let used_memory_mb = used_memory / (1024 * 1024);
1163+
let memory_percentage = if total_memory > 0 {
1164+
(used_memory as f32 / total_memory as f32) * 100.0
1165+
} else {
1166+
0.0
1167+
};
1168+
1169+
let metrics = SystemMetrics {
1170+
cpu: cpu_usage,
1171+
ram: RamMetrics {
1172+
used_mb: used_memory_mb,
1173+
total_mb: total_memory_mb,
1174+
percentage: memory_percentage,
1175+
},
1176+
};
1177+
1178+
Ok(Json(metrics).into_response())
1179+
}
1180+
11141181
#[derive(Debug)]
11151182
pub enum WorkbenchError {
11161183
NotFound(String),

0 commit comments

Comments
 (0)