Repository navigation
fix(multiline): stitch bare Java exception headers on containerd - #1807
Open
zanejohnson-azure wants to merge 1 commit into
Open
zanejohnson-azure wants to merge 1 commit into
zanejohnson-azure wants to merge 1 commit into
Conversation
containerd (CRI) log lines carry no trailing newline, so the start rule of fluent-bit's built-in "java" multiline parser ([:\r\n] after the exception class) never matches a header that ends with the class name, e.g. a bare java.lang.NullPointerException or `Exception in thread "main" X`. Its frames are then emitted as separate records, or appended to a stale multiline state so the record starts with "\tat ...". Docker json-file lines end in "\n" and are not affected. Add azmon_java to azm-containers-parser-multiline.conf: a copy of the built-in java parser whose start rule also matches at end of line. Both fluent-bit conf customizers now render "java" as "azmon_java" in the multiline filter. A distinct name is needed because a custom parser named "java" is shadowed by the built-in one. AZMON_MULTILINE_LANGUAGES and telemetry still report "java". Also applies to dotnet, which maps to java. ICM 21000002363585 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: b709124f-6f9e-4ca4-89bd-bf3768441b9c
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). 2 pipeline(s) were filtered out due to trigger conditions. |
Contributor
Author
Cluster A/B validation: PASSI ran the repo's
Also verified
Not run on a node
This covers both "Remaining before merge" items: the Windows image check and the |
Contributor
|
This PR is stale because it has been open 7 days with no activity. Remove stale label or comment or this will be closed in 5 days. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On containerd, ContainerLogV2 multiline doesn't group Java (and .NET) stack traces whose exception header has no message, for example a bare
java.lang.NullPointerException. This PR fixes that. Reported in ICM 21000002363585.Root cause
main.shandmain.ps1switch the tail input toMultiline.Parser cri. CRIlogvalues have no trailing\n; Docker json-file values do.:or a newline after the class name. fluent-bit's built-injavastart rule is/(.)(?:Exception|Error|Throwable|V8 errors stack trace)[:\r\n]/. On CRI, a header that ends with the exception class never matches. Examples:java.lang.NullPointerExceptionException in thread "main" java.lang.X...Error---> System.Xwith no message\tatframes after the unmatched header can then group under state left by an earlier trace. The result is the header alone, then a record that starts with\tat ....: messagematch, so most traces group correctly. Docker-runtime clusters aren't affected.This isn't a documented ContainerLogV2 multiline limitation. The trace is a standard Java exception, and the same input groups correctly on Docker.
Fix
azm-containers-parser-multiline.confgetsazmon_java, a copy of the built-injavaparser (src/multiline/flb_ml_parser_java.c). Its start rule also matches at end of line,(?:[:\r\n]|$); every other rule is unchanged.fluent-bit-conf-customizer.rbandfluent-bit-geneva-conf-customizer.rbrenderjavaasazmon_javainmultiline.parser. For example,go,java,pythonbecomesgo,azmon_java,python.[MULTILINE_PARSER]namedjavais shadowed by the built-in one.AZMON_MULTILINE_LANGUAGESand telemetry still reportjava.dotnetalready maps tojava, so it also gets the fix. Linux and Windows share the parser file and customizers.Validation
Production conf A/B on containerd.
fluent-bit.confrendered by the customizer fromci_prodvs. this branch. Themain.shCRIsed, the real tail input, and the real filters are used;omsoutputs are replaced with stdout.ci_prodjava*Exception in thread "main" XCaused bychainXErrorINFO ... Error+ normal line)nested exception is:* Docker reference values come from the same inputs in a minimal multiline harness. On Docker,
azmon_javaoutput was identical to the built-in parser in every scenario, so there is no regression.\tat ....Unit test. The new
fluent-bit-conf-customizer_test.rbis picked up bytest/unit-tests/test_driver.rbin the Ruby-Tests job. It checks that:multiline.parser go,azmon_java,pythonwithout loggingconfig::errorjavaare unchangedazmon_javastart rule matches message-less headers without a trailing newline (Ruby uses Onigmo, the same regex engine as fluent-bit)With the
ci_prodcustomizers and parser file, the test fails (2 failures); on this branch it passes. The full Ruby suite (test_driver.rb) also passes: 96 runs, 0 failures, 0 errors.Remaining before merge
javaparser.multiline-validationA/B on a test cluster.Follow-ups (not in this PR)
javastart rule should accept end of lineazmon_javain sync with the built-in parser on fluent-bit upgrades (noted in the conf comment).