feat: add sysinfo dependency and system metrics support
Added the sysinfo crate (v0.37.2) to gather system metrics. This includes: - New dependencies: sysinfo, ntapi, objc2-core-foundation, objc2-io-kit - Updated windows-core to specific version 0.62.2 - Initial system metrics integration in bot module The change enables monitoring system resources which will be used for performance optimization and health monitoring.
This commit is contained in:
parent
ac9c1509d5
commit
dc0e0a9c51
6 changed files with 243 additions and 4 deletions
110
Cargo.lock
generated
110
Cargo.lock
generated
|
|
@ -1151,6 +1151,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"sha2",
|
||||
"smartstring",
|
||||
"sysinfo",
|
||||
"tempfile",
|
||||
"time",
|
||||
"tokio",
|
||||
|
|
@ -2821,7 +2822,7 @@ dependencies = [
|
|||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
"windows-core 0.62.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3642,6 +3643,15 @@ dependencies = [
|
|||
"nom 8.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.50.3"
|
||||
|
|
@ -3695,6 +3705,25 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-foundation"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-kit"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.2"
|
||||
|
|
@ -5229,6 +5258,20 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.37.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"objc2-core-foundation",
|
||||
"objc2-io-kit",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.6.1"
|
||||
|
|
@ -6144,6 +6187,41 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.61.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-core 0.61.2",
|
||||
"windows-future",
|
||||
"windows-link 0.1.3",
|
||||
"windows-numerics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link 0.1.3",
|
||||
"windows-result 0.3.4",
|
||||
"windows-strings 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.2"
|
||||
|
|
@ -6157,6 +6235,17 @@ dependencies = [
|
|||
"windows-strings 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-link 0.1.3",
|
||||
"windows-threading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.2"
|
||||
|
|
@ -6191,6 +6280,16 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-registry"
|
||||
version = "0.5.3"
|
||||
|
|
@ -6331,6 +6430,15 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.53.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-threading"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
serde_json = "1.0"
|
||||
sha2 = "0.10.9"
|
||||
smartstring = "1.0"
|
||||
sysinfo = "0.37.2"
|
||||
tempfile = "3"
|
||||
time = "0.3.44"
|
||||
tokio = { version = "1.41", features = ["full"] }
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
use crate::config::ConfigManager;
|
||||
use crate::drive_monitor::DriveMonitor;
|
||||
use crate::llm_models;
|
||||
use crate::nvidia::get_system_metrics;
|
||||
use crate::shared::models::{BotResponse, Suggestion, UserMessage, UserSession};
|
||||
use crate::shared::state::AppState;
|
||||
use actix_web::{web, HttpRequest, HttpResponse, Result};
|
||||
use actix_ws::Message as WsMessage;
|
||||
use chrono::Utc;
|
||||
use chrono::{Utc};
|
||||
use diesel::PgConnection;
|
||||
use log::{error, info, trace, warn};
|
||||
use serde_json;
|
||||
use tokio::time::Instant;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::Mutex as AsyncMutex;
|
||||
use uuid::Uuid;
|
||||
|
|
@ -436,9 +439,10 @@ impl BotOrchestrator {
|
|||
response_tx.send(thinking_response).await?;
|
||||
}
|
||||
|
||||
let prompt_clone = prompt.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = llm
|
||||
.generate_stream(&prompt, &serde_json::Value::Null, stream_tx)
|
||||
.generate_stream(&prompt_clone, &serde_json::Value::Null, stream_tx)
|
||||
.await
|
||||
{
|
||||
error!("LLM streaming error: {}", e);
|
||||
|
|
@ -450,8 +454,32 @@ impl BotOrchestrator {
|
|||
let mut in_analysis = false;
|
||||
let mut chunk_count = 0;
|
||||
let mut first_word_received = false;
|
||||
let mut last_progress_update = Instant::now();
|
||||
let progress_interval = Duration::from_secs(1);
|
||||
|
||||
// Calculate initial token count
|
||||
let initial_tokens = crate::shared::utils::estimate_token_count(&prompt);
|
||||
let config_manager = ConfigManager::new(Arc::clone(&self.state.conn));
|
||||
let max_context_size = config_manager
|
||||
.get_config(
|
||||
&Uuid::parse_str(&message.bot_id).unwrap_or_default(),
|
||||
"llm-server-ctx-size",
|
||||
None,
|
||||
)
|
||||
.unwrap_or_default()
|
||||
.parse::<usize>()
|
||||
.unwrap_or(0);
|
||||
|
||||
// Show initial progress
|
||||
if let Ok(metrics) = get_system_metrics(initial_tokens, max_context_size) {
|
||||
eprintln!(
|
||||
"\nNVIDIA: {:.1}% | CPU: {:.1}% | Tokens: {}/{}",
|
||||
metrics.gpu_usage.unwrap_or(0.0),
|
||||
metrics.cpu_usage,
|
||||
initial_tokens,
|
||||
max_context_size
|
||||
);
|
||||
}
|
||||
let model = config_manager
|
||||
.get_config(
|
||||
&Uuid::parse_str(&message.bot_id).unwrap_or_default(),
|
||||
|
|
@ -498,6 +526,21 @@ impl BotOrchestrator {
|
|||
if !in_analysis {
|
||||
full_response.push_str(&chunk);
|
||||
|
||||
// Update progress if interval elapsed
|
||||
if last_progress_update.elapsed() >= progress_interval {
|
||||
let current_tokens = initial_tokens + crate::shared::utils::estimate_token_count(&full_response);
|
||||
if let Ok(metrics) = get_system_metrics(current_tokens, max_context_size) {
|
||||
eprintln!(
|
||||
"\nNVIDIA: {:.1}% | CPU: {:.1}% | Tokens: {}/{}",
|
||||
metrics.gpu_usage.unwrap_or(0.0),
|
||||
metrics.cpu_usage,
|
||||
current_tokens,
|
||||
max_context_size
|
||||
);
|
||||
}
|
||||
last_progress_update = Instant::now();
|
||||
}
|
||||
|
||||
let partial = BotResponse {
|
||||
bot_id: message.bot_id.clone(),
|
||||
user_id: message.user_id.clone(),
|
||||
|
|
|
|||
|
|
@ -20,3 +20,4 @@ pub mod tests;
|
|||
pub mod web_automation;
|
||||
pub mod web_server;
|
||||
pub mod auth;
|
||||
pub mod nvidia;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ pub mod tests;
|
|||
#[cfg(feature = "web_automation")]
|
||||
mod web_automation;
|
||||
mod web_server;
|
||||
|
||||
mod nvidia;
|
||||
|
||||
use crate::auth::auth_handler;
|
||||
use crate::automation::AutomationService;
|
||||
|
|
|
|||
86
src/nvidia/mod.rs
Normal file
86
src/nvidia/mod.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
use anyhow::Result;
|
||||
use log::warn;
|
||||
use std::collections::HashMap;
|
||||
use sysinfo::{System};
|
||||
|
||||
/// System monitoring data
|
||||
pub struct SystemMetrics {
|
||||
pub gpu_usage: Option<f32>,
|
||||
pub cpu_usage: f32,
|
||||
pub token_ratio: f32,
|
||||
}
|
||||
|
||||
/// Gets current system metrics
|
||||
pub fn get_system_metrics(current_tokens: usize, max_tokens: usize) -> Result<SystemMetrics> {
|
||||
let mut sys = System::new();
|
||||
sys.refresh_cpu_usage();
|
||||
|
||||
// Get CPU usage (average across all cores)
|
||||
let cpu_usage = sys.global_cpu_usage();
|
||||
|
||||
// Get GPU usage if available
|
||||
let gpu_usage = if has_nvidia_gpu() {
|
||||
get_gpu_utilization()?.get("gpu").copied()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Calculate token ratio
|
||||
let token_ratio = if max_tokens > 0 {
|
||||
current_tokens as f32 / max_tokens as f32 * 100.0
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
Ok(SystemMetrics {
|
||||
gpu_usage,
|
||||
cpu_usage,
|
||||
token_ratio,
|
||||
})
|
||||
}
|
||||
|
||||
/// Checks if NVIDIA GPU is available
|
||||
pub fn has_nvidia_gpu() -> bool {
|
||||
match std::process::Command::new("nvidia-smi")
|
||||
.arg("--query-gpu=utilization.gpu")
|
||||
.arg("--format=csv,noheader,nounits")
|
||||
.output()
|
||||
{
|
||||
Ok(output) => output.status.success(),
|
||||
Err(_) => {
|
||||
warn!("No NVIDIA GPU detected or nvidia-smi not available");
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets current GPU utilization percentages
|
||||
pub fn get_gpu_utilization() -> Result<HashMap<String, f32>> {
|
||||
let output = std::process::Command::new("nvidia-smi")
|
||||
.arg("--query-gpu=utilization.gpu,utilization.memory")
|
||||
.arg("--format=csv,noheader,nounits")
|
||||
.output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(anyhow::anyhow!("Failed to query GPU utilization"));
|
||||
}
|
||||
|
||||
let output_str = String::from_utf8(output.stdout)?;
|
||||
let mut util = HashMap::new();
|
||||
|
||||
for line in output_str.lines() {
|
||||
let parts: Vec<&str> = line.split(',').collect();
|
||||
if parts.len() >= 2 {
|
||||
util.insert(
|
||||
"gpu".to_string(),
|
||||
parts[0].trim().parse::<f32>().unwrap_or(0.0),
|
||||
);
|
||||
util.insert(
|
||||
"memory".to_string(),
|
||||
parts[1].trim().parse::<f32>().unwrap_or(0.0),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(util)
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue