Add rainbowgum-jfr: JDK Flight Recorder LogOutput - #371
Draft
agentgt wants to merge 1 commit into
Draft
Conversation
New optional module, separate from core since it requires the jdk.jfr module. JfrLogOutput commits each event as a JFR event instead of writing bytes, one event type per level (RainbowGumLogEvent.TraceEvent/ DebugEvent/InfoEvent/WarnEvent/ErrorEvent) so each can be independently enabled/thresholded/stack-traced through a normal .jfc configuration or -XX:StartFlightRecording, the same as any other JFR event - not through Rainbow Gum properties. TRACE/DEBUG default disabled (@enabled(false)) since they're usually too high volume to want on by default in a recording. Inspired by https://github.com/mbien/JFRLog, adapted to Rainbow Gum's LogEvent/LogOutput model (one output class using Event.isEnabled() per instance, per the standard JFR custom-event idiom, rather than a SLF4J bridge). MDC/key values aren't carried as fields since JFR custom event fields are limited to primitives/String/Class/Thread - documented as a deliberate scope cut, not an oversight. Since LogOutput is always paired with an encoder even though this one never looks at the encoded bytes (it reads fields straight off the LogEvent passed alongside them instead), the configurator also registers a near-zero-cost encoder (LogFormatter.builder().build(), a documented noop) under the same "jfr" scheme, so pairing output=jfr:/// with encoder=jfr:/// skips formatting bytes that would just be thrown away. The output still has to format the message once itself (for the JFR "message" field) regardless of which encoder is paired with it - that part isn't avoidable, only the encoder's redundant formatting is. Tests start a real in-process Recording, run events through the output, then read the dumped .jfr file back with RecordingFile and assert on the recorded fields - not just that commit() doesn't throw. Documented in doc/overview.html's Outputs section. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
agentgt
marked this pull request as draft
August 24, 2026 15:50
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.
New optional module, separate from core since it requires the jdk.jfr module. JfrLogOutput commits each event as a JFR event instead of writing bytes, one event type per level (RainbowGumLogEvent.TraceEvent/ DebugEvent/InfoEvent/WarnEvent/ErrorEvent) so each can be independently enabled/thresholded/stack-traced through a normal .jfc configuration or -XX:StartFlightRecording, the same as any other JFR event - not through Rainbow Gum properties. TRACE/DEBUG default disabled (@enabled(false)) since they're usually too high volume to want on by default in a recording. Inspired by https://github.com/mbien/JFRLog, adapted to Rainbow Gum's LogEvent/LogOutput model (one output class using Event.isEnabled() per instance, per the standard JFR custom-event idiom, rather than a SLF4J bridge).
MDC/key values aren't carried as fields since JFR custom event fields are limited to primitives/String/Class/Thread - documented as a deliberate scope cut, not an oversight.
Since LogOutput is always paired with an encoder even though this one never looks at the encoded bytes (it reads fields straight off the LogEvent passed alongside them instead), the configurator also registers a near-zero-cost encoder (LogFormatter.builder().build(), a documented noop) under the same "jfr" scheme, so pairing output=jfr:/// with encoder=jfr:/// skips formatting bytes that would just be thrown away. The output still has to format the message once itself (for the JFR "message" field) regardless of which encoder is paired with it - that part isn't avoidable, only the encoder's redundant formatting is.
Tests start a real in-process Recording, run events through the output, then read the dumped .jfr file back with RecordingFile and assert on the recorded fields - not just that commit() doesn't throw.
Documented in doc/overview.html's Outputs section.