use std::io;
use std::path::PathBuf;
use clap::Parser;
use env_logger::Env;
use inferno::collapse::perf::{Folder, Options};
use inferno::collapse::{Collapse, DEFAULT_NTHREADS};
use once_cell::sync::Lazy;
static NTHREADS: Lazy<String> = Lazy::new(|| DEFAULT_NTHREADS.to_string());
#[derive(Debug, Parser)]
#[clap(
name = "inferno-collapse-perf",
about,
after_help = "\
[1] perf script must emit both PID and TIDs for these to work; eg, Linux < 4.1:
perf script -f comm,pid,tid,cpu,time,event,ip,sym,dso,trace
for Linux >= 4.1:
perf script -F comm,pid,tid,cpu,time,event,ip,sym,dso,trace
If you save this output add --header on Linux >= 3.14 to include perf info."
)]
struct Opt {
#[clap(long = "addrs")]
addrs: bool,
#[clap(long = "all")]
all: bool,
#[clap(long = "jit")]
jit: bool,
#[clap(long = "kernel")]
kernel: bool,
#[clap(long = "pid")]
pid: bool,
#[clap(long = "tid")]
tid: bool,
#[clap(short = 'q', long = "quiet")]
quiet: bool,
#[clap(short = 'v', long = "verbose", parse(from_occurrences))]
verbose: usize,
#[clap(long = "event-filter", value_name = "STRING")]
event_filter: Option<String>,
#[clap(
short = 'n',
long = "nthreads",
default_value = &NTHREADS,
value_name = "UINT"
)]
nthreads: usize,
#[clap(value_name = "PATH")]
infile: Option<PathBuf>,
#[clap(long = "skip-after", value_name = "STRING")]
skip_after: Vec<String>,
}
impl Opt {
fn into_parts(self) -> (Option<PathBuf>, Options) {
let mut options = Options::default();
options.include_pid = self.pid;
options.include_tid = self.tid;
options.include_addrs = self.addrs;
options.annotate_jit = self.jit || self.all;
options.annotate_kernel = self.kernel || self.all;
options.event_filter = self.event_filter;
options.nthreads = self.nthreads;
options.skip_after = self.skip_after;
(self.infile, options)
}
}
fn main() -> io::Result<()> {
let opt = Opt::parse();
if !opt.quiet {
env_logger::Builder::from_env(Env::default().default_filter_or(match opt.verbose {
0 => "warn",
1 => "info",
2 => "debug",
_ => "trace",
}))
.format_timestamp(None)
.init();
}
let (infile, options) = opt.into_parts();
Folder::from(options).collapse_file_to_stdout(infile.as_ref())
}