Slf4jLogStatement

WARNING

LikelyError

View source code on GitHub

Summary

Make sure SLF4J log statements contain proper placeholders with matching arguments

Suppression

Suppress false positives by adding the suppression annotation @SuppressWarnings("Slf4jLogStatement") to the enclosing element.

Disable this pattern completely by adding -Xep:Slf4jLogStatement:OFF as compiler argument. Learn more.

Samples

Replacement

Shows the difference in example code before and after the bug pattern is applied.

 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Marker;
 import org.slf4j.MarkerFactory;
 
 class A {
   private static final String FMT_ERR = "format-string-with-%s-placeholder";
   private static final Logger LOG = LoggerFactory.getLogger(A.class);
 
   private final Marker marker = MarkerFactory.getMarker(A.class.getName());
   private final Object o = new Object();
   private final String s = o.toString();
   private final Throwable t = new Throwable();
 
   void m() {
     LOG.error(FMT_ERR, o);
-    LOG.error("format-string-with-'%s'-placeholder", o);
-    LOG.error("format-string-with-\"%s\"-placeholder", o);
-    LOG.error("format-string-with-%s" + "-placeholder", o);
+    LOG.error("format-string-with-'{}'-placeholder", o);
+    LOG.error("format-string-with-\"{}\"-placeholder", o);
+    LOG.error("format-string-with-{}" + "-placeholder", o);
   }
 }
 

Identification

Shows code lines which will (not) be flagged by this bug pattern.
A //BUG: Diagnostic contains: comment is placed above any violating line.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;

class A {
  private static final String FMT0 = "format-string-without-placeholders";
  private static final String FMT1 = "format-string-with-{}-placeholder";
  private static final String FMT_ERR = "format-string-with-%s-placeholder";
  private static final Logger LOG = LoggerFactory.getLogger(A.class);

  private final Marker marker = MarkerFactory.getMarker(A.class.getName());
  private final Object o = new Object();
  private final String s = o.toString();
  private final Throwable t = new Throwable();

  void m() {
    LOG.trace(s);
    LOG.debug(s, o);
    LOG.info(s, t);
    LOG.warn(s, o, t);
    LOG.error(marker, s);
    LOG.trace(marker, s, o);
    LOG.debug(marker, s, t);
    LOG.info(marker, s, o, t);

    LOG.warn(FMT0);
    // BUG: Diagnostic contains: Log statement contains 0 placeholders, but specifies 1 matching
    // argument(s)
    LOG.error(FMT0, o);
    LOG.trace(FMT0, t);
    // BUG: Diagnostic contains:
    LOG.debug(FMT0, o, t);
    LOG.info(marker, FMT0);
    // BUG: Diagnostic contains:
    LOG.warn(marker, FMT0, o);
    LOG.error(marker, FMT0, t);
    // BUG: Diagnostic contains:
    LOG.trace(marker, FMT0, o, t);

    // BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 0 matching
    // argument(s)
    LOG.debug(FMT1);
    LOG.info(FMT1, o);
    // BUG: Diagnostic contains:
    LOG.warn(FMT1, t);
    LOG.error(FMT1, o, t);
    // BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 2 matching
    // argument(s)
    LOG.trace(FMT1, o, o);
    // BUG: Diagnostic contains:
    LOG.debug(FMT1, o, o, t);
    // BUG: Diagnostic contains:
    LOG.info(marker, FMT1);
    LOG.warn(marker, FMT1, o);
    // BUG: Diagnostic contains:
    LOG.error(marker, FMT1, t);
    LOG.trace(marker, FMT1, o, t);
    // BUG: Diagnostic contains:
    LOG.debug(marker, FMT1, o, o);
    // BUG: Diagnostic contains:
    LOG.info(marker, FMT1, o, o, t);

    // BUG: Diagnostic contains: SLF4J log statement placeholders are of the form `{}`, not `%s`
    LOG.warn(FMT_ERR);
    // BUG: Diagnostic contains:
    LOG.error(FMT_ERR, t);
    // BUG: Diagnostic contains:
    LOG.trace(FMT_ERR, o);
    // BUG: Diagnostic contains:
    LOG.debug(FMT_ERR, o, t);
  }
}

Copyright © 2017-2024 Picnic Technologies BV