Skip to content

feat(pipeline): coalesce multi-line stack traces into one event#1

Merged
maxie7 merged 1 commit into
mainfrom
feat/m7-multiline-grouping
Jul 17, 2026
Merged

feat(pipeline): coalesce multi-line stack traces into one event#1
maxie7 merged 1 commit into
mainfrom
feat/m7-multiline-grouping

Conversation

@maxie7

@maxie7 maxie7 commented Jul 17, 2026

Copy link
Copy Markdown
Owner

A multi-line stack trace previously exploded into one template per frame — a Python FastAPI traceback became ~40 "novel" templates in M4 live testing, which is exactly the noise logscry exists to suppress.

Add a coalescer stage upstream of templating: a standalone goroutine folds continuation lines (indentation, frame markers, language cues for Python, Java, and Go) into the preceding logical line, so a traceback reaches templating as ONE model.LogLine and dedups as a single event. The heuristic is conservative — unrelated single-line logs stay separate — and gated leniency (blank lines, exception summaries, Go frames, the SIGSEGV "[signal ...]" line) only applies once a multi-line block is confirmed active.

Bounded latency: a buffered event is flushed on the next header, after an idle timeout, or when input closes. The timeout is configurable via group.timeout / --group-timeout (default 200ms; 0 disables). Coalescer state is confined to the single goroutine, so the no-lock concurrency model (RDI §3) is unchanged and go test -race stays green. Masking order and rules are untouched.

A multi-line stack trace previously exploded into one template per frame — a
Python FastAPI traceback became ~40 "novel" templates in M4 live testing, which
is exactly the noise logscry exists to suppress.

Add a coalescer stage upstream of templating: a standalone goroutine folds
continuation lines (indentation, frame markers, language cues for Python, Java,
and Go) into the preceding logical line, so a traceback reaches templating as
ONE model.LogLine and dedups as a single event. The heuristic is conservative —
unrelated single-line logs stay separate — and gated leniency (blank lines,
exception summaries, Go frames, the SIGSEGV "[signal ...]" line) only applies
once a multi-line block is confirmed active.

Bounded latency: a buffered event is flushed on the next header, after an idle
timeout, or when input closes. The timeout is configurable via group.timeout /
--group-timeout (default 200ms; 0 disables). Coalescer state is confined to the
single goroutine, so the no-lock concurrency model (RDI §3) is unchanged and
go test -race stays green. Masking order and rules are untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@maxie7
maxie7 merged commit 846bd24 into main Jul 17, 2026
1 check passed
@maxie7
maxie7 deleted the feat/m7-multiline-grouping branch July 22, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant