From 4b0d9f13f72c0920f6c9a4bfb6287005fea18c95 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Tue, 3 Nov 2026 15:51:19 +0000 Subject: [PATCH] fix(logging): continue a message's line breaks on indented lines --- crates/engine/src/system/logging.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/engine/src/system/logging.rs b/crates/engine/src/system/logging.rs index 857a3e90d..e9df27de2 100644 --- a/crates/engine/src/system/logging.rs +++ b/crates/engine/src/system/logging.rs @@ -126,6 +126,9 @@ fn utc_parts(secs: u64, nanos: u32) -> (i64, chrono::NaiveDateTime) { /// One log line (without the newline): ` [] : `. fn format_line(ts: &str, level: log::Level, thread: &str, target: &str, message: &str) -> String { 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\n", "\n").replace('\r', "\\r").replace('\n', "\n\t"); format!("{ts} {level:<5} [{thread}] {target}: {message}") } @@ -472,4 +475,13 @@ 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}"); + } }