Skip to content

fix: stitch multi-line stack traces into one log event in observability-logs-openobserve - #281

Open
TemRevil wants to merge 2 commits into
openchoreo:mainfrom
TemRevil:fix/openobserve-multiline-stacktraces
Open

fix: stitch multi-line stack traces into one log event in observability-logs-openobserve#281
TemRevil wants to merge 2 commits into
openchoreo:mainfrom
TemRevil:fix/openobserve-multiline-stacktraces

Conversation

@TemRevil

@TemRevil TemRevil commented Jul 10, 2026

Copy link
Copy Markdown

Purpose

Multi-line exceptions (a .NET FluentValidation.ValidationException, or a Java/Go/Python stack trace) emitted by a workload are shipped to OpenObserve as one record per physical line instead of one record per exception, so a single error is scattered across many records and continuation lines get inconsistent log levels. Fixes openchoreo/openchoreo#4150.

Approach

Follows the proposed fix in the issue, and mirrors #280 (the same fix for the opensearch module) so the sibling modules stay consistent:

  • Added a multiline filter between the tail input and the kubernetes filter, keyed on log content, using the built-in go, java, python parsers plus a custom dotnet parser (buffer On, flush_ms 2000).
  • Defined the dotnet [MULTILINE_PARSER] in parsers.conf — Fluent Bit has no built-in .NET parser. A comment documents how to add further custom parsers for formats the built-ins don't cover.

Verification

  • Checked the dotnet rules against a representative FluentValidation.ValidationException trace: the …Exception: … line matches start_state only, the at … / --- End of inner exception stack trace --- lines match cont only, and a following normal log line matches neither — so the exception is stitched into one record (level taken from the first line) and the next record starts cleanly.
  • Rendered template parses as valid YAML; resulting pipeline order is tail → multiline → kubernetes → http.

Summary by CodeRabbit

  • New Features
    • Improved log collection for multiline application logs.
    • Added support for combining Go, Java, Python, and .NET stack traces into single log entries.
    • Enhanced detection of .NET exception stack traces, including indented frames and stack trace completion markers.
    • Added buffering and timed flushing to improve multiline log handling.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8918eeb5-c7f9-4bbb-921c-5cd71ea6ca5b

📥 Commits

Reviewing files that changed from the base of the PR and between 3e003b8 and fd5a70b.

📒 Files selected for processing (1)
  • observability-logs-openobserve/helm/templates/fluent-bit/config.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • observability-logs-openobserve/helm/templates/fluent-bit/config.yaml

📝 Walkthrough

Walkthrough

Fluent Bit’s Kubernetes log pipeline now applies application-level multiline parsing for Go, Java, Python, and .NET stack traces, buffering records for up to 2000ms and combining recognized continuation lines.

Changes

Multiline stack-trace processing

Layer / File(s) Summary
Configure multiline stack-trace parsing
observability-logs-openobserve/helm/templates/fluent-bit/config.yaml
Adds a multiline filter for kube.* logs and defines a custom dotnet regex parser for exception and stack-trace continuation lines.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TailInput as Fluent Bit tail input
  participant MultilineFilter as multiline filter
  participant Parser as Built-in or dotnet parser
  participant OpenObserve
  TailInput->>MultilineFilter: Send kube.* log records
  MultilineFilter->>Parser: Parse multiline content from log key
  Parser-->>MultilineFilter: Return combined stack trace
  MultilineFilter->>OpenObserve: Forward combined log record
Loading

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific, concise, and accurately describes the main log-stitching change.
Description check ✅ Passed It covers the purpose and approach well and links the issue, though checklist and remarks sections are missing.
Linked Issues check ✅ Passed The changes add the required multiline filter and custom .NET parser, matching the issue's acceptance criteria.
Out of Scope Changes check ✅ Passed No unrelated code changes are apparent beyond the multiline log-stitching fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@observability-logs-openobserve/helm/templates/fluent-bit/config.yaml`:
- Around line 89-90: Update the continuation regex in the “cont” rule to require
a word boundary or whitespace after “at” (for example, `at\s` or `\bat\b`),
while preserving the existing `--- End of` matching.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 016b99f0-4aee-41b8-ba3b-011b13be9a4f

📥 Commits

Reviewing files that changed from the base of the PR and between 397acdc and 3e003b8.

📒 Files selected for processing (1)
  • observability-logs-openobserve/helm/templates/fluent-bit/config.yaml

Comment thread observability-logs-openobserve/helm/templates/fluent-bit/config.yaml Outdated
…ty-logs-openobserve

The tail input only set 'multiline.parser docker, cri', which handles
the container-runtime partial-line protocol but never concatenates
application lines belonging to one stack trace, so each frame reached
OpenObserve as its own record with its own inferred level.

Add an application-level multiline filter (go, java, python built-ins
plus a custom dotnet parser) between the tail input and the kubernetes
filter, and document in parsers.conf how to extend the parser list for
formats not covered by the built-ins.

Signed-off-by: Tem Revil <temrevil@gmail.com>
@TemRevil
TemRevil force-pushed the fix/openobserve-multiline-stacktraces branch from 3e003b8 to aa31194 Compare July 10, 2026 10:15
…egex

CodeRabbit flagged that the cont rule's alternation "at|--- End of"
matches "at" as a bare substring, so any continuation line starting
with a word like "atomic" or "attribute" (not just a stack frame "   at
...") would also be folded into the same multiline record. Require a
space after "at" so only actual stack-frame lines match.

Signed-off-by: Tem Revil <temrevil@gmail.com>
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

Stitch multi-line stack traces into a single log event in observability-logs-openobserve module

2 participants