# Avoid Concatenation in Logging Statements
# Description
Concatenated arguments in a logging message lead to concatenation and therefore an evaluation, even if the logging level is too low to show a message. This leads to a needless performance reduction and is classified as a "Major" code smell by SonarCloud S2629 (opens new window).
By using the built-in string formatting of loggers, an evaluation will only happen if the logging level permits the message to be displayed.
This rule transforms logger statements where the message uses concatenation by introducing string formatting placeholders {}
and moving the concatenated parts to be parameters.
Requirements
This rule works on the following types and implementations of them:
# Benefits
Improved performance, especially in cases where concatenation is used at low logging levels, such as debug
.
# Tags
# Code Changes
# Introducing Parameters and Merging Strings
Pre
Object o = ...;
logger.debug("o = '" + o + "', ONE = '" + BigDecimal.ONE + "', 1 = '" + 1 + "'");
Post
Object o = ...;
logger.debug("o = '{}', ONE = '{}', 1 = '{}'", o, BigDecimal.ONE, 1);
# No Merging of Consecutive Strings
Consecutive string literals do not get merged. Since the compiler already merges such cases, that does not make sense from a performance standpoint.
Pre
int i;
logger.info("String: " + "FooBar" + ", i: " + i);
Post
int i;
logger.info("String: " + "FooBar" + ", i: {}", i);
# Throwable Types as Parameter
Types inheriting from java.lang.Throwable
(e.g., any java.lang.Exception
) may already be present as a parameter in a concatenated message. Such cases simply introduce new parameters for the concatenated items, while, of course, not changing the behavior of Throwable
logging.
Pre
try {
// code
} catch (Exception e) {
logger.info("Concatenated items: " + BigDecimal.ZERO + 1, e);
}
Post
try {
// code
} catch (Exception e) {
logger.info("Concatenated items: {}{}", BigDecimal.ZERO, 1, e);
}
# Limitations
This rule does not apply to logging messages that use concatenation but already contain parameters (other than a Throwable
parameter). In such cases, it is assumed that a deliberate decision has been made. See examples below:
// this will not transform
logger.info("A " + 1 + " B {}", 2);
🛠️ Auto-refactor Available
You can auto-refactor this with jSparrow.
Drop this button to your Eclipse IDE workspace to install jSparrow for free:
Need help? Check out our installation guide.