perf: use slf4j placeholders instead of string interpolation in logging - #3537
Merged
Merged
Conversation
Motivation:
Several slf4j log calls in main sources built their message with Scala
string interpolation, so the message was formatted eagerly even when the
level was disabled. A few others carried an `s` prefix on a literal that
had no interpolation at all, which is misleading next to the `{}`
placeholders in the same string.
Modification:
- Replaced interpolated log messages with slf4j `{}` placeholders and
lazily formatted arguments in persistence-typed `BehaviorSetup` (both
the event-sourced and durable-state variants),
`EventSourcedBehaviorImpl`, and the testkit `LogCapturing` /
`LogCapturingExtension` rules.
- Dropped the redundant `s` prefix from log literals that contain no
interpolation in `Running` and `RequestingRecoveryPermit` (both
variants).
- `BehaviorSetup.onSignal` now passes the signal as a placeholder
argument and keeps the throwable as the trailing slf4j argument, so
the stack trace is still logged without rendering the exception into
the message eagerly.
Result:
Log message rendering is deferred to the logging backend and only
happens when the level is enabled. Rendered output is unchanged apart
from `onSignal`, where the exception `toString` is no longer duplicated
in the message text; it remains available via the logged throwable.
Tests:
- sbt "actor-testkit-typed/compile" "persistence-typed/compile" - pass
- scalafmt on changed files - pass
- No behavior change beyond log formatting; covered by existing
EventSourcedBehaviorLoggingSpec assertions on "Handled command"
References:
None - internal logging cleanup
Philippus
approved these changes
Sep 11, 2026
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.
Motivation
Several slf4j log calls in main sources built their message with Scala string interpolation, so the message was formatted eagerly even when the level was disabled. A few others carried an
sprefix on a literal with no interpolation at all, which is misleading next to the{}placeholders in the same string.Modification
{}placeholders and lazily formatted arguments in persistence-typedBehaviorSetup(both the event-sourced and durable-state variants),EventSourcedBehaviorImpl, and the testkitLogCapturing/LogCapturingExtensionrules.sprefix from log literals that contain no interpolation inRunningandRequestingRecoveryPermit(both variants).BehaviorSetup.onSignalnow passes the signal as a placeholder argument and keeps the throwable as the trailing slf4j argument, so the stack trace is still logged without rendering the exception into the message eagerly.Result
Log message rendering is deferred to the logging backend and only happens when the level is enabled. Rendered output is unchanged apart from
onSignal, where the exceptiontoStringis no longer duplicated in the message text; it remains available via the logged throwable.Tests
sbt "actor-testkit-typed/compile" "persistence-typed/compile"- passscalafmton changed files - passEventSourcedBehaviorLoggingSpecassertions on"Handled command"cover the unchanged message text. Full test run left to CI.References
None - internal logging cleanup