Skip to content

Commit 2b9bc3c

Browse files
committed
Ruby: write errors to json log
1 parent d5e60df commit 2b9bc3c

File tree

4 files changed

+201
-161
lines changed

4 files changed

+201
-161
lines changed

ruby/extractor/src/diagnostics.rs

Lines changed: 77 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::path::PathBuf;
66
pub enum Severity {
77
Error,
88
Warning,
9+
#[allow(unused)]
910
Note,
1011
}
1112

@@ -42,13 +43,13 @@ pub struct Location {
4243
/** Path to the affected file if appropriate, relative to the source root */
4344
pub file: Option<String>,
4445
#[serde(skip_serializing_if = "Option::is_none")]
45-
pub start_line: Option<i32>,
46+
pub start_line: Option<usize>,
4647
#[serde(skip_serializing_if = "Option::is_none")]
47-
pub start_column: Option<i32>,
48+
pub start_column: Option<usize>,
4849
#[serde(skip_serializing_if = "Option::is_none")]
49-
pub end_line: Option<i32>,
50+
pub end_line: Option<usize>,
5051
#[serde(skip_serializing_if = "Option::is_none")]
51-
pub end_column: Option<i32>,
52+
pub end_column: Option<usize>,
5253
}
5354

5455
#[derive(Serialize)]
@@ -81,12 +82,45 @@ fn is_default_visibility(v: &Visibility) -> bool {
8182
}
8283

8384
pub struct LogWriter {
85+
extractor: String,
8486
path: Option<PathBuf>,
8587
inner: Option<std::io::BufWriter<std::fs::File>>,
8688
}
8789

8890
impl LogWriter {
89-
pub fn write(&mut self, mesg: &DiagnosticMessage) -> std::io::Result<()> {
91+
pub fn message(&self, id: &str, name: &str) -> DiagnosticMessage {
92+
DiagnosticMessage {
93+
timestamp: std::time::SystemTime::now()
94+
.duration_since(std::time::UNIX_EPOCH)
95+
.expect("")
96+
.as_millis() as u64,
97+
source: Source {
98+
id: format!("{}/{}", self.extractor, id),
99+
name: name.to_owned(),
100+
extractor_name: Some(self.extractor.to_owned()),
101+
},
102+
markdown_message: String::new(),
103+
plaintext_message: String::new(),
104+
help_links: vec![],
105+
severity: None,
106+
internal: false,
107+
visibility: Visibility {
108+
cli_summary_table: false,
109+
status_page: false,
110+
telemetry: false,
111+
},
112+
location: None,
113+
}
114+
}
115+
pub fn write(&mut self, mesg: &DiagnosticMessage) {
116+
let full_error_message = mesg.full_error_message();
117+
118+
match mesg.severity {
119+
Some(Severity::Error) => tracing::error!("{}", full_error_message),
120+
Some(Severity::Warning) => tracing::warn!("{}", full_error_message),
121+
Some(Severity::Note) => tracing::info!("{}", full_error_message),
122+
None => tracing::debug!("{}", full_error_message),
123+
}
90124
if self.inner.is_none() {
91125
let mut open_failed = false;
92126
self.inner = self.path.as_ref().and_then(|path| {
@@ -113,10 +147,12 @@ impl LogWriter {
113147
}
114148
}
115149
if let Some(mut writer) = self.inner.as_mut() {
116-
serde_json::to_writer(&mut writer, mesg)?;
117-
&mut writer.write_all(b"\n")?;
150+
serde_json::to_writer(&mut writer, mesg)
151+
.unwrap_or_else(|e| tracing::debug!("Failed to write log entry: {}", e));
152+
&mut writer
153+
.write_all(b"\n")
154+
.unwrap_or_else(|e| tracing::debug!("Failed to write log entry: {}", e));
118155
}
119-
Ok(())
120156
}
121157
}
122158

@@ -134,7 +170,7 @@ impl DiagnosticLoggers {
134170

135171
let root = match std::env::var(&env_var) {
136172
Err(e) => {
137-
tracing::error!("{}: {}", &env_var, e);
173+
tracing::error!("{}: {}", e, &env_var);
138174
None
139175
}
140176
Ok(dir) => {
@@ -160,37 +196,14 @@ impl DiagnosticLoggers {
160196
};
161197
}
162198
THREAD_NUM.with(|n| LogWriter {
199+
extractor: self.extractor.to_owned(),
163200
inner: None,
164201
path: self
165202
.root
166203
.as_ref()
167204
.map(|root| root.to_owned().join(format!("extractor_{}.jsonl", n))),
168205
})
169206
}
170-
pub fn message(&self, id: &str, name: &str) -> DiagnosticMessage {
171-
DiagnosticMessage {
172-
timestamp: std::time::SystemTime::now()
173-
.duration_since(std::time::UNIX_EPOCH)
174-
.expect("")
175-
.as_millis() as u64,
176-
source: Source {
177-
id: id.to_owned(),
178-
name: name.to_owned(),
179-
extractor_name: Some(self.extractor.to_owned()),
180-
},
181-
markdown_message: String::new(),
182-
plaintext_message: String::new(),
183-
help_links: vec![],
184-
severity: None,
185-
internal: false,
186-
visibility: Visibility {
187-
cli_summary_table: false,
188-
status_page: false,
189-
telemetry: false,
190-
},
191-
location: None,
192-
}
193-
}
194207
}
195208
static EMPTY_LOCATION: Location = Location {
196209
file: None,
@@ -200,10 +213,23 @@ static EMPTY_LOCATION: Location = Location {
200213
end_column: None,
201214
};
202215
impl DiagnosticMessage {
216+
pub fn full_error_message(&self) -> String {
217+
match &self.location {
218+
Some(Location {
219+
file: Some(path),
220+
start_line: Some(line),
221+
..
222+
}) => format!("{}:{}: {}", path, line, self.plaintext_message),
223+
_ => self.plaintext_message.to_owned(),
224+
}
225+
}
226+
203227
pub fn text<'a>(&'a mut self, text: &str) -> &'a mut Self {
204228
self.plaintext_message = text.to_owned();
205229
self
206230
}
231+
232+
#[allow(unused)]
207233
pub fn markdown<'a>(&'a mut self, text: &str) -> &'a mut Self {
208234
self.markdown_message = text.to_owned();
209235
self
@@ -212,14 +238,17 @@ impl DiagnosticMessage {
212238
self.severity = Some(severity);
213239
self
214240
}
241+
#[allow(unused)]
215242
pub fn help_link<'a>(&'a mut self, link: &str) -> &'a mut Self {
216243
self.help_links.push(link.to_owned());
217244
self
218245
}
246+
#[allow(unused)]
219247
pub fn internal<'a>(&'a mut self) -> &'a mut Self {
220248
self.internal = true;
221249
self
222250
}
251+
#[allow(unused)]
223252
pub fn cli_summary_table<'a>(&'a mut self) -> &'a mut Self {
224253
self.visibility.cli_summary_table = true;
225254
self
@@ -228,36 +257,25 @@ impl DiagnosticMessage {
228257
self.visibility.status_page = true;
229258
self
230259
}
260+
#[allow(unused)]
231261
pub fn telemetry<'a>(&'a mut self) -> &'a mut Self {
232262
self.visibility.telemetry = true;
233263
self
234264
}
235-
pub fn file<'a>(&'a mut self, path: &str) -> &'a mut Self {
236-
self.location.get_or_insert(EMPTY_LOCATION.to_owned()).file = Some(path.to_owned());
237-
self
238-
}
239-
pub fn start_line<'a>(&'a mut self, start_line: i32) -> &'a mut Self {
240-
self.location
241-
.get_or_insert(EMPTY_LOCATION.to_owned())
242-
.start_line = Some(start_line);
243-
self
244-
}
245-
pub fn start_column<'a>(&'a mut self, start_column: i32) -> &'a mut Self {
246-
self.location
247-
.get_or_insert(EMPTY_LOCATION.to_owned())
248-
.start_column = Some(start_column);
249-
self
250-
}
251-
pub fn end_line<'a>(&'a mut self, end_line: i32) -> &'a mut Self {
252-
self.location
253-
.get_or_insert(EMPTY_LOCATION.to_owned())
254-
.end_line = Some(end_line);
255-
self
256-
}
257-
pub fn end_column<'a>(&'a mut self, end_column: i32) -> &'a mut Self {
258-
self.location
259-
.get_or_insert(EMPTY_LOCATION.to_owned())
260-
.end_column = Some(end_column);
265+
pub fn location<'a>(
266+
&'a mut self,
267+
path: &str,
268+
start_line: usize,
269+
start_column: usize,
270+
end_line: usize,
271+
end_column: usize,
272+
) -> &'a mut Self {
273+
let loc = self.location.get_or_insert(EMPTY_LOCATION.to_owned());
274+
loc.file = Some(path.to_owned());
275+
loc.start_line = Some(start_line);
276+
loc.start_column = Some(start_column);
277+
loc.end_line = Some(end_line);
278+
loc.end_column = Some(end_column);
261279
self
262280
}
263281
}

0 commit comments

Comments
 (0)