Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aperf: Add support for analytics #241

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ cfg-if = "1.0"
tempfile = "3"
serial_test = "3.1.1"
log4rs = "1.3.0"
tdigest = "0.2"
11 changes: 4 additions & 7 deletions src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ pub mod systeminfo;
pub mod utils;
pub mod vmstat;

use crate::utils::DataMetrics;
use crate::visualizer::{GetData, ReportParams};
use crate::{InitParams, APERF_FILE_FORMAT};
use crate::{noop, InitParams, APERF_FILE_FORMAT};
use anyhow::Result;
use aperf_runlog::AperfRunlog;
use aperf_stats::AperfStat;
Expand Down Expand Up @@ -285,10 +286,10 @@ macro_rules! processed_data {
)*
}
}
pub fn get_data(&mut self, values: Vec<ProcessedData>, query: String) -> Result<String> {
pub fn get_data(&mut self, values: Vec<ProcessedData>, query: String, metrics: &mut DataMetrics) -> Result<String> {
match self {
$(
ProcessedData::$x(ref mut value) => Ok(value.get_data(values, query)?),
ProcessedData::$x(ref mut value) => Ok(value.get_data(values, query, metrics)?),
)*
}
}
Expand Down Expand Up @@ -339,10 +340,6 @@ processed_data!(
JavaProfile
);

macro_rules! noop {
() => {};
}

pub trait CollectData {
fn prepare_data_collector(&mut self, _params: &CollectorParams) -> Result<()> {
noop!();
Expand Down
8 changes: 7 additions & 1 deletion src/data/aperf_runlog.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
extern crate ctor;

use crate::utils::DataMetrics;
use crate::visualizer::{DataVisualizer, GetData, ReportParams};
use crate::{data::ProcessedData, APERF_RUNLOG, VISUALIZATION_DATA};
use anyhow::Result;
Expand Down Expand Up @@ -47,7 +48,12 @@ impl GetData for AperfRunlog {
Ok(vec!["values".to_string()])
}

fn get_data(&mut self, buffer: Vec<ProcessedData>, _query: String) -> Result<String> {
fn get_data(
&mut self,
buffer: Vec<ProcessedData>,
_query: String,
_metrics: &mut DataMetrics,
) -> Result<String> {
let mut values = Vec::new();
for data in buffer {
match data {
Expand Down
8 changes: 7 additions & 1 deletion src/data/aperf_stats.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
extern crate ctor;

use crate::data::{ProcessedData, TimeEnum};
use crate::utils::DataMetrics;
use crate::visualizer::{DataVisualizer, GetData, GraphLimitType, GraphMetadata, ReportParams};
use crate::VISUALIZATION_DATA;
use anyhow::Result;
Expand Down Expand Up @@ -103,7 +104,12 @@ impl GetData for AperfStat {
Ok(vec!["keys".to_string(), "values".to_string()])
}

fn get_data(&mut self, buffer: Vec<ProcessedData>, query: String) -> Result<String> {
fn get_data(
&mut self,
buffer: Vec<ProcessedData>,
query: String,
_metrics: &mut DataMetrics,
) -> Result<String> {
let mut values = Vec::new();
for data in buffer {
match data {
Expand Down
55 changes: 50 additions & 5 deletions src/data/cpu_utilization.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
extern crate ctor;

use crate::data::{CollectData, CollectorParams, Data, DataType, ProcessedData, TimeEnum};
use crate::utils::{DataMetrics, Metric};
use crate::visualizer::{DataVisualizer, GetData};
use crate::{PERFORMANCE_DATA, VISUALIZATION_DATA};
use anyhow::Result;
Expand All @@ -9,6 +10,7 @@ use ctor::ctor;
use log::trace;
use procfs::{CpuTime, KernelStats};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::ops::Sub;

pub static CPU_UTILIZATION_FILE_NAME: &str = "cpu_utilization";
Expand Down Expand Up @@ -239,10 +241,19 @@ fn set_as_percent(value: UtilValues) -> UtilValues {
new_values
}

pub fn get_aggregate_data(values: Vec<CpuData>) -> Result<String> {
pub fn get_aggregate_data(values: Vec<CpuData>, metrics: &mut DataMetrics) -> Result<String> {
let mut end_values = Vec::new();
let mut prev_cpu_data = values[0].values;
let time_zero = values[0].time;
let mut metric_map = HashMap::new();
let mut user = Metric::new("User".to_string());
let mut nice = Metric::new("Nice".to_string());
let mut system = Metric::new("System".to_string());
let mut irq = Metric::new("Irq".to_string());
let mut softirq = Metric::new("SoftIrq".to_string());
let mut idle = Metric::new("Idle".to_string());
let mut iowait = Metric::new("Iowait".to_string());
let mut steal = Metric::new("Steal".to_string());
for value in values {
let mut end_value = CpuData::new();
let current_cpu_data = value.values;
Expand All @@ -254,10 +265,29 @@ pub fn get_aggregate_data(values: Vec<CpuData>) -> Result<String> {
}
end_value.cpu = value.cpu;
end_value.values = set_as_percent(current_cpu_data - prev_cpu_data);
user.insert_value(end_value.values.user as f64);
nice.insert_value(end_value.values.nice as f64);
system.insert_value(end_value.values.system as f64);
irq.insert_value(end_value.values.irq as f64);
softirq.insert_value(end_value.values.softirq as f64);
idle.insert_value(end_value.values.idle as f64);
iowait.insert_value(end_value.values.iowait as f64);
steal.insert_value(end_value.values.steal as f64);
end_value.set_time(current_time - time_zero);
end_values.push(end_value);
prev_cpu_data = current_cpu_data;
}
metric_map.insert("User".to_string(), user.form_stats());
metric_map.insert("Nice".to_string(), nice.form_stats());
metric_map.insert("System".to_string(), system.form_stats());
metric_map.insert("Irq".to_string(), irq.form_stats());
metric_map.insert("SoftIrq".to_string(), softirq.form_stats());
metric_map.insert("Idle".to_string(), idle.form_stats());
metric_map.insert("Iowait".to_string(), iowait.form_stats());
metric_map.insert("Steal".to_string(), steal.form_stats());
metrics
.values
.insert(CPU_UTILIZATION_FILE_NAME.to_string(), metric_map);
Ok(serde_json::to_string(&end_values)?)
}

Expand Down Expand Up @@ -331,7 +361,12 @@ impl GetData for CpuUtilization {
Ok(vec!["keys".to_string(), "values".to_string()])
}

fn get_data(&mut self, buffer: Vec<ProcessedData>, query: String) -> Result<String> {
fn get_data(
&mut self,
buffer: Vec<ProcessedData>,
query: String,
metrics: &mut DataMetrics,
) -> Result<String> {
let mut values = Vec::new();
for data in buffer {
match data {
Expand Down Expand Up @@ -364,7 +399,7 @@ impl GetData for CpuUtilization {
for value in values {
temp_values.push(value.total);
}
get_aggregate_data(temp_values)
get_aggregate_data(temp_values, metrics)
} else {
get_type(values[0].per_cpu.len() as u64, values, key)
}
Expand Down Expand Up @@ -407,6 +442,7 @@ fn init_cpu_utilization() {
mod cpu_tests {
use super::{CpuData, CpuUtilization, CpuUtilizationRaw, UtilData};
use crate::data::{CollectData, CollectorParams, Data, ProcessedData};
use crate::utils::DataMetrics;
use crate::visualizer::GetData;

#[test]
Expand Down Expand Up @@ -438,6 +474,7 @@ mod cpu_tests {
.get_data(
processed_buffer,
"run=test&get=values&=aggregate".to_string(),
&mut DataMetrics::new(String::new()),
)
.unwrap();
let values: Vec<CpuData> = serde_json::from_str(&json).unwrap();
Expand All @@ -447,7 +484,11 @@ mod cpu_tests {
#[test]
fn test_get_util_types() {
let types = CpuUtilization::new()
.get_data(Vec::new(), "run=test&get=keys".to_string())
.get_data(
Vec::new(),
"run=test&get=keys".to_string(),
&mut DataMetrics::new(String::new()),
)
.unwrap();
let values: Vec<&str> = serde_json::from_str(&types).unwrap();
for type_str in values {
Expand Down Expand Up @@ -476,7 +517,11 @@ mod cpu_tests {
processed_buffer.push(CpuUtilization::new().process_raw_data(buf).unwrap());
}
let json = CpuUtilization::new()
.get_data(processed_buffer, "run=test&get=values&key=user".to_string())
.get_data(
processed_buffer,
"run=test&get=values&key=user".to_string(),
&mut DataMetrics::new(String::new()),
)
.unwrap();
let values: Vec<UtilData> = serde_json::from_str(&json).unwrap();
assert!(!values.is_empty());
Expand Down
16 changes: 14 additions & 2 deletions src/data/diskstats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ extern crate ctor;

use crate::data::constants::*;
use crate::data::{CollectData, CollectorParams, Data, DataType, ProcessedData, TimeEnum};
use crate::utils::DataMetrics;
use crate::visualizer::{DataVisualizer, GetData, GraphLimitType, GraphMetadata};
use crate::{PERFORMANCE_DATA, VISUALIZATION_DATA};
use anyhow::Result;
Expand Down Expand Up @@ -308,7 +309,12 @@ impl GetData for Diskstats {
Ok(vec!["keys".to_string(), "values".to_string()])
}

fn get_data(&mut self, buffer: Vec<ProcessedData>, query: String) -> Result<String> {
fn get_data(
&mut self,
buffer: Vec<ProcessedData>,
query: String,
_metrics: &mut DataMetrics,
) -> Result<String> {
let mut values = Vec::new();
for data in buffer {
match data {
Expand Down Expand Up @@ -364,6 +370,7 @@ fn init_diskstats() {
mod tests {
use super::{DiskstatKeys, Diskstats, DiskstatsRaw, EndDiskValues};
use crate::data::{CollectData, CollectorParams, Data, ProcessedData};
use crate::utils::DataMetrics;
use crate::visualizer::GetData;
use std::collections::HashMap;
use strum::IntoEnumIterator;
Expand Down Expand Up @@ -420,7 +427,11 @@ mod tests {
.unwrap(),
);
let json = Diskstats::new()
.get_data(processed_buffer, "run=test&get=keys".to_string())
.get_data(
processed_buffer,
"run=test&get=keys".to_string(),
&mut DataMetrics::new(String::new()),
)
.unwrap();
let values: Vec<String> = serde_json::from_str(&json).unwrap();
assert!(!values.is_empty());
Expand All @@ -445,6 +456,7 @@ mod tests {
.get_data(
processed_buffer,
"run=test&get=values&key=Reads".to_string(),
&mut DataMetrics::new(String::new()),
)
.unwrap();
let data: EndDiskValues = serde_json::from_str(&json).unwrap();
Expand Down
10 changes: 8 additions & 2 deletions src/data/flamegraphs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
extern crate ctor;

use crate::data::{CollectData, CollectorParams, Data, DataType, ProcessedData};
use crate::utils::DataMetrics;
use crate::visualizer::{DataVisualizer, GetData, ReportParams};
use crate::{get_file_name, PDError, PERFORMANCE_DATA, VISUALIZATION_DATA};
use anyhow::Result;
Expand Down Expand Up @@ -63,7 +64,7 @@ impl CollectData for FlamegraphRaw {
"inject",
"-j",
"-i",
&file_pathbuf.to_str().unwrap(),
file_pathbuf.to_str().unwrap(),
"-o",
perf_jit_loc.to_str().unwrap(),
])
Expand Down Expand Up @@ -149,7 +150,12 @@ impl GetData for Flamegraph {
Ok(vec!["values".to_string()])
}

fn get_data(&mut self, _buffer: Vec<ProcessedData>, _query: String) -> Result<String> {
fn get_data(
&mut self,
_buffer: Vec<ProcessedData>,
_query: String,
_metrics: &mut DataMetrics,
) -> Result<String> {
let values: Vec<&str> = Vec::new();
Ok(serde_json::to_string(&values)?)
}
Expand Down
27 changes: 23 additions & 4 deletions src/data/interrupts.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
extern crate ctor;

use crate::data::{CollectData, CollectorParams, Data, DataType, ProcessedData, TimeEnum};
use crate::utils::DataMetrics;
use crate::visualizer::{DataVisualizer, GetData};
use crate::{PDError, PERFORMANCE_DATA, VISUALIZATION_DATA};
use anyhow::Result;
Expand Down Expand Up @@ -289,7 +290,12 @@ impl GetData for InterruptData {
Ok(vec!["keys".to_string(), "values".to_string()])
}

fn get_data(&mut self, buffer: Vec<ProcessedData>, query: String) -> Result<String> {
fn get_data(
&mut self,
buffer: Vec<ProcessedData>,
query: String,
_metrics: &mut DataMetrics,
) -> Result<String> {
let mut values = Vec::new();
for data in buffer {
match data {
Expand Down Expand Up @@ -345,6 +351,7 @@ mod tests {
use super::{InterruptData, InterruptDataRaw, InterruptLine, InterruptLineData};
use crate::data::{CollectData, CollectorParams, Data, ProcessedData};
use crate::get_file;
use crate::utils::DataMetrics;
use crate::visualizer::{DataVisualizer, GetData};

#[test]
Expand Down Expand Up @@ -412,7 +419,11 @@ mod tests {
processed_buffer.push(InterruptData::new().process_raw_data(buf).unwrap());
}
let json = InterruptData::new()
.get_data(processed_buffer, "run=test&get=keys".to_string())
.get_data(
processed_buffer,
"run=test&get=keys".to_string(),
&mut DataMetrics::new(String::new()),
)
.unwrap();
let values: Vec<String> = serde_json::from_str(&json).unwrap();
assert!(!values.is_empty());
Expand All @@ -432,12 +443,20 @@ mod tests {
processed_buffer.push(InterruptData::new().process_raw_data(buf).unwrap());
}
let json = InterruptData::new()
.get_data(processed_buffer.clone(), "run=test&get=keys".to_string())
.get_data(
processed_buffer.clone(),
"run=test&get=keys".to_string(),
&mut DataMetrics::new(String::new()),
)
.unwrap();
let values: Vec<String> = serde_json::from_str(&json).unwrap();
let key_query = format!("run=test&get=values&key={}", values[0]);
let ld_json = InterruptData::new()
.get_data(processed_buffer, key_query)
.get_data(
processed_buffer,
key_query,
&mut DataMetrics::new(String::new()),
)
.unwrap();
let line_data: Vec<InterruptLineData> = serde_json::from_str(&ld_json).unwrap();
assert!(!line_data.is_empty());
Expand Down
Loading
Loading