aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/bin/logger.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rust-analyzer/src/bin/logger.rs')
-rw-r--r--crates/rust-analyzer/src/bin/logger.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/crates/rust-analyzer/src/bin/logger.rs b/crates/rust-analyzer/src/bin/logger.rs
new file mode 100644
index 000000000..3bcb1ae37
--- /dev/null
+++ b/crates/rust-analyzer/src/bin/logger.rs
@@ -0,0 +1,73 @@
1//! Simple logger that logs either to stderr or to a file, using `env_logger`
2//! filter syntax. Amusingly, there's no crates.io crate that can do this and
3//! only this.
4
5use std::{
6 fs::File,
7 io::{BufWriter, Write},
8};
9
10use env_logger::filter::{Builder, Filter};
11use log::{Log, Metadata, Record};
12use parking_lot::Mutex;
13
14pub(crate) struct Logger {
15 filter: Filter,
16 file: Option<Mutex<BufWriter<File>>>,
17}
18
19impl Logger {
20 pub(crate) fn new(log_file: Option<File>, filter: Option<&str>) -> Logger {
21 let filter = {
22 let mut builder = Builder::new();
23 if let Some(filter) = filter {
24 builder.parse(filter);
25 }
26 builder.build()
27 };
28
29 let file = log_file.map(|it| Mutex::new(BufWriter::new(it)));
30
31 Logger { filter, file }
32 }
33
34 pub(crate) fn install(self) {
35 let max_level = self.filter.filter();
36 let _ = log::set_boxed_logger(Box::new(self)).map(|()| log::set_max_level(max_level));
37 }
38}
39
40impl Log for Logger {
41 fn enabled(&self, metadata: &Metadata) -> bool {
42 self.filter.enabled(metadata)
43 }
44
45 fn log(&self, record: &Record) {
46 if !self.filter.matches(record) {
47 return;
48 }
49 match &self.file {
50 Some(w) => {
51 let _ = writeln!(
52 w.lock(),
53 "[{} {}] {}",
54 record.level(),
55 record.module_path().unwrap_or_default(),
56 record.args(),
57 );
58 }
59 None => eprintln!(
60 "[{} {}] {}",
61 record.level(),
62 record.module_path().unwrap_or_default(),
63 record.args(),
64 ),
65 }
66 }
67
68 fn flush(&self) {
69 if let Some(w) = &self.file {
70 let _ = w.lock().flush();
71 }
72 }
73}