use std::io;
use std::path::PathBuf;
use env_logger::Env;
use inferno::collapse::dtrace::{Folder, Options};
use inferno::collapse::{Collapse, DEFAULT_NTHREADS};
use lazy_static::lazy_static;
use structopt::StructOpt;
lazy_static! {
static ref NTHREADS: String = format!("{}", *DEFAULT_NTHREADS);
}
#[derive(Debug, StructOpt)]
#[structopt(
name = "inferno-collapse-dtrace",
about,
after_help = "\
[1] This processes the result of the dtrace ustack() as run with:
dtrace -x ustackframes=100 -n 'profile-97 /pid == 12345 && arg1/ { @[ustack()] = count(); } tick-60s { exit(0); }'
or including kernel time:
dtrace -x ustackframes=100 -n 'profile-97 /pid == 12345/ { @[ustack()] = count(); } tick-60s { exit(0); }'
"
)]
struct Opt {
#[structopt(long = "includeoffset")]
includeoffset: bool,
#[structopt(short = "q", long = "quiet")]
quiet: bool,
#[structopt(short = "v", long = "verbose", parse(from_occurrences))]
verbose: usize,
#[structopt(
short = "n",
long = "nthreads",
default_value = &NTHREADS,
value_name = "UINT"
)]
nthreads: usize,
#[structopt(value_name = "PATH")]
infile: Option<PathBuf>,
}
impl Opt {
fn into_parts(self) -> (Option<PathBuf>, Options) {
let mut options = Options::default();
options.includeoffset = self.includeoffset;
options.nthreads = self.nthreads;
(self.infile, options)
}
}
fn main() -> io::Result<()> {
let opt = Opt::from_args();
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())
}