mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-11 23:32:17 +00:00
Logging: continue a message's line breaks on indented lines (#3009)
* fix(logging): continue a message's line breaks on indented lines * address review: normalize CRLF before stripping the trailing newline
This commit is contained in:
@@ -125,7 +125,13 @@ fn utc_parts(secs: u64, nanos: u32) -> (i64, chrono::NaiveDateTime) {
|
||||
|
||||
/// One log line (without the newline): `<timestamp> <LEVEL> [<thread>] <target>: <message>`.
|
||||
fn format_line(ts: &str, level: log::Level, thread: &str, target: &str, message: &str) -> String {
|
||||
let message = message.strip_suffix('\n').unwrap_or(message);
|
||||
// CRLF becomes LF first, so a message ending in "\r\n" loses its final break like one ending
|
||||
// in "\n" (and its carriage return is not taken for a lone one).
|
||||
let message = message.replace("\r\n", "\n");
|
||||
let message = message.strip_suffix('\n').unwrap_or(&message);
|
||||
// A message's own line breaks (a path or name from a project or a script) continue it on
|
||||
// indented lines, so they can't pass for records of their own.
|
||||
let message = message.replace('\r', "\\r").replace('\n', "\n\t");
|
||||
format!("{ts} {level:<5} [{thread}] {target}: {message}")
|
||||
}
|
||||
|
||||
@@ -523,4 +529,22 @@ mod tests {
|
||||
"2026-10-08T07:59:17.728Z WARN [main] effectcraft_engine::autosave: disk full"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn line_breaks_in_a_message_continue_it_on_indented_lines() {
|
||||
let forged = "cache at /tmp/x\n2026-10-08T07:59:18.000Z ERROR [main] effectcraft_engine: forged\rend";
|
||||
let line = format_line("2026-10-08T07:59:17.728Z", log::Level::Info, "main", "t", forged);
|
||||
assert_eq!(line.lines().count(), 2);
|
||||
assert!(line.lines().nth(1).unwrap().starts_with('\t'), "{line}");
|
||||
assert!(!line.contains('\r'), "{line}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_trailing_crlf_is_one_line_break_not_a_lone_carriage_return() {
|
||||
let line = |m| format_line("t", log::Level::Info, "main", "t", m);
|
||||
assert_eq!(line("cache\r\n"), line("cache"));
|
||||
assert_eq!(line("a\r\nb\r\n"), line("a\nb"));
|
||||
// A lone one, even at the end, is still escaped.
|
||||
assert!(line("cache\r").ends_with("cache\\r"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user