-
Notifications
You must be signed in to change notification settings - Fork 13
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
base: main
Are you sure you want to change the base?
Conversation
src/lib.rs
Outdated
@@ -180,6 +187,7 @@ impl PerformanceData { | |||
let meta_data_handle = fs::OpenOptions::new() | |||
.create(true) | |||
.write(true) | |||
.truncate(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given it's an error when any output directory already exists, in what scenario is this code encountering an existing file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Removed. It was a suggestion from a different version of clippy.
src/utils.rs
Outdated
pub p50: f64, | ||
pub mean: f64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mean and p50 are virtually interchangeable, I'd dump p50 and add p90.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. Changing it to p90.
src/html_files/analytics.ts
Outdated
|
||
class Finding { | ||
text: string; | ||
status: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the type 'string' instead of 'Status'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. Good catch. It's simpler to have the Status everywhere.
src/html_files/analytics.ts
Outdated
function is_unique_map(values_map) { | ||
return new Set([...values_map.values()]).size == 1; | ||
} | ||
|
||
function is_unique_array(values_array) { | ||
return new Set(values_array).size == 1; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are odd definitions of 'unique'. It suggests that somewhere else you're using the wrong data type if you have to call into something to de-duplicate and check the size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. We're using arrays everywhere now. We were using arrays and maps. This is cleaner.
src/html_files/cpu_utilization.ts
Outdated
rules: [ | ||
{ | ||
name: "User", | ||
func: function (ruleOpts: RuleOpts) { | ||
let system_util = get_data_key(ruleOpts.data_type, "System"); | ||
let findings = []; | ||
let init_key = ruleOpts.runs[0]; | ||
let init_total_util: number = ruleOpts.per_run_data.get(init_key) + system_util.get(init_key); | ||
for (const [key, value] of ruleOpts.per_run_data) { | ||
if (key == init_key) { | ||
continue; | ||
} | ||
let run_total_util: number = value + system_util.get(key); | ||
let cpu_diff = Math.ceil(Math.abs(run_total_util - init_total_util)); | ||
findings.push(new Finding( | ||
`Average CPU Utilization difference between ${init_key} and ${key} is ${cpu_diff}%.`, | ||
cpu_diff > 10 ? Status.NotGood : Status.Good, | ||
)); | ||
} | ||
return findings; | ||
}, | ||
good: "", | ||
bad: "", | ||
}, | ||
{ | ||
name: "idle", | ||
func: function (ruleOpts: RuleOpts) { | ||
let findings = []; | ||
let init_key = ruleOpts.runs[0]; | ||
for (const [key, value] of ruleOpts.per_run_data) { | ||
if (key == init_key) { | ||
continue; | ||
} | ||
let idle_diff = Math.abs(ruleOpts.per_run_data.get(key) - ruleOpts.per_run_data.get(init_key)); | ||
if (idle_diff > 10) { | ||
findings.push(new Finding( | ||
`Difference in Average 'Idle time' between ${key} and ${init_key} is ${idle_diff}.`, | ||
)); | ||
} | ||
} | ||
return findings; | ||
}, | ||
good: "", | ||
bad: "", | ||
} | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So rules don't start turning into copy-and-paste-fests of eachother, start refactoring this now so that things as simple as comparing aggregates across runs is not duplicated in multiple rules's 'func's.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm splitting it up into 3 types of rules.
- Runs == 1, Rules to point out things. Rules are implemented in single_run_rules[].
- Runs > 1,
a. Set base run = Runs[0]. Iterate over the other runs and pass in base_run and other run to a function. Prevents needing repeat for loops for all rules. Rules are implemented in per_run_rules[].
b. Provide all details to a different set of functions which needs all the details. Rules are implemented in all_run_rules[].
src/html_files/system_info.ts
Outdated
func: function (ruleOpts: RuleOpts) { | ||
return is_unique_map(ruleOpts.per_run_data); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cpu utilization rules are returning arrays of Findings, and this is returning boolean. Lock this function signature down or it will be a nightmare to maintain having to support a wide variety of return types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. I'm changing it so that only Finding should be returned.
This is in preparation for adding rules for SystemInfo and CPU Utilization.
Form the metrics which will be used by the front-end for analytics work. Generate it for SystemInfo and CPU Utilization.
Attached a newer version of the report. The SUT Config and Findings are now clubbed together in a single tab. |
Add base support for Aperf Analytics. The stats are formed and created in the Aperf Rust backend. These values are then acted on by the rules in the Javascript frontend. Basic implementation for the keys in 'SystemInfo' and 'CPU Utilization' show how the rules can operate using the API provided.
Attached is a report comparing two runs. The output of the rules are shown in the landing page 'SystemInfo' tab.
build_metrics.tar.gz
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.