about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2025-02-25 19:21:59 -0600
committergennyble <gen@nyble.dev>2025-02-25 19:21:59 -0600
commit337b1faeeb414c5dad9a1b2cf80460a5e74eacbe (patch)
tree39c5d8e630672c4ffc51488556184c4fc3f189a4 /src
parentf9df72033b29ed08811ac87d1ef22002eac4b992 (diff)
downloadawake-337b1faeeb414c5dad9a1b2cf80460a5e74eacbe.tar.gz
awake-337b1faeeb414c5dad9a1b2cf80460a5e74eacbe.zip
Make CPU graph better
Diffstat (limited to 'src')
-rw-r--r--src/db.rs5
-rw-r--r--src/gatherer.rs43
-rw-r--r--src/griph/mod.rs25
-rwxr-xr-xsrc/main.rs9
4 files changed, 71 insertions, 11 deletions
diff --git a/src/db.rs b/src/db.rs
index 9a0256a..0abf722 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -238,4 +238,9 @@ impl DbCpuinfo {
 		let avg = used_sum as f32 / self.span_sec as f32;
 		avg
 	}
+
+	/// The sum of the user, nice, and system deltas
+	pub fn usage_sum(&self) -> usize {
+		self.user_delta + self.nice_delta + self.system_delta
+	}
 }
diff --git a/src/gatherer.rs b/src/gatherer.rs
index 7289f60..53e46f1 100644
--- a/src/gatherer.rs
+++ b/src/gatherer.rs
@@ -10,7 +10,11 @@ use std::{
 use regex_lite::Regex;
 use time::OffsetDateTime;
 
-use crate::{db::DbMeminfo, griph, AwakeState};
+use crate::{
+	db::DbMeminfo,
+	griph::{self, Style},
+	AwakeState,
+};
 
 pub struct Gatherer {
 	state: AwakeState,
@@ -124,7 +128,7 @@ pub fn make_mem_graph(state: &AwakeState) {
 	// right side, so last in the array
 	usages.reverse();
 
-	let gif = griph::make_1line(0, max, &usages);
+	let gif = griph::make_1line(0, max, &usages, Style::Line);
 
 	let path = state.cache_path.join("current_hostmeminfo.gif");
 	gif.save(path).unwrap();
@@ -162,7 +166,7 @@ pub fn make_net_graph(state: &AwakeState) {
 
 	mixed.sort();
 	let kinda_highest = mixed[511 - 32];
-	let high_bound = (kinda_highest as f32 / 256.0).ceil().min(1.0) as usize * 256;
+	let high_bound = (kinda_highest as f32 / 256.0).ceil().max(1.0) as usize * 256;
 	state
 		.netinfo_upper_bound
 		.store(high_bound, Ordering::Release);
@@ -180,14 +184,39 @@ pub fn make_cpu_graph(state: &AwakeState) {
 
 	let now = OffsetDateTime::now_utc();
 	let cleaned = clean_series(&infos, |cpu| cpu.stamp, now);
-	// Scalling by 10 because the graph system does not like to have a max of only 100 due to some bad programming
-	let mut usages = extract(&cleaned, |cpu| (cpu.average_usage() * 10.0) as usize);
+
+	// Usages are of the unit of hundreths of a second of CPU usage averaged over a minute.
+	// A value of 1 means the cpu saw 1% CPU usage
+	let usages = extract(&cleaned, |cpu| cpu.average_usage());
+
+	let mut zeroed: Vec<f32> = usages.iter().map(|m| m.unwrap_or(0.0)).collect();
+	zeroed.sort_by(|a, b| a.partial_cmp(&b).unwrap());
+	let kinda_highest = zeroed[255 - 8];
+
+	tracing::debug!(
+		"kinda_highest = {kinda_highest} // highest = {}",
+		zeroed[255]
+	);
+
+	// high_vound unit: hundreths of a second (1% / 1)
+	let high_bound = kinda_highest.max(1.0);
+	state
+		.cpuinfo_upper_bound
+		.store(high_bound as usize, Ordering::Release);
+
+	// can't scale the range, so we have to scale the inputs.
+	// Finally, we multiply by ten to put it in a 0-1000 range
+	let scale_factor = 100.0 / high_bound;
+	let mut scaled: Vec<Option<usize>> = usages
+		.iter()
+		.map(|m| m.map(|v| (v * scale_factor) as usize * 10))
+		.collect();
 
 	// Reversing here because we want latest valeus on on the
 	// right side, so last in the array
-	usages.reverse();
+	scaled.reverse();
 
-	let gif = griph::make_1line(0, 1000, &usages);
+	let gif = griph::make_1line(0, 1000, &scaled, Style::UnderfilledLine);
 
 	let path = state.cache_path.join("current_hostcpuinfo.gif");
 	gif.save(path).unwrap();
diff --git a/src/griph/mod.rs b/src/griph/mod.rs
index b1449f5..636ffd9 100644
--- a/src/griph/mod.rs
+++ b/src/griph/mod.rs
@@ -10,6 +10,7 @@ pub const DARK_PALETTE: &[u8] = &[
 	 48, 192,  48, // Secondary 2 Colour - Green
 	 96,  96, 224, // Primary Underfill - Light Blue
 	 48, 128,  48, // Secondary Underfill - Lesser Green
+	144, 144, 144  // Graphline Underfill - 16 * 9 gray
 ];
 
 const BACKGROUND: u8 = 0;
@@ -20,22 +21,40 @@ const LINE1: u8 = 4;
 const LINE2: u8 = 5;
 const LINE1_FILL: u8 = 6;
 const LINE2_FILL: u8 = 7;
+const LINE_FILL: u8 = 8;
 
 const WIDTH: usize = 256;
 const HEIGHT: usize = 160;
 const SIZE: usize = WIDTH * HEIGHT;
 
-pub fn make_1line(min: usize, max: usize, values: &[Option<usize>]) -> Gif {
+pub enum Style {
+	Line,
+	UnderfilledLine,
+}
+
+pub fn make_1line(min: usize, max: usize, values: &[Option<usize>], style: Style) -> Gif {
 	let range = max - min;
 	// this assumes a range of values that is >1 per pixel
 	let vpp = range / HEIGHT;
 
 	let mut raster = vec![0; SIZE];
+	let mut standard = Gif::new(WIDTH as u16, HEIGHT as u16);
+
 	draw_grid(&mut raster);
 	draw_line(&mut raster, values, vpp, LINE);
 
-	let mut standard = Gif::new(WIDTH as u16, HEIGHT as u16);
-	standard.set_palette(Some(DARK_PALETTE[0..12].try_into().unwrap()));
+	let plt = match style {
+		Style::Line => {
+			draw_line(&mut raster, values, vpp, LINE);
+			&DARK_PALETTE[0..12]
+		}
+		Style::UnderfilledLine => {
+			draw_line_underfill(&mut raster, values, vpp, LINE_FILL, LINE);
+			&DARK_PALETTE
+		}
+	};
+
+	standard.set_palette(Some(plt.try_into().unwrap()));
 	standard.push(
 		ImageBuilder::new(WIDTH as u16, HEIGHT as u16)
 			.build(raster)
diff --git a/src/main.rs b/src/main.rs
index 5ba279f..d4faf9f 100755
--- a/src/main.rs
+++ b/src/main.rs
@@ -17,7 +17,7 @@ use std::{
 	os::unix::fs::MetadataExt,
 	str::FromStr,
 	sync::{
-		atomic::{AtomicUsize, Ordering},
+		atomic::{AtomicU8, AtomicUsize, Ordering},
 		Arc,
 	},
 	time::Duration,
@@ -55,7 +55,10 @@ pub struct AwakeState {
 	pub do_statistics: bool,
 	pub database: Arc<Database>,
 	pub cache_path: Utf8PathBuf,
+	/// kbps
 	pub netinfo_upper_bound: Arc<AtomicUsize>,
+	/// whole digit % cpu usage
+	pub cpuinfo_upper_bound: Arc<AtomicUsize>,
 }
 
 #[tokio::main]
@@ -97,6 +100,7 @@ async fn main() {
 		database: Arc::new(database),
 		cache_path: cache.into(),
 		netinfo_upper_bound: Arc::new(AtomicUsize::new(256)),
+		cpuinfo_upper_bound: Arc::new(AtomicUsize::new(100)),
 	};
 
 	match std::env::args().nth(1).as_deref() {
@@ -437,6 +441,9 @@ fn template_content(state: AwakeState, frontmatter: &Frontmatter, marked: String
 
 		let netinfo_upper = state.netinfo_upper_bound.load(Ordering::Relaxed);
 		doc.set("stats.net.max_bound", netinfo_upper);
+
+		let cpuinfo_upper = state.cpuinfo_upper_bound.load(Ordering::Relaxed);
+		doc.set("stats.cpu.max_bound", cpuinfo_upper);
 	}
 
 	doc.compile()