Skip to content

Commit cd423a2

Browse files
authored
[integration] tweaks needed to integrate with lnav (ttiimm#9)
Mostly need to make some more fields public so lnav can read them. Also, restore checking if the file name mentioned in the log is in the discovered source path. The check is pretty loose since I think I've seen file names truncated before.
2 parents 7ed0042 + 369e2e4 commit cd423a2

File tree

2 files changed

+63
-32
lines changed

2 files changed

+63
-32
lines changed

src/lib.rs

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub enum LogError {
4848
/// Collection of log statements in a single source file
4949
#[derive(Debug)]
5050
pub struct StatementsInFile {
51+
pub filename: String,
5152
pub log_statements: Vec<SourceRef>,
5253
/// A single matcher for all log statements.
5354
/// XXX If there are too many in the file, the RegexSet constructor
@@ -165,17 +166,36 @@ impl LogMatcher {
165166
/// Attempt to match the given log message.
166167
pub fn match_log_statement<'a>(&self, log_ref: &LogRef<'a>) -> Option<LogMapping<'a>> {
167168
for (_path, coll) in &self.roots {
168-
let matches = coll
169-
.statements
170-
.par_iter()
171-
.flat_map(|src_ref_coll| {
172-
let file_matches = src_ref_coll.matcher.matches(log_ref.body());
173-
match file_matches.iter().next() {
174-
None => None,
175-
Some(index) => src_ref_coll.log_statements.get(index),
176-
}
177-
})
178-
.collect::<Vec<&SourceRef>>();
169+
let matches = if let Some(LogDetails {
170+
file: Some(filename),
171+
body: Some(body),
172+
..
173+
}) = log_ref.details
174+
{
175+
// XXX this block and the else are basically the same, try to refactor
176+
coll.statements
177+
.iter()
178+
.filter(|stmts| stmts.filename.contains(filename))
179+
.flat_map(|stmts| {
180+
let file_matches = stmts.matcher.matches(body);
181+
match file_matches.iter().next() {
182+
None => None,
183+
Some(index) => stmts.log_statements.get(index),
184+
}
185+
})
186+
.collect::<Vec<&SourceRef>>()
187+
} else {
188+
coll.statements
189+
.par_iter()
190+
.flat_map(|src_ref_coll| {
191+
let file_matches = src_ref_coll.matcher.matches(log_ref.body());
192+
match file_matches.iter().next() {
193+
None => None,
194+
Some(index) => src_ref_coll.log_statements.get(index),
195+
}
196+
})
197+
.collect::<Vec<&SourceRef>>()
198+
};
179199
if let Some(src_ref) = matches.first() {
180200
let variables = extract_variables(log_ref, src_ref);
181201
return Some(LogMapping {
@@ -268,24 +288,14 @@ pub struct LogMapping<'a> {
268288
#[derive(Copy, Clone, Debug, PartialEq)]
269289
pub struct LogRef<'a> {
270290
pub line: &'a str,
271-
details: Option<LogDetails<'a>>,
272-
}
273-
274-
impl<'a> LogRef<'a> {
275-
pub fn body(self) -> &'a str {
276-
if let Some(LogDetails { body: Some(s), .. }) = self.details {
277-
s
278-
} else {
279-
self.line
280-
}
281-
}
291+
pub details: Option<LogDetails<'a>>,
282292
}
283293

284294
#[derive(Copy, Clone, Debug, PartialEq)]
285-
struct LogDetails<'a> {
286-
file: Option<&'a str>,
287-
lineno: Option<u32>,
288-
body: Option<&'a str>,
295+
pub struct LogDetails<'a> {
296+
pub file: Option<&'a str>,
297+
pub lineno: Option<u32>,
298+
pub body: Option<&'a str>,
289299
}
290300

291301
impl<'a> LogRef<'a> {
@@ -296,6 +306,18 @@ impl<'a> LogRef<'a> {
296306
}
297307
}
298308

309+
pub fn from_parsed(file: Option<&'a str>, lineno: Option<u32>, body: &'a str) -> Self {
310+
let details = Some(LogDetails {
311+
file,
312+
lineno,
313+
body: Some(body),
314+
});
315+
Self {
316+
line: body,
317+
details,
318+
}
319+
}
320+
299321
pub fn with_format(line: &'a str, log_format: LogFormat) -> Self {
300322
let captures = log_format.captures(line);
301323
let file = captures.name("file").map(|file_match| file_match.as_str());
@@ -308,6 +330,14 @@ impl<'a> LogRef<'a> {
308330
details: Some(LogDetails { file, lineno, body }),
309331
}
310332
}
333+
334+
pub fn body(self) -> &'a str {
335+
if let Some(LogDetails { body: Some(s), .. }) = self.details {
336+
s
337+
} else {
338+
self.line
339+
}
340+
}
311341
}
312342

313343
pub fn link_to_source<'a>(log_ref: &LogRef, src_refs: &'a [SourceRef]) -> Option<&'a SourceRef> {
@@ -364,7 +394,7 @@ pub fn extract_variables<'a>(
364394
variables
365395
}
366396

367-
pub fn filter_log<R>(buffer: &str, filter: R, log_format: Option<String>) -> Vec<LogRef>
397+
pub fn filter_log<R>(buffer: &str, filter: R, log_format: Option<String>) -> Vec<LogRef<'_>>
368398
where
369399
R: RangeBounds<usize>,
370400
{
@@ -432,6 +462,7 @@ pub fn extract_logging(sources: &[CodeSource], tracker: &ProgressTracker) -> Vec
432462
None
433463
} else {
434464
Some(StatementsInFile {
465+
filename: matched.first().unwrap().source_path.clone(),
435466
log_statements: matched,
436467
matcher: RegexSet::new(patterns).expect("To combine patterns"),
437468
})

src/source_ref.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ pub enum FormatArgument {
1616
#[derive(Clone, Debug, Serialize)]
1717
pub struct SourceRef {
1818
#[serde(rename(serialize = "sourcePath"))]
19-
pub(crate) source_path: String,
19+
pub source_path: String,
2020
#[serde(rename(serialize = "lineNumber"))]
2121
pub line_no: usize,
22-
pub(crate) column: usize,
23-
pub(crate) name: String,
24-
pub(crate) text: String,
22+
pub column: usize,
23+
pub name: String,
24+
pub text: String,
2525
#[serde(skip_serializing)]
2626
pub(crate) matcher: Regex,
27-
pub(crate) pattern: String,
27+
pub pattern: String,
2828
pub(crate) args: Vec<FormatArgument>,
2929
pub(crate) vars: Vec<String>,
3030
}

0 commit comments

Comments
 (0)