Skip to content

Commit

Permalink
Create a tmp directory for record and report
Browse files Browse the repository at this point in the history
Also, move to using references where possible for the Data trait.
  • Loading branch information
janaknat committed Sep 11, 2024
1 parent 039d598 commit bb815df
Show file tree
Hide file tree
Showing 13 changed files with 108 additions and 114 deletions.
20 changes: 16 additions & 4 deletions src/bin/aperf.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use anyhow::Result;
use aperf_lib::record::{record, Record};
use aperf_lib::report::{report, Report};
use aperf_lib::PDError;
use aperf_lib::{PDError, APERF_TMP};
use clap::{Parser, Subcommand};
use env_logger::Builder;
use log::LevelFilter;
use std::{fs, os::unix::fs::PermissionsExt};
use tempfile::Builder as TempBuilder;

#[derive(Parser)]
#[command(author, about, long_about = None)]
Expand All @@ -18,6 +20,10 @@ struct Cli {
/// Show debug messages. Use -vv for more verbose messages.
#[clap(short, long, global = true, action = clap::ArgAction::Count)]
verbose: u8,

/// Temporary directory for intermediate files.
#[clap(short, long, value_parser, default_value_t = APERF_TMP.to_string(), global = true)]
tmp_dir: String,
}

#[derive(Subcommand)]
Expand All @@ -42,11 +48,17 @@ fn init_logger(verbose: u8) -> Result<()> {

fn main() -> Result<()> {
let cli = Cli::parse();

let tmp_dir = TempBuilder::new().prefix("aperf-tmp-").tempdir_in(&cli.tmp_dir)?;
fs::set_permissions(&tmp_dir, fs::Permissions::from_mode(0o1777))?;
let tmp_dir_path_buf = tmp_dir.path().to_path_buf();

init_logger(cli.verbose)?;

match &cli.command {
Commands::Record(r) => record(r),
Commands::Report(r) => report(r),
match cli.command {
Commands::Record(r) => record(&r, &tmp_dir_path_buf),
Commands::Report(r) => report(&r, &tmp_dir_path_buf),
}?;
fs::remove_dir_all(tmp_dir_path_buf)?;
Ok(())
}
40 changes: 18 additions & 22 deletions src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,31 +119,30 @@ impl DataType {
self.collector_params.signal = signal;
}

pub fn init_data_type(&mut self, param: InitParams) -> Result<()> {
pub fn init_data_type(&mut self, param: &InitParams) -> Result<()> {
trace!("Initializing data type...");
let name = format!(
"{}_{}.{}",
self.file_name, param.time_str, APERF_FILE_FORMAT
);
let full_path = format!("{}/{}", param.dir_name, name);

self.file_name = name;
self.full_path = full_path.clone();
self.file_name = name.clone();
self.full_path = format!("{}/{}", param.dir_name, name);
self.dir_name = param.dir_name.clone();
self.collector_params.run_name = param.dir_name.clone();
self.collector_params.collection_time = param.period;
self.collector_params.elapsed_time = 0;
self.collector_params.data_file_path = PathBuf::from(full_path);
self.collector_params.data_dir = PathBuf::from(param.dir_name);
self.collector_params.data_file_path = PathBuf::from(&self.full_path);
self.collector_params.data_dir = PathBuf::from(param.dir_name.clone());
self.collector_params.profile = param.profile.clone();
self.collector_params.tmp_dir = PathBuf::from(param.tmp_dir);
self.collector_params.tmp_dir = param.tmp_dir.clone();

self.file_handle = Some(
OpenOptions::new()
.read(true)
.create(true)
.append(true)
.open(self.full_path.clone())
.open(&self.full_path)
.expect("Could not create file for data"),
);

Expand All @@ -152,8 +151,7 @@ impl DataType {

pub fn prepare_data_collector(&mut self) -> Result<()> {
trace!("Preparing data collector...");
self.data
.prepare_data_collector(self.collector_params.clone())?;
self.data.prepare_data_collector(&self.collector_params)?;
Ok(())
}

Expand All @@ -172,15 +170,13 @@ impl DataType {

pub fn finish_data_collection(&mut self) -> Result<()> {
trace!("Finish data collection...");
self.data
.finish_data_collection(self.collector_params.clone())?;
self.data.finish_data_collection(&self.collector_params)?;
Ok(())
}

pub fn after_data_collection(&mut self) -> Result<()> {
trace!("Running post collection actions...");
self.data
.after_data_collection(self.collector_params.clone())?;
self.data.after_data_collection(&self.collector_params)?;
Ok(())
}
}
Expand Down Expand Up @@ -231,7 +227,7 @@ macro_rules! data {
Ok(())
}

fn prepare_data_collector(&mut self, params: CollectorParams) -> Result<()> {
fn prepare_data_collector(&mut self, params: &CollectorParams) -> Result<()> {
match self {
$(
Data::$x(ref mut value) => value.prepare_data_collector(params)?,
Expand All @@ -240,15 +236,15 @@ macro_rules! data {
Ok(())
}

fn finish_data_collection(&mut self, params: CollectorParams) -> Result<()> {
fn finish_data_collection(&mut self, params: &CollectorParams) -> Result<()> {
match self {
$(
Data::$x(ref mut value) => value.finish_data_collection(params)?,
)*
}
Ok(())
}
fn after_data_collection(&mut self, params: CollectorParams) -> Result<()> {
fn after_data_collection(&mut self, params: &CollectorParams) -> Result<()> {
match self {
$(
Data::$x(ref mut value) => value.after_data_collection(params)?,
Expand Down Expand Up @@ -342,19 +338,19 @@ macro_rules! noop {
}

pub trait CollectData {
fn prepare_data_collector(&mut self, _params: CollectorParams) -> Result<()> {
fn prepare_data_collector(&mut self, _params: &CollectorParams) -> Result<()> {
noop!();
Ok(())
}
fn collect_data(&mut self, _params: &CollectorParams) -> Result<()> {
noop!();
Ok(())
}
fn finish_data_collection(&mut self, _params: CollectorParams) -> Result<()> {
fn finish_data_collection(&mut self, _params: &CollectorParams) -> Result<()> {
noop!();
Ok(())
}
fn after_data_collection(&mut self, _params: CollectorParams) -> Result<()> {
fn after_data_collection(&mut self, _params: &CollectorParams) -> Result<()> {
noop!();
Ok(())
}
Expand Down Expand Up @@ -390,7 +386,7 @@ mod tests {
.create(param.dir_name.clone())
.unwrap();

dt.init_data_type(param).unwrap();
dt.init_data_type(&param).unwrap();

assert!(dt.file_handle.is_some());
fs::remove_file(dt.full_path).unwrap();
Expand Down Expand Up @@ -418,7 +414,7 @@ mod tests {
.create(param.dir_name.clone())
.unwrap();

dt.init_data_type(param).unwrap();
dt.init_data_type(&param).unwrap();

assert!(Path::new(&dt.full_path).exists());
dt.write_to_file().unwrap();
Expand Down
4 changes: 2 additions & 2 deletions src/data/flamegraphs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ impl FlamegraphRaw {
}

impl CollectData for FlamegraphRaw {
fn prepare_data_collector(&mut self, _params: CollectorParams) -> Result<()> {
fn prepare_data_collector(&mut self, _params: &CollectorParams) -> Result<()> {
match Command::new("perf").args(["--version"]).output() {
Err(e) => Err(PDError::DependencyError(format!("'perf' command failed. {}", e)).into()),
_ => Ok(()),
}
}

fn after_data_collection(&mut self, params: CollectorParams) -> Result<()> {
fn after_data_collection(&mut self, params: &CollectorParams) -> Result<()> {
let data_dir = PathBuf::from(&params.data_dir);

let file_pathbuf = data_dir.join(get_file_name(
Expand Down
14 changes: 5 additions & 9 deletions src/data/java_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl JavaProfileRaw {
}
}

fn launch_asprof(&self, jids: Vec<String>, params: CollectorParams) -> Result<()> {
fn launch_asprof(&self, jids: Vec<String>, params: &CollectorParams) -> Result<()> {
for jid in &jids {
match Command::new("asprof")
.args([
Expand Down Expand Up @@ -137,7 +137,7 @@ impl JavaProfileRaw {
}

impl CollectData for JavaProfileRaw {
fn prepare_data_collector(&mut self, params: CollectorParams) -> Result<()> {
fn prepare_data_collector(&mut self, params: &CollectorParams) -> Result<()> {
let mut jids: Vec<String> = Vec::new();
let pgrep: Vec<String> = self.launch_pgrep()?;
for pid in pgrep {
Expand Down Expand Up @@ -172,7 +172,7 @@ impl CollectData for JavaProfileRaw {
}
jids.sort();
jids.dedup();
self.launch_asprof(jids, params.clone())
self.launch_asprof(jids, params)
}

fn collect_data(&mut self, params: &CollectorParams) -> Result<()> {
Expand All @@ -198,10 +198,10 @@ impl CollectData for JavaProfileRaw {
}

self.update_process_map()?;
self.launch_asprof(jids, params.clone())
self.launch_asprof(jids, params)
}

fn finish_data_collection(&mut self, params: CollectorParams) -> Result<()> {
fn finish_data_collection(&mut self, params: &CollectorParams) -> Result<()> {
for child in ASPROF_CHILDREN.lock().unwrap().iter() {
signal::kill(Pid::from_raw(child.id() as i32), params.signal)?;
}
Expand Down Expand Up @@ -242,10 +242,6 @@ impl CollectData for JavaProfileRaw {

Ok(())
}

fn after_data_collection(&mut self, _params: CollectorParams) -> Result<()> {
Ok(())
}
}

#[derive(Serialize, Deserialize, Debug, Clone)]
Expand Down
12 changes: 7 additions & 5 deletions src/data/perf_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ use log::{error, trace};
use nix::{sys::signal, unistd::Pid};
use serde::{Deserialize, Serialize};
use std::fs;
use std::io::Write;
use std::process::{Child, Command, Stdio};
use std::sync::Mutex;
use std::{
io::Write,
process::{Child, Command, Stdio},
sync::Mutex,
};

pub static PERF_PROFILE_FILE_NAME: &str = "perf_profile";
pub static PERF_TOP_FUNCTIONS_FILE_NAME: &str = "top_functions";
Expand All @@ -34,7 +36,7 @@ impl PerfProfileRaw {
}

impl CollectData for PerfProfileRaw {
fn prepare_data_collector(&mut self, params: CollectorParams) -> Result<()> {
fn prepare_data_collector(&mut self, params: &CollectorParams) -> Result<()> {
match Command::new("perf")
.stdout(Stdio::null())
.args([
Expand Down Expand Up @@ -73,7 +75,7 @@ impl CollectData for PerfProfileRaw {
Ok(())
}

fn finish_data_collection(&mut self, params: CollectorParams) -> Result<()> {
fn finish_data_collection(&mut self, params: &CollectorParams) -> Result<()> {
let mut child = PERF_CHILD.lock().unwrap();
match child.as_ref() {
None => return Ok(()),
Expand Down
6 changes: 3 additions & 3 deletions src/data/perf_stat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl PerfStatRaw {
}

impl CollectData for PerfStatRaw {
fn prepare_data_collector(&mut self, _params: CollectorParams) -> Result<()> {
fn prepare_data_collector(&mut self, _params: &CollectorParams) -> Result<()> {
let num_cpus = match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN as libc::c_int) } {
-1 => {
warn!("Could not get the number of cpus in the system with sysconf.");
Expand Down Expand Up @@ -567,7 +567,7 @@ mod tests {
let mut perf_stat = PerfStatRaw::new();
let params = CollectorParams::new();

match perf_stat.prepare_data_collector(params.clone()) {
match perf_stat.prepare_data_collector(&params) {
Err(e) => {
if let Some(os_error) = e.downcast_ref::<std::io::Error>() {
match os_error.kind() {
Expand All @@ -593,7 +593,7 @@ mod tests {
let mut processed_buffer: Vec<ProcessedData> = Vec::new();
let params = CollectorParams::new();

match perf_stat.prepare_data_collector(params.clone()) {
match perf_stat.prepare_data_collector(&params) {
Err(e) => {
if let Some(os_error) = e.downcast_ref::<std::io::Error>() {
match os_error.kind() {
Expand Down
12 changes: 4 additions & 8 deletions src/data/processes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl Default for ProcessesRaw {
}

impl CollectData for ProcessesRaw {
fn prepare_data_collector(&mut self, _params: CollectorParams) -> Result<()> {
fn prepare_data_collector(&mut self, _params: &CollectorParams) -> Result<()> {
*TICKS_PER_SECOND.lock().unwrap() = procfs::ticks_per_second()? as u64;
Ok(())
}
Expand Down Expand Up @@ -345,7 +345,7 @@ mod process_test {
fn test_collect_data() {
let mut processes = ProcessesRaw::new();
let params = CollectorParams::new();
processes.prepare_data_collector(params.clone()).unwrap();
processes.prepare_data_collector(&params).unwrap();
processes.collect_data(&params).unwrap();
assert!(!processes.data.is_empty());
}
Expand All @@ -358,12 +358,8 @@ mod process_test {
let mut processed_buffer: Vec<ProcessedData> = Vec::<ProcessedData>::new();
let params = CollectorParams::new();

processes_zero
.prepare_data_collector(params.clone())
.unwrap();
processes_one
.prepare_data_collector(params.clone())
.unwrap();
processes_zero.prepare_data_collector(&params).unwrap();
processes_one.prepare_data_collector(&params).unwrap();
processes_zero.collect_data(&params).unwrap();
processes_one.collect_data(&params).unwrap();

Expand Down
2 changes: 2 additions & 0 deletions src/html_files/aperf_run_stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ function getAperfEntry(elem, key, run_data) {
y: y_print,
type: 'scatter',
};
let limits = key_limits.get(key);
var layout = {
title: `${key}`,
xaxis: {
title: 'Time (s)',
},
yaxis: {
title: 'Time (us)',
range: [limits.low, limits.high],
},
}
Plotly.newPlot(TESTER, [aperfstat_collect_data, aperfstat_print_data], layout, { frameMargins: 0 });
Expand Down
Loading

0 comments on commit bb815df

Please sign in to comment.