Skip to content

[improve] PIP-467: Convert pulsar-broker module logging from SLF4J to slog - #25535

Merged
merlimat merged 6 commits into
apache:masterfrom
merlimat:slog-broker
Apr 16, 2026
Merged

merlimat merged 6 commits into
apache:masterfrom
merlimat:slog-broker

Conversation

@merlimat

Copy link
Copy Markdown
Contributor

Summary

  • Convert 210 files in the pulsar-broker module from SLF4J to slog structured logging
  • Add derived loggers with class-level context attributes (e.g. topic, subscription, state) so that related log lines carry the same structured context automatically
  • Subclasses that previously inherited a protected final Logger log from their parent now declare their own logger that chains the parent's context via Logger.get(SubClass.class).with().ctx(super.log).build(), so the logger name matches the actual runtime class while still inheriting parent attributes
  • Rename leftover generic argN attrs to meaningful names; strip stale SLF4J {} placeholder text from log messages
  • Use short form log.level("msg") when no attributes are present

Test plan

  • ./gradlew :pulsar-broker:compileJava passes
  • ./gradlew :pulsar-broker:checkstyleMain passes
  • ./gradlew :pulsar-broker:compileTestJava passes
  • ./gradlew :pulsar-broker:checkstyleTest passes
  • CI passes

Motivation

PIP-467

Note

Please label this PR with ready-to-test

The '%s%' sequences were parsed as '%s' followed by an incomplete
format specifier '%', causing DuplicateFormatFlagsException at runtime.
Replace with '%s%%' to emit a literal percent sign.
The original SLF4J code was guarded by if(log.isDebugEnabled()), which
prevented servletRequest.getServletContext().getContextPath() from
being called. In tests using Mockito.mock(HttpServletRequest.class),
getServletContext() returns null, so the eager call NPEs.

Use lambda suppliers so the value is only computed when debug is
actually enabled.
snapshot.getSnapshotId() throws IllegalStateException when the
required field is not set. Use a method reference for lazy evaluation
since the call was previously guarded by if(log.isDebugEnabled()).
In ServerCnx.handleConnect, authState.getAuthRole() throws
AuthenticationException when called before authentication completes.
The original code was inside if(log.isDebugEnabled()) so it was
never called in production (INFO level). Use a lambda supplier.

Also fix ReplicatedSubscriptionSnapshotCache where snapshot_id is
a required LightProto field that throws when not set.
The original code used @slf4j on SnapshotBuilder giving it its own
static logger. The slog conversion incorrectly changed it to use
controller.log, which is null when the controller is a Mockito mock
(mocks skip constructors and field initializers).

Restore @CustomLog on SnapshotBuilder so it has its own logger.
@merlimat
merlimat merged commit 4998cd9 into apache:master Apr 16, 2026
43 checks passed
@merlimat
merlimat deleted the slog-broker branch April 16, 2026 13:20
@lhotari lhotari added this to the 5.0.0-M1 milestone Jun 12, 2026
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.

2 participants