Skip to content

Add rainbowgum-jfr: JDK Flight Recorder LogOutput - #371

Draft
agentgt wants to merge 1 commit into
mainfrom
feature/jfr-log-output
Draft

Add rainbowgum-jfr: JDK Flight Recorder LogOutput#371
agentgt wants to merge 1 commit into
mainfrom
feature/jfr-log-output

Conversation

@agentgt

@agentgt agentgt commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

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.

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
agentgt marked this pull request as draft August 24, 2026 15:50
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