diff --git a/Cargo.lock b/Cargo.lock index 3d259b3f..8f4a5031 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,6 +147,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi 0.3.9", +] + [[package]] name = "clap" version = "2.33.3" @@ -399,7 +412,7 @@ checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.1+wasi-snapshot-preview1", + "wasi 0.10.0+wasi-snapshot-preview1", ] [[package]] @@ -681,6 +694,16 @@ dependencies = [ "itoa", ] +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -785,6 +808,7 @@ dependencies = [ name = "py-spy" version = "0.3.4" dependencies = [ + "chrono", "clap", "console 0.13.0", "cpp_demangle", @@ -1188,6 +1212,17 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi 0.3.9", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -1235,9 +1270,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.1+wasi-snapshot-preview1" +version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c6c3420963c5c64bca373b25e77acb562081b9bb4dd5bb864187742186cea9" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasmparser" diff --git a/Cargo.toml b/Cargo.toml index 505e1421..017dc70a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ serde_json = "1.0" rand = "0.8" rand_distr = "0.4" remoteprocess = {version="0.4.2", features=["unwind"]} +chrono = "0.4.19" [target.'cfg(unix)'.dependencies] termios = "0.3.2" diff --git a/src/config.rs b/src/config.rs index 84ecbdf0..30287dac 100644 --- a/src/config.rs +++ b/src/config.rs @@ -143,7 +143,7 @@ impl Config { .value_name("filename") .help("Output filename") .takes_value(true) - .required(true)) + .required(false)) .arg(Arg::with_name("format") .short("f") .long("format") diff --git a/src/main.rs b/src/main.rs index e47c98c2..0435eb1c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ extern crate lazy_static; extern crate libc; #[macro_use] extern crate log; +extern crate chrono; #[cfg(unwind)] extern crate lru; extern crate memmap; @@ -66,6 +67,8 @@ use stack_trace::{StackTrace, Frame}; use console_viewer::ConsoleViewer; use config::{Config, FileFormat, RecordDuration}; +use chrono::{SecondsFormat, Local}; + #[cfg(unix)] fn permission_denied(err: &Error) -> bool { err.iter_chain().any(|cause| { @@ -153,9 +156,25 @@ fn record_samples(pid: remoteprocess::Pid, config: &Config) -> Result<(), Error> None => return Err(format_err!("A file format is required to record samples")) }; - let filename = match config.filename.as_ref() { + let filename = match config.filename.clone() { Some(filename) => filename, - None => return Err(format_err!("A filename is required to record samples")) + None => { + let ext = match config.format.as_ref() { + Some(FileFormat::flamegraph) => "svg", + Some(FileFormat::speedscope) => "json", + Some(FileFormat::raw) => "txt", + None => return Err(format_err!("A file format is required to record samples")) + }; + let local_time = Local::now().to_rfc3339_opts(SecondsFormat::Secs, true); + let name = match config.python_program.as_ref() { + Some(prog) => prog[0].to_string(), + None => match config.pid.as_ref() { + Some(pid) => pid.to_string(), + None => String::from("unknown") + } + }; + format!("{}-{}.{}", name, local_time, ext) + } }; let sampler = sampler::Sampler::new(pid, config)?; @@ -294,7 +313,7 @@ fn record_samples(pid: remoteprocess::Pid, config: &Config) -> Result<(), Error> } { - let mut out_file = std::fs::File::create(filename)?; + let mut out_file = std::fs::File::create(&filename)?; output.write(&mut out_file)?; } @@ -305,7 +324,7 @@ fn record_samples(pid: remoteprocess::Pid, config: &Config) -> Result<(), Error> // you might be SSH'ed into a server somewhere and this isn't desired, but on // that is pretty unlikely for osx) (note to self: xdg-open will open on linux) #[cfg(target_os = "macos")] - std::process::Command::new("open").arg(filename).spawn()?; + std::process::Command::new("open").arg(&filename).spawn()?; }, FileFormat::speedscope => { println!("{}Wrote speedscope file to '{}'. Samples: {} Errors: {}", lede, filename, samples, errors);