From 5b7012318cdf5fb0bb8b01319270c1b4bf0311ee Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 14 Apr 2019 23:18:58 +0300 Subject: filter by time --- crates/ra_prof/src/lib.rs | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'crates/ra_prof') diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index c7c21b6d2..999cc61f0 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs @@ -27,7 +27,8 @@ pub fn set_filter(f: Filter) { PROFILING_ENABLED.store(f.depth > 0, Ordering::SeqCst); let set = HashSet::from_iter(f.allowed.iter().cloned()); let mut old = FILTER.write().unwrap(); - let filter_data = FilterData { depth: f.depth, allowed: set, version: old.version + 1 }; + let filter_data = + FilterData { depth: f.depth, allowed: set, cutoff: f.cutoff, version: old.version + 1 }; *old = filter_data; } @@ -101,15 +102,41 @@ pub struct Profiler { pub struct Filter { depth: usize, allowed: Vec, + cutoff: Duration, } impl Filter { + // Filtering syntax + // env RA_PROFILE=* // dump everything + // env RA_PROFILE=foo|bar|baz // enabled only selected entries + // env RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more than 10 ms + pub fn from_spec(mut spec: &str) -> Filter { + let cutoff = if let Some(idx) = spec.rfind(">") { + let cutoff = spec[idx + 1..].parse().expect("invalid profile cutoff"); + spec = &spec[..idx]; + Duration::from_millis(cutoff) + } else { + Duration::new(0, 0) + }; + + let depth = if let Some(idx) = spec.rfind("@") { + let depth: usize = spec[idx + 1..].parse().expect("invalid profile depth"); + spec = &spec[..idx]; + depth + } else { + 999 + }; + let allowed = + if spec == "*" { Vec::new() } else { spec.split("|").map(String::from).collect() }; + Filter::new(depth, allowed, cutoff) + } + pub fn disabled() -> Filter { - Filter::new(0, Vec::new()) + Filter::new(0, Vec::new(), Duration::new(0, 0)) } - pub fn new(depth: usize, allowed: Vec) -> Filter { - Filter { depth, allowed } + pub fn new(depth: usize, allowed: Vec, cutoff: Duration) -> Filter { + Filter { depth, allowed, cutoff } } } @@ -136,6 +163,7 @@ struct FilterData { depth: usize, version: usize, allowed: HashSet, + cutoff: Duration, } static PROFILING_ENABLED: AtomicBool = AtomicBool::new(false); @@ -159,7 +187,9 @@ impl Drop for Profiler { stack.messages.push(Message { level, duration, message }); if level == 0 { let stdout = stderr(); - print(0, &stack.messages, &mut stdout.lock()); + if duration >= stack.filter_data.cutoff { + print(0, &stack.messages, &mut stdout.lock()); + } stack.messages.clear(); } }); -- cgit v1.2.3