Why this matters
Preconditions and logging arguments should not require costly evaluations. Using precomputed values prevents unnecessary performance overhead, especially for logging.
Ensure that logging arguments and preconditions do not require costly evaluations before method calls.
Preconditions and logging arguments should not require costly evaluations. Using precomputed values prevents unnecessary performance overhead, especially for logging.
Side-by-side examples engineers can pattern-match during review.
logger.log(Level.DEBUG, "Something went wrong: " + message); // Noncompliant; string concatenation performed even when log level too high to show DEBUG messages
logger.fine("An exception occurred with message: " + message); // Noncompliant
LOG.error("Unable to open file " + csvPath, e); // Noncompliant
Preconditions.checkState(a > 0, "Arg must be positive, but got " + a); // Noncompliant. String concatenation performed even when a > 0
Preconditions.checkState(condition, formatMessage()); // Noncompliant. formatMessage() invoked regardless of condition
Preconditions.checkState(condition, "message: %s", formatMessage()); // Noncompliantlogger.log(Level.DEBUG, "Something went wrong: {0} ", message); // String formatting only applied if needed
logger.log(Level.SEVERE, () -> "Something went wrong: " + message); // since Java 8, we can use Supplier , which will be evaluated lazily
logger.fine("An exception occurred with message: {}", message); // SLF4J, Log4j
LOG.error("Unable to open file {0}", csvPath, e);
if (LOG.isDebugEnabled()) {
LOG.debug("Unable to open file " + csvPath, e); // this is compliant, because it will not evaluate if log level is above debug.
}
Preconditions.checkState(arg > 0, "Arg must be positive, but got %d", a); // String formatting only applied if needed
if (!condition) {
throw new IllegalStateException(formatMessage()); // formatMessage() only invoked conditionally
}
if (!condition) {
throw new IllegalStateException("message: " + formatMessage());
}logger.log(Level.DEBUG, "Something went wrong: " + message); // Noncompliant; string concatenation performed even when log level too high to show DEBUG messages
logger.fine("An exception occurred with message: " + message); // Noncompliant
LOG.error("Unable to open file " + csvPath, e); // Noncompliant
Preconditions.checkState(a > 0, "Arg must be positive, but got " + a); // Noncompliant. String concatenation performed even when a > 0
Preconditions.checkState(condition, formatMessage()); // Noncompliant. formatMessage() invoked regardless of condition
Preconditions.checkState(condition, "message: %s", formatMessage()); // Noncompliantlogger.log(Level.DEBUG, "Something went wrong: {0} ", message); // String formatting only applied if needed
logger.log(Level.SEVERE, () -> "Something went wrong: " + message); // since Java 8, we can use Supplier , which will be evaluated lazily
logger.fine("An exception occurred with message: {}", message); // SLF4J, Log4j
LOG.error("Unable to open file {0}", csvPath, e);
if (LOG.isDebugEnabled()) {
LOG.debug("Unable to open file " + csvPath, e); // this is compliant, because it will not evaluate if log level is above debug.
}
Preconditions.checkState(arg > 0, "Arg must be positive, but got %d", a); // String formatting only applied if needed
if (!condition) {
throw new IllegalStateException(formatMessage()); // formatMessage() only invoked conditionally
}
if (!condition) {
throw new IllegalStateException("message: " + formatMessage());
}From the same buckets as this rule.
Never emit Primary Account Number (PAN) or Sensitive Authentication Data (SAD: CVV/CVC, full track data, PIN) to application or audit logs. Per PCI DSS 4.0 Req. 3 and 10, always mask PAN as first6last4 and fully redact SAD before logging.