From 6d0f615176f217d35eccdb3a9f029f6cc10cdc55 Mon Sep 17 00:00:00 2001 From: Janakarajan Natarajan Date: Thu, 14 Sep 2023 17:04:10 +0000 Subject: [PATCH 1/7] Add support for Graph Limits --- src/html_files/utils.ts | 39 ++++++++++++++++++++ src/visualizer.rs | 79 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/src/html_files/utils.ts b/src/html_files/utils.ts index 431a47f9..62a99d97 100644 --- a/src/html_files/utils.ts +++ b/src/html_files/utils.ts @@ -13,6 +13,40 @@ declare let netstat_raw_data; declare let perf_profile_raw_data; declare let flamegraph_raw_data; +let key_limits: Map = new Map(); + +function form_graph_limits(data) { + key_limits.clear(); + for (let i = 0; i < data.runs.length; i++) { + let key_values = data.runs[i]['key_values']; + for (let key in key_values) { + let metadata = JSON.parse(key_values[key])['metadata']; + let limits = metadata.limits; + if (key_limits.has(key)) { + let existing_limit = key_limits.get(key); + if (limits.low < existing_limit.low) { + existing_limit.low = limits.low; + } + if (limits.high > existing_limit.high) { + existing_limit.high = limits.high; + } + } else { + key_limits.set(key, limits); + } + } + } + for (let [key, value] of key_limits.entries()) { + let extra = (value.high - value.low) * 0.1; + value.high += extra; + if (value.low != 0) { + if ((value.low - extra) < 0) { + value.low = 0; + } else { + value.low -= extra; + } + } + } +} class RunEntry { run: string; entries: Map; @@ -21,6 +55,11 @@ class RunEntry { raw_entries: string; } +class Limits { + low: number; + high: number; +} + function clearElements(id: string) { let node: HTMLElement = document.getElementById(id); while(node.lastElementChild) { diff --git a/src/visualizer.rs b/src/visualizer.rs index 724bc42f..92948778 100644 --- a/src/visualizer.rs +++ b/src/visualizer.rs @@ -3,6 +3,7 @@ use crate::{data::Data, data::ProcessedData, get_file, PDError}; use std::{collections::HashMap, fs::File}; use log::debug; use std::path::{Path, PathBuf}; +use serde::{Deserialize, Serialize}; use rustix::fd::AsRawFd; use std::fs; @@ -130,6 +131,84 @@ impl DataVisualizer { } } +pub enum GraphLimitType { + UInt64(u64), + F64(f64), +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GraphLimits { + pub low: u64, + pub high: u64, + pub init_done: bool, +} + +impl GraphLimits { + pub fn new() -> Self { + GraphLimits { + low: 0, + high: 0, + init_done: false, + } + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GraphMetadata { + pub limits: GraphLimits, +} + +impl GraphMetadata { + pub fn new() -> Self { + GraphMetadata { + limits: GraphLimits::new(), + } + } + + fn update_limit_u64(&mut self, value: u64) { + if !self.limits.init_done { + self.limits.low = value; + self.limits.init_done = true; + } + if value < self.limits.low { + self.limits.low = value; + } + if value > self.limits.high { + self.limits.high = value; + } + } + + fn update_limit_f64(&mut self, value: f64) { + let value_floor = value.floor() as u64; + let value_ceil = value.ceil() as u64; + if !self.limits.init_done { + self.limits.low = value_floor; + self.limits.init_done = true; + } + // Set low + if value_floor < self.limits.low { + self.limits.low = value_floor; + } + if value_ceil < self.limits.low { + self.limits.low = value_ceil; + } + // Set high + if value_floor > self.limits.high { + self.limits.high = value_floor; + } + if value_ceil > self.limits.high { + self.limits.high = value_ceil; + } + } + + pub fn update_limits(&mut self, value: GraphLimitType) { + match value { + GraphLimitType::UInt64(v) => self.update_limit_u64(v), + GraphLimitType::F64(v) => self.update_limit_f64(v), + } + } +} + pub trait GetData { fn get_calls(&mut self) -> Result> { unimplemented!(); From 90e4929a612d09654cfa3485b7f52b229710c597 Mon Sep 17 00:00:00 2001 From: Janakarajan Natarajan Date: Mon, 25 Sep 2023 16:08:44 +0000 Subject: [PATCH 2/7] Add GraphLimits for Diskstats --- src/data/diskstats.rs | 20 ++++++++++++++------ src/html_files/disk_stats.ts | 5 ++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/data/diskstats.rs b/src/data/diskstats.rs index 0e845a65..97488bf1 100644 --- a/src/data/diskstats.rs +++ b/src/data/diskstats.rs @@ -4,7 +4,7 @@ use anyhow::Result; use crate::data::{CollectData, Data, ProcessedData, DataType, TimeEnum}; use crate::data::constants::*; use crate::{PERFORMANCE_DATA, VISUALIZATION_DATA}; -use crate::visualizer::{DataVisualizer, GetData}; +use crate::visualizer::{DataVisualizer, GetData, GraphMetadata, GraphLimitType}; use chrono::prelude::*; use ctor::ctor; use log::trace; @@ -209,9 +209,16 @@ fn get_disk_names(value: Diskstats) -> Vec { names } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct EndDiskValues { + pub data: Vec, + pub metadata: GraphMetadata, +} + fn get_values(values: Vec, key: String) -> Result { let mut ev: BTreeMap = BTreeMap::new(); let disk_names = get_disk_names(values[0].clone()); + let mut metadata = GraphMetadata::new(); let mut factor = FACTOR_OF_ONE; let mut mult_factor = MULT_FACTOR_OF_ONE; for name in disk_names { @@ -248,12 +255,13 @@ fn get_values(values: Vec, key: String) -> Result { time: (v.time - time_zero), value: stat_value, }; + metadata.update_limits(GraphLimitType::F64(stat_value)); let dvs = ev.get_mut(&disk.name).unwrap(); dvs.values.push(dv); } prev_data = v.clone(); } - let end_values: Vec = ev.into_values().collect(); + let end_values = EndDiskValues{data: ev.into_values().collect(), metadata: metadata}; Ok(serde_json::to_string(&end_values)?) } @@ -333,7 +341,7 @@ fn init_diskstats() { #[cfg(test)] mod tests { - use super::{Diskstats, DiskstatsRaw, DiskstatKeys, DiskValues}; + use super::{Diskstats, DiskstatsRaw, DiskstatKeys, EndDiskValues}; use crate::data::{CollectData, Data, ProcessedData}; use crate::visualizer::GetData; use std::collections::HashMap; @@ -401,8 +409,8 @@ mod tests { processed_buffer.push(Diskstats::new().process_raw_data(buf).unwrap()); } let json = Diskstats::new().get_data(processed_buffer, "run=test&get=values&key=Reads".to_string()).unwrap(); - let values: Vec = serde_json::from_str(&json).unwrap(); - assert!(values[0].name != ""); - assert!(values[0].values.len() > 0); + let data: EndDiskValues = serde_json::from_str(&json).unwrap(); + assert!(data.data[0].name != ""); + assert!(data.data[0].values.len() > 0); } } diff --git a/src/html_files/disk_stats.ts b/src/html_files/disk_stats.ts index 018e6ece..b2e8647a 100644 --- a/src/html_files/disk_stats.ts +++ b/src/html_files/disk_stats.ts @@ -3,7 +3,7 @@ let got_disk_stat_data = false; function getStatValues(run, elem, key, run_data) { var disk_datas = []; var data = JSON.parse(run_data); - data.forEach(function (v, i, a) { + data.data.forEach(function (v, i, a) { var x_time = []; var y_data = []; v.values.forEach(function (disk_value, disk_index, disk_arr) { @@ -27,6 +27,7 @@ function getStatValues(run, elem, key, run_data) { } else { unit = 'Count'; } + let limits = key_limits.get(key); var layout = { title: key, xaxis: { @@ -34,6 +35,7 @@ function getStatValues(run, elem, key, run_data) { }, yaxis: { title: unit, + range: [limits.low, limits.high], }, }; Plotly.newPlot(TESTER, disk_datas, layout, { frameMargins: 0 }); @@ -63,6 +65,7 @@ function diskStats(mb: boolean) { } var run_width = 100 / data.length; clearElements('disk-stat-runs'); + form_graph_limits(disk_stats_raw_data); data.forEach(function (value, index, arr) { // Run div var run_div = document.createElement('div'); From 3e5e6163116677df3abac90e2372441a41e2203b Mon Sep 17 00:00:00 2001 From: Janakarajan Natarajan Date: Mon, 25 Sep 2023 16:09:35 +0000 Subject: [PATCH 3/7] Add GraphLimits for Vmstat --- src/data/vmstat.rs | 21 +++++++++++++++------ src/html_files/vmstat.ts | 5 ++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/data/vmstat.rs b/src/data/vmstat.rs index 065b5caa..6fb0908a 100644 --- a/src/data/vmstat.rs +++ b/src/data/vmstat.rs @@ -1,7 +1,7 @@ extern crate ctor; use crate::data::{CollectData, Data, ProcessedData, DataType, TimeEnum}; -use crate::visualizer::{DataVisualizer, GetData}; +use crate::visualizer::{DataVisualizer, GetData, GraphMetadata, GraphLimitType}; use crate::{PDError, PERFORMANCE_DATA, VISUALIZATION_DATA}; use anyhow::Result; use chrono::prelude::*; @@ -61,6 +61,12 @@ impl Vmstat { } } +#[derive(Serialize, Deserialize, Debug, Clone)] +struct EndVmstatData { + pub data: Vec, + pub metadata: GraphMetadata, +} + #[derive(Serialize, Deserialize, Debug, Clone)] struct VmstatEntry { pub time: TimeEnum, @@ -69,6 +75,7 @@ struct VmstatEntry { fn get_entry(values: Vec, key: String) -> Result { let mut end_values = Vec::new(); + let mut metadata = GraphMetadata::new(); let time_zero = values[0].time; let mut prev_vmstat = values[0].clone(); for value in values { @@ -88,6 +95,7 @@ fn get_entry(values: Vec, key: String) -> Result { if !key.contains("nr_") { v = *curr_value - *prev_value; } + metadata.update_limits(GraphLimitType::UInt64(v as u64)); let vmstat_entry = VmstatEntry { time: (current_time - time_zero), value: v, @@ -95,7 +103,8 @@ fn get_entry(values: Vec, key: String) -> Result { end_values.push(vmstat_entry); prev_vmstat = value.clone(); } - Ok(serde_json::to_string(&end_values)?) + let vmstat_data = EndVmstatData {data: end_values, metadata: metadata}; + Ok(serde_json::to_string(&vmstat_data)?) } fn get_entries(value: Vmstat) -> Result { @@ -187,7 +196,7 @@ fn init_vmstat() { #[cfg(test)] mod tests { - use super::{Vmstat, VmstatEntry, VmstatRaw}; + use super::{Vmstat, VmstatRaw, EndVmstatData}; use crate::data::{CollectData, Data, ProcessedData, TimeEnum}; use crate::visualizer::GetData; @@ -223,9 +232,9 @@ mod tests { buffer.push(Data::VmstatRaw(vmstat)); processed_buffer.push(Vmstat::new().process_raw_data(buffer[0].clone()).unwrap()); let json = Vmstat::new().get_data(processed_buffer, "run=test&get=values&key=nr_dirty".to_string()).unwrap(); - let values: Vec = serde_json::from_str(&json).unwrap(); - assert!(values.len() > 0); - match values[0].time { + let data: EndVmstatData = serde_json::from_str(&json).unwrap(); + assert!(data.data.len() > 0); + match data.data[0].time { TimeEnum::TimeDiff(value) => assert!(value == 0), _ => assert!(false), } diff --git a/src/html_files/vmstat.ts b/src/html_files/vmstat.ts index f4fce608..bc7f9d26 100644 --- a/src/html_files/vmstat.ts +++ b/src/html_files/vmstat.ts @@ -17,7 +17,7 @@ function getEntry(run, parent_id, key, run_data) { var data = JSON.parse(run_data); var x_time = []; var y_data = []; - data.forEach(function (value, index, arr) { + data.data.forEach(function (value, index, arr) { x_time.push(value.time.TimeDiff); y_data.push(value.value); }); @@ -30,6 +30,7 @@ function getEntry(run, parent_id, key, run_data) { y: y_data, type: 'scatter', }; + let limits = key_limits.get(key); var layout = { title: `${key}`, xaxis: { @@ -37,6 +38,7 @@ function getEntry(run, parent_id, key, run_data) { }, yaxis: { title: 'Pages', + range: [limits.low, limits.high], }, } Plotly.newPlot(TESTER, [vmstat_data], layout, { frameMargins: 0 }); @@ -53,6 +55,7 @@ function vmStat() { } var run_width = 100 / data.length; clearElements('vmstat-runs'); + form_graph_limits(vmstat_raw_data); data.forEach(function (value, index, arr) { // Run div var run_div = document.createElement('div'); From 29ecd61513328376e1da511d89758e9774aadf86 Mon Sep 17 00:00:00 2001 From: Janakarajan Natarajan Date: Mon, 25 Sep 2023 16:10:03 +0000 Subject: [PATCH 4/7] Add GraphLimits for Netstat --- src/data/netstat.rs | 21 +++++++++++++++------ src/html_files/netstat.ts | 5 ++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/data/netstat.rs b/src/data/netstat.rs index 8253ee7a..2fa91758 100644 --- a/src/data/netstat.rs +++ b/src/data/netstat.rs @@ -1,7 +1,7 @@ extern crate ctor; use crate::data::{CollectData, Data, ProcessedData, DataType, TimeEnum}; -use crate::visualizer::{DataVisualizer, GetData}; +use crate::visualizer::{DataVisualizer, GetData, GraphMetadata, GraphLimitType}; use crate::{PDError, PERFORMANCE_DATA, VISUALIZATION_DATA}; use anyhow::Result; use chrono::prelude::*; @@ -67,8 +67,15 @@ struct NetstatEntry { pub value: u64, } +#[derive(Serialize, Deserialize, Debug, Clone)] +struct EndNetData { + pub data: Vec, + pub metadata: GraphMetadata, +} + fn get_entry(values: Vec, key: String) -> Result { let mut end_values = Vec::new(); + let mut metadata = GraphMetadata::new(); let time_zero = values[0].time; let mut prev_netstat = values[0].clone(); for value in values { @@ -88,10 +95,12 @@ fn get_entry(values: Vec, key: String) -> Result { time: (current_time - time_zero), value: *curr_value - *prev_value, }; + metadata.update_limits(GraphLimitType::UInt64(netstat_entry.value)); end_values.push(netstat_entry); prev_netstat = value.clone(); } - Ok(serde_json::to_string(&end_values)?) + let netdata = EndNetData {data: end_values, metadata: metadata}; + Ok(serde_json::to_string(&netdata)?) } fn get_entries(value: Netstat) -> Result { @@ -202,7 +211,7 @@ fn init_netstat() { #[cfg(test)] mod tests { - use super::{Netstat, NetstatEntry, NetstatRaw}; + use super::{Netstat, NetstatRaw, EndNetData}; use crate::data::{CollectData, Data, ProcessedData, TimeEnum}; use crate::visualizer::GetData; @@ -238,9 +247,9 @@ mod tests { buffer.push(Data::NetstatRaw(netstat)); processed_buffer.push(Netstat::new().process_raw_data(buffer[0].clone()).unwrap()); let json = Netstat::new().get_data(processed_buffer, "run=test&get=values&key=TcpExt: TCPDSACKRecv".to_string()).unwrap(); - let values: Vec = serde_json::from_str(&json).unwrap(); - assert!(values.len() > 0); - match values[0].time { + let data: EndNetData = serde_json::from_str(&json).unwrap(); + assert!(data.data.len() > 0); + match data.data[0].time { TimeEnum::TimeDiff(value) => assert!(value == 0), _ => assert!(false), } diff --git a/src/html_files/netstat.ts b/src/html_files/netstat.ts index 03df5196..3d9feebb 100644 --- a/src/html_files/netstat.ts +++ b/src/html_files/netstat.ts @@ -17,7 +17,7 @@ function getNetstatEntry(run, parent_id, key, run_data) { var data = JSON.parse(run_data); var x_time = []; var y_data = []; - data.forEach(function (value, index, arr) { + data.data.forEach(function (value, index, arr) { x_time.push(value.time.TimeDiff); y_data.push(value.value); }); @@ -30,6 +30,7 @@ function getNetstatEntry(run, parent_id, key, run_data) { y: y_data, type: 'scatter', }; + let limits = key_limits.get(key); var layout = { title: `${key}`, xaxis: { @@ -37,6 +38,7 @@ function getNetstatEntry(run, parent_id, key, run_data) { }, yaxis: { title: 'Count', + range: [limits.low, limits.high], }, } Plotly.newPlot(TESTER, [netstat_data], layout, { frameMargins: 0 }); @@ -53,6 +55,7 @@ function netStat() { } var run_width = 100 / data.length; clearElements('netstat-runs'); + form_graph_limits(netstat_raw_data); data.forEach(function (value, index, arr) { // Run div var run_div = document.createElement('div'); From da1455da029d9ec804df88cdda4d8ce7dea1689d Mon Sep 17 00:00:00 2001 From: Janakarajan Natarajan Date: Mon, 25 Sep 2023 16:11:15 +0000 Subject: [PATCH 5/7] Add GraphLimits for PerfStat --- src/data/perf_stat.rs | 14 ++++++++++++-- src/html_files/perf_stat.ts | 7 +++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/data/perf_stat.rs b/src/data/perf_stat.rs index 36e8eb98..5998fa6d 100644 --- a/src/data/perf_stat.rs +++ b/src/data/perf_stat.rs @@ -3,7 +3,7 @@ extern crate ctor; use anyhow::Result; use crate::data::{CollectData, Data, ProcessedData, CollectorParams, DataType, TimeEnum}; use crate::{PERFORMANCE_DATA, VISUALIZATION_DATA}; -use crate::visualizer::{DataVisualizer, GetData}; +use crate::visualizer::{DataVisualizer, GetData, GraphMetadata, GraphLimitType}; use chrono::prelude::*; use ctor::ctor; use log::{trace, error}; @@ -319,8 +319,15 @@ fn get_named_stat_for_all_cpus(value: PerfStat, key: String) -> Vec { return named_stats; } +#[derive(Serialize, Deserialize, Debug, Clone)] +struct EndPerfData { + pub data: Vec, + pub metadata: GraphMetadata, +} + fn get_values(values: Vec, key: String) -> Result { let time_zero = &values[0].perf_stats[0].named_stats[0].time; + let mut metadata = GraphMetadata::new(); let mut end_values = Vec::new(); let mut aggregate_value: f64; for value in &values { @@ -332,11 +339,13 @@ fn get_values(values: Vec, key: String) -> Result { for stat in &stats { let this_cpu_end_stat_value = stat.named_stat.nr_value as f64 / stat.named_stat.dr_value as f64; let this_cpu_end_stat = EndStat { cpu: stat.cpu as i64, value: this_cpu_end_stat_value * stat.named_stat.scale as f64 }; + metadata.update_limits(GraphLimitType::F64(this_cpu_end_stat.value)); end_cpu_stats.push(this_cpu_end_stat); aggregate_nr += stat.named_stat.nr_value; aggregate_dr += stat.named_stat.dr_value; } aggregate_value = (aggregate_nr as f64 / aggregate_dr as f64) * stats[0].named_stat.scale as f64; + metadata.update_limits(GraphLimitType::F64(aggregate_value)); let aggr_cpu_stat = EndStat { cpu: -1, value: aggregate_value }; end_cpu_stats.push(aggr_cpu_stat); @@ -344,7 +353,8 @@ fn get_values(values: Vec, key: String) -> Result { end_stats.cpus = end_cpu_stats; end_values.push(end_stats); } - Ok(serde_json::to_string(&end_values)?) + let perf_data = EndPerfData {data: end_values, metadata: metadata}; + Ok(serde_json::to_string(&perf_data)?) } fn get_named_events(value: PerfStat) -> Result { diff --git a/src/html_files/perf_stat.ts b/src/html_files/perf_stat.ts index 2829e980..7bf36222 100644 --- a/src/html_files/perf_stat.ts +++ b/src/html_files/perf_stat.ts @@ -37,14 +37,14 @@ function addData(perfstat_data, stat, timediff) { function getEvent(run, parent_id, key, run_data) { var data = JSON.parse(run_data); var perfstat_datas = []; - data[0].cpus.forEach(function (value, index, arr) { + data.data[0].cpus.forEach(function (value, index, arr) { var cpu_stat = new StatValue(); cpu_stat.cpu = value.cpu; cpu_stat.x_time = []; cpu_stat.y_data = []; perfstat_datas.push(cpu_stat); }); - data.forEach(function (value, index, arr) { + data.data.forEach(function (value, index, arr) { value.cpus.forEach(function (stat, i_index, i_arr) { addData(perfstat_datas, stat, value.time.TimeDiff); }) @@ -70,6 +70,7 @@ function getEvent(run, parent_id, key, run_data) { }; end_datas.push(perfstat_line); }) + let limits = key_limits.get(key); var layout = { title: `${key}`, xaxis: { @@ -77,6 +78,7 @@ function getEvent(run, parent_id, key, run_data) { }, yaxis: { title: 'Count', + range: [limits.low, limits.high], }, } Plotly.newPlot(TESTER, end_datas, layout, { frameMargins: 0 }); @@ -93,6 +95,7 @@ function perfStat() { } var run_width = 100 / data.length; clearElements('perfstat-runs'); + form_graph_limits(perf_stat_raw_data); data.forEach(function (value, index, arr) { // Run div var run_div = document.createElement('div'); From a0ee04e0382ed5c61edf09f9726b3b5a89e14e45 Mon Sep 17 00:00:00 2001 From: Janakarajan Natarajan Date: Mon, 25 Sep 2023 16:12:14 +0000 Subject: [PATCH 6/7] Add GraphLimits for MeminfoData --- src/data/meminfodata.rs | 24 ++++++++++++------ src/html_files/meminfo.ts | 53 +++++++++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/data/meminfodata.rs b/src/data/meminfodata.rs index 85ee5052..df78931a 100644 --- a/src/data/meminfodata.rs +++ b/src/data/meminfodata.rs @@ -3,7 +3,7 @@ extern crate ctor; use anyhow::Result; use crate::data::{CollectData, Data, ProcessedData, DataType, TimeEnum}; use crate::{PDError, PERFORMANCE_DATA, VISUALIZATION_DATA}; -use crate::visualizer::{DataVisualizer, GetData}; +use crate::visualizer::{DataVisualizer, GetData, GraphMetadata, GraphLimitType}; use chrono::prelude::*; use ctor::ctor; use log::{trace}; @@ -163,17 +163,27 @@ pub struct MemEntry { pub value: u64, } +#[derive(Serialize, Deserialize, Debug, Clone)] +struct EndMemValues { + pub data: MemData, + pub metadata: GraphMetadata, +} + fn get_values(values: Vec, key: String) -> Result { let time_zero = values[0].time; + let mut metadata = GraphMetadata::new(); let mut end_value = MemData {name: key.clone(), values: Vec::new()}; for v in values { let value = v.data .get(&key) .ok_or(PDError::VisualizerMeminfoValueGetError(key.to_string()))?; - let mementry = MemEntry {time: v.time - time_zero, value: *value}; + /* Bytes => kB */ + let mementry = MemEntry {time: v.time - time_zero, value: *value / 1024}; + metadata.update_limits(GraphLimitType::UInt64(mementry.value)); end_value.values.push(mementry); } - return Ok(serde_json::to_string(&end_value)?) + let end_values = EndMemValues {data: end_value, metadata: metadata}; + return Ok(serde_json::to_string(&end_values)?) } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -332,7 +342,7 @@ fn init_meminfo() { #[cfg(test)] mod tests { - use super::{MeminfoDataRaw, MeminfoData, MeminfoKeys, MemData}; + use super::{MeminfoDataRaw, MeminfoData, MeminfoKeys, EndMemValues}; use crate::data::{CollectData, Data, ProcessedData}; use crate::visualizer::GetData; use std::collections::HashMap; @@ -400,8 +410,8 @@ mod tests { processed_buffer.push(MeminfoData::new().process_raw_data(buf).unwrap()); } let json = MeminfoData::new().get_data(processed_buffer, "run=test&get=values&key=Mem Total".to_string()).unwrap(); - let memdata: MemData = serde_json::from_str(&json).unwrap(); - assert!(memdata.name == "Mem Total"); - assert!(memdata.values.len() > 0); + let memdata: EndMemValues = serde_json::from_str(&json).unwrap(); + assert!(memdata.data.name == "Mem Total"); + assert!(memdata.data.values.len() > 0); } } diff --git a/src/html_files/meminfo.ts b/src/html_files/meminfo.ts index 9e794c0f..51d38916 100644 --- a/src/html_files/meminfo.ts +++ b/src/html_files/meminfo.ts @@ -1,12 +1,43 @@ let got_meminfo_data = false; let TB = 1073741824; let GB = 1048576; -function get_divisor_unit(values) { + +let meminfo_average: Map = new Map(); +function form_meminfo_averages() { + runs_raw.forEach(function (value, index, arr) { + let this_run_data; + for (let i = 0; i < meminfo_raw_data['runs'].length; i++) { + if (meminfo_raw_data['runs'][i]['name'] == value) { + this_run_data = meminfo_raw_data['runs'][i]; + let keys = this_run_data['keys']; + let values = this_run_data['key_values']; + keys.forEach(function (v, i, a) { + var run_data = JSON.parse(values[v]); + let y_data = []; + run_data.data.values.forEach(function (rv, ri, ra) { + y_data.push(rv.value); + }) + var total = 0; + for (i = 0; i < y_data.length; i++) { + total += y_data[i]; + } + let average = total / y_data.length; + if (meminfo_average.has(v)) { + if (average > meminfo_average.get(v)) { + meminfo_average.set(v, average); + } + } else { + meminfo_average.set(v, average); + } + }); + } + } + }); +} + +function get_divisor_unit(key) { var total = 0; - for (i = 0; i < values.length; i++) { - total += values[i]; - } - let average = total / values.length; + let average = meminfo_average.get(key); if (average > TB) { return { divisor: TB, @@ -29,14 +60,12 @@ function getMeminfo(elem, key, run_data) { var data = JSON.parse(run_data); var x_data = []; var y_data = []; - data.values.forEach(function (value, index, arr) { + data.data.values.forEach(function (value, index, arr) { x_data.push(value.time.TimeDiff); - - /* Bytes => kB */ - y_data.push(value.value / 1024); + y_data.push(value.value); }) - var { divisor, unit } = get_divisor_unit(y_data); + var { divisor, unit } = get_divisor_unit(key); if (key.includes("Mem Total") || key.includes("Vmalloc Total") || key.includes("Hugepagesize")) { @@ -62,6 +91,7 @@ function getMeminfo(elem, key, run_data) { type: 'scatter', }; var TESTER = elem; + let limits = key_limits.get(key); var layout = { title: key, xaxis: { @@ -69,6 +99,7 @@ function getMeminfo(elem, key, run_data) { }, yaxis: { title: `${unit}`, + range: [limits.low/divisor, limits.high/divisor], } }; Plotly.newPlot(TESTER, [meminfodata], layout, { frameMargins: 0 }); @@ -98,6 +129,8 @@ function meminfo() { } var run_width = 100 / data.length; clearElements('meminfo-runs'); + form_meminfo_averages(); + form_graph_limits(meminfo_raw_data); data.forEach(function (value, index, arr) { // Run div var run_div = document.createElement('div'); From d3564162cbd7283e25ce29768363e5bbb3a696e6 Mon Sep 17 00:00:00 2001 From: Janakarajan Natarajan Date: Mon, 25 Sep 2023 16:12:34 +0000 Subject: [PATCH 7/7] Set got_meminfo_data after getting the data --- src/html_files/meminfo.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/html_files/meminfo.ts b/src/html_files/meminfo.ts index 51d38916..cbafd5ba 100644 --- a/src/html_files/meminfo.ts +++ b/src/html_files/meminfo.ts @@ -158,4 +158,5 @@ function meminfo() { } } }) + got_meminfo_data = true; } \ No newline at end of file