mirror of
				https://github.com/csehviktor/status-monitor.git
				synced 2025-08-08 18:06:14 +02:00 
			
		
		
		
	create cpu breakdown
This commit is contained in:
		| @@ -1,10 +1,13 @@ | ||||
| use common::metrics::{Disk, Memory, Metrics, Network, SystemInfo, CPU}; | ||||
| use sysinfo::{Disks, Networks, System}; | ||||
|  | ||||
| use crate::cpu::CpuStatReader; | ||||
|  | ||||
| pub struct Collector { | ||||
|     sys: System, | ||||
|     disks: Disks, | ||||
|     networks: Networks, | ||||
|     cpu_reader: CpuStatReader, | ||||
| } | ||||
|  | ||||
| impl Collector { | ||||
| @@ -13,6 +16,7 @@ impl Collector { | ||||
|             sys: System::new_all(), | ||||
|             disks: Disks::new_with_refreshed_list(), | ||||
|             networks: Networks::new_with_refreshed_list(), | ||||
|             cpu_reader: CpuStatReader::new(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -46,16 +50,11 @@ impl Collector { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn collect_cpu(&self) -> CPU { | ||||
|         let cpus = self.sys.cpus(); | ||||
|  | ||||
|         let threads = cpus.len(); | ||||
|         let usage = self.sys.global_cpu_usage(); | ||||
|  | ||||
|     fn collect_cpu(&mut self) -> CPU { | ||||
|         CPU { | ||||
|             brand: String::from(cpus[0].brand()), | ||||
|             usage, | ||||
|             threads, | ||||
|             usage: self.sys.global_cpu_usage(), | ||||
|             threads: self.sys.cpus().len(), | ||||
|             breakdown: self.cpu_reader.read_global_cpu_stats().unwrap_or_default() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										97
									
								
								agent/src/cpu.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								agent/src/cpu.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| use std::collections::HashMap; | ||||
| use common::metrics::CpuBreakdown; | ||||
|  | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| struct CpuValues { | ||||
|     pub user: u64, | ||||
|     pub nice: u64, | ||||
|     pub system: u64, | ||||
|     pub idle: u64, | ||||
|     pub iowait: u64, | ||||
|     pub irq: u64, | ||||
|     pub softirq: u64, | ||||
|     pub steal: u64, | ||||
|     pub guest: u64, | ||||
|     pub guest_nice: u64, | ||||
| } | ||||
|  | ||||
| impl CpuValues { | ||||
|     pub fn total(&self) -> u64 { | ||||
|         self.user + self.nice + self.system + self.idle + self.iowait + | ||||
|         self.irq + self.softirq + self.steal + self.guest + self.guest_nice | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub struct CpuStatReader { | ||||
|     previous_stats: HashMap<String, CpuValues>, | ||||
| } | ||||
|  | ||||
| impl CpuStatReader { | ||||
|     pub fn new() -> Self { | ||||
|         Self { previous_stats: HashMap::new() } | ||||
|     } | ||||
|  | ||||
|     pub fn read_global_cpu_stats(&mut self) -> anyhow::Result<CpuBreakdown> { | ||||
|         let content = std::fs::read_to_string("/proc/stat").unwrap(); | ||||
|  | ||||
|         let cpu_line = content | ||||
|             .lines() | ||||
|             .find(|line| line.starts_with("cpu ")) | ||||
|             .unwrap(); | ||||
|  | ||||
|         self.parse_cpu_line(cpu_line) | ||||
|     } | ||||
|  | ||||
|     fn parse_cpu_line(&mut self, line: &str) -> anyhow::Result<CpuBreakdown> { | ||||
|         let parts: Vec<&str> = line.split_whitespace().collect(); | ||||
|  | ||||
|         let cpu_name = parts[0].to_string(); | ||||
|  | ||||
|         let parse = |num: usize| -> u64 { | ||||
|             parts[num].parse().ok().unwrap() | ||||
|         }; | ||||
|  | ||||
|         let values = CpuValues { | ||||
|             user: parse(1), | ||||
|             nice: parse(2), | ||||
|             system: parse(3), | ||||
|             idle: parse(4), | ||||
|             iowait: parse(5), | ||||
|             irq: parse(6), | ||||
|             softirq: parse(7), | ||||
|             steal: parse(8), | ||||
|             guest: parse(9), | ||||
|             guest_nice: parse(10), | ||||
|         }; | ||||
|  | ||||
|         let previous = self.previous_stats.get(&cpu_name).copied(); | ||||
|         let percentages = self.calculate_percentages(&values, previous); | ||||
|  | ||||
|         self.previous_stats.insert(cpu_name, values); | ||||
|  | ||||
|         Ok(percentages) | ||||
|     } | ||||
|  | ||||
|     fn calculate_percentages(&self, current: &CpuValues, previous: Option<CpuValues>) -> CpuBreakdown { | ||||
|         let Some(prev) = previous else { | ||||
|             return CpuBreakdown::default(); | ||||
|         }; | ||||
|  | ||||
|         let total_delta = current.total().saturating_sub(prev.total()) as f32; | ||||
|         if total_delta <= 0.0 { | ||||
|             return CpuBreakdown::default(); | ||||
|         } | ||||
|  | ||||
|         let calculate_pct = |current: u64, prev: u64| { | ||||
|             (current.saturating_sub(prev) as f32 / total_delta) * 100.0 | ||||
|         }; | ||||
|  | ||||
|         CpuBreakdown { | ||||
|             system: calculate_pct(current.system, prev.system), | ||||
|             user: calculate_pct(current.user, prev.user), | ||||
|             idle: calculate_pct(current.idle, prev.idle), | ||||
|             steal: calculate_pct(current.steal, prev.steal), | ||||
|             iowait: calculate_pct(current.iowait, prev.iowait), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -5,6 +5,9 @@ use std::time::Duration; | ||||
| use std::thread; | ||||
|  | ||||
| pub mod collector; | ||||
| pub mod config; | ||||
| pub mod mqtt; | ||||
| pub mod cpu; | ||||
|  | ||||
| #[tokio::main] | ||||
| async fn main() -> anyhow::Result<()> { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user