aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_lsp_server/src/main.rs25
-rw-r--r--crates/ra_prof/src/lib.rs40
2 files changed, 39 insertions, 26 deletions
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs
index 28f9985b6..b0b70df5c 100644
--- a/crates/ra_lsp_server/src/main.rs
+++ b/crates/ra_lsp_server/src/main.rs
@@ -8,31 +8,14 @@ use ra_prof;
8fn main() -> Result<()> { 8fn main() -> Result<()> {
9 std::env::set_var("RUST_BACKTRACE", "short"); 9 std::env::set_var("RUST_BACKTRACE", "short");
10 let logger = Logger::with_env_or_str("error").duplicate_to_stderr(Duplicate::All); 10 let logger = Logger::with_env_or_str("error").duplicate_to_stderr(Duplicate::All);
11 match std::env::var("RA_INTERNAL_MODE") { 11 match std::env::var("RA_LOG_DIR") {
12 Ok(ref v) if v == "1" => logger.log_to_file().directory("log").start()?, 12 Ok(ref v) if v == "1" => logger.log_to_file().directory("log").start()?,
13 _ => logger.start()?, 13 _ => logger.start()?,
14 }; 14 };
15 // Filtering syntax 15 ra_prof::set_filter(match std::env::var("RA_PROFILE") {
16 // env RA_PROFILE=* // dump everything 16 Ok(spec) => ra_prof::Filter::from_spec(&spec),
17 // env RA_PROFILE=foo|bar|baz // enabled only selected entries
18 // env RA_PROFILE=*@3 // dump everything, up to depth 3
19 let filter = match std::env::var("RA_PROFILE") {
20 Ok(p) => {
21 let mut p = p.as_str();
22 let depth = if let Some(idx) = p.rfind("@") {
23 let depth: usize = p[idx + 1..].parse().expect("invalid profile depth");
24 p = &p[..idx];
25 depth
26 } else {
27 999
28 };
29 let allowed =
30 if p == "*" { Vec::new() } else { p.split(";").map(String::from).collect() };
31 ra_prof::Filter::new(depth, allowed)
32 }
33 Err(_) => ra_prof::Filter::disabled(), 17 Err(_) => ra_prof::Filter::disabled(),
34 }; 18 });
35 ra_prof::set_filter(filter);
36 log::info!("lifecycle: server started"); 19 log::info!("lifecycle: server started");
37 match ::std::panic::catch_unwind(main_inner) { 20 match ::std::panic::catch_unwind(main_inner) {
38 Ok(res) => { 21 Ok(res) => {
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) {
27 PROFILING_ENABLED.store(f.depth > 0, Ordering::SeqCst); 27 PROFILING_ENABLED.store(f.depth > 0, Ordering::SeqCst);
28 let set = HashSet::from_iter(f.allowed.iter().cloned()); 28 let set = HashSet::from_iter(f.allowed.iter().cloned());
29 let mut old = FILTER.write().unwrap(); 29 let mut old = FILTER.write().unwrap();
30 let filter_data = FilterData { depth: f.depth, allowed: set, version: old.version + 1 }; 30 let filter_data =
31 FilterData { depth: f.depth, allowed: set, cutoff: f.cutoff, version: old.version + 1 };
31 *old = filter_data; 32 *old = filter_data;
32} 33}
33 34
@@ -101,15 +102,41 @@ pub struct Profiler {
101pub struct Filter { 102pub struct Filter {
102 depth: usize, 103 depth: usize,
103 allowed: Vec<String>, 104 allowed: Vec<String>,
105 cutoff: Duration,
104} 106}
105 107
106impl Filter { 108impl Filter {
109 // Filtering syntax
110 // env RA_PROFILE=* // dump everything
111 // env RA_PROFILE=foo|bar|baz // enabled only selected entries
112 // env RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more than 10 ms
113 pub fn from_spec(mut spec: &str) -> Filter {
114 let cutoff = if let Some(idx) = spec.rfind(">") {
115 let cutoff = spec[idx + 1..].parse().expect("invalid profile cutoff");
116 spec = &spec[..idx];
117 Duration::from_millis(cutoff)
118 } else {
119 Duration::new(0, 0)
120 };
121
122 let depth = if let Some(idx) = spec.rfind("@") {
123 let depth: usize = spec[idx + 1..].parse().expect("invalid profile depth");
124 spec = &spec[..idx];
125 depth
126 } else {
127 999
128 };
129 let allowed =
130 if spec == "*" { Vec::new() } else { spec.split("|").map(String::from).collect() };
131 Filter::new(depth, allowed, cutoff)
132 }
133
107 pub fn disabled() -> Filter { 134 pub fn disabled() -> Filter {
108 Filter::new(0, Vec::new()) 135 Filter::new(0, Vec::new(), Duration::new(0, 0))
109 } 136 }
110 137
111 pub fn new(depth: usize, allowed: Vec<String>) -> Filter { 138 pub fn new(depth: usize, allowed: Vec<String>, cutoff: Duration) -> Filter {
112 Filter { depth, allowed } 139 Filter { depth, allowed, cutoff }
113 } 140 }
114} 141}
115 142
@@ -136,6 +163,7 @@ struct FilterData {
136 depth: usize, 163 depth: usize,
137 version: usize, 164 version: usize,
138 allowed: HashSet<String>, 165 allowed: HashSet<String>,
166 cutoff: Duration,
139} 167}
140 168
141static PROFILING_ENABLED: AtomicBool = AtomicBool::new(false); 169static PROFILING_ENABLED: AtomicBool = AtomicBool::new(false);
@@ -159,7 +187,9 @@ impl Drop for Profiler {
159 stack.messages.push(Message { level, duration, message }); 187 stack.messages.push(Message { level, duration, message });
160 if level == 0 { 188 if level == 0 {
161 let stdout = stderr(); 189 let stdout = stderr();
162 print(0, &stack.messages, &mut stdout.lock()); 190 if duration >= stack.filter_data.cutoff {
191 print(0, &stack.messages, &mut stdout.lock());
192 }
163 stack.messages.clear(); 193 stack.messages.clear();
164 } 194 }
165 }); 195 });