findbugs-slf4j bug pattern

FindBugs plugin for SLF4J

License

License

Categories

Categories

SLF4J Application Layer Libs Logging
GroupId

GroupId

jp.skypencil.findbugs.slf4j
ArtifactId

ArtifactId

bug-pattern
Last Version

Last Version

1.5.0
Release Date

Release Date

Type

Type

jar
Description

Description

findbugs-slf4j bug pattern
FindBugs plugin for SLF4J
Project URL

Project URL

https://github.com/KengoTODA/findbugs-slf4j

Download bug-pattern

How to add to project

<!-- https://jarcasting.com/artifacts/jp.skypencil.findbugs.slf4j/bug-pattern/ -->
<dependency>
    <groupId>jp.skypencil.findbugs.slf4j</groupId>
    <artifactId>bug-pattern</artifactId>
    <version>1.5.0</version>
</dependency>
// https://jarcasting.com/artifacts/jp.skypencil.findbugs.slf4j/bug-pattern/
implementation 'jp.skypencil.findbugs.slf4j:bug-pattern:1.5.0'
// https://jarcasting.com/artifacts/jp.skypencil.findbugs.slf4j/bug-pattern/
implementation ("jp.skypencil.findbugs.slf4j:bug-pattern:1.5.0")
'jp.skypencil.findbugs.slf4j:bug-pattern:jar:1.5.0'
<dependency org="jp.skypencil.findbugs.slf4j" name="bug-pattern" rev="1.5.0">
  <artifact name="bug-pattern" type="jar" />
</dependency>
@Grapes(
@Grab(group='jp.skypencil.findbugs.slf4j', module='bug-pattern', version='1.5.0')
)
libraryDependencies += "jp.skypencil.findbugs.slf4j" % "bug-pattern" % "1.5.0"
[jp.skypencil.findbugs.slf4j/bug-pattern "1.5.0"]

Dependencies

compile (2)

Group / Artifact Type Version
com.google.guava : guava jar 28.0-jre
org.slf4j : slf4j-api jar 1.7.26

provided (2)

Group / Artifact Type Version
com.github.spotbugs : spotbugs jar 3.1.12
org.projectlombok : lombok jar 1.18.8

runtime (1)

Group / Artifact Type Version
org.junit.jupiter : junit-jupiter-engine jar 5.4.2

test (7)

Group / Artifact Type Version
org.junit.jupiter : junit-jupiter-api jar 5.4.2
org.mockito : mockito-core jar 2.28.2
com.google.truth : truth jar 0.46
com.github.spotbugs : test-harness jar 3.1.12
com.youdevise : test-driven-detectors4findbugs jar 1.0
junit : junit jar 4.12
org.junit.vintage : junit-vintage-engine jar 5.4.2

Project Modules

There are no modules declared in this project.

FindBugs bug pattern for SLF4J

This product helps you to verify usage of SLF4J 1.6, 1.7 and 1.8. Works with Java8 and later.

To use this plugin with SonarQube, see here. To detect problems at compile time, see errorprone-slf4j.

Build Status Quality Gate Maven Central

Motivation

SLF4J is useful logging facade, but sometimes we mistake how to use. Can you find mistakes in following class? It is not so easy especially in huge product, this FindBugs plugin will help you to find.

class Foo {
    private static final Logger logger = LoggerFactory.getLogger(Bar.class);

    void rethrow(String name, Throwable t) {
        logger.info("Hello, {}!");
        logger.warn("Now I will wrap and throw {}", t);
        throw new RuntimeException(t);
    }
}

Provided bug patterns

Currently this product provides 9 patterns.

SLF4J_PLACE_HOLDER_MISMATCH

This pattern checks how placeholder is used. Alert if count of placeholder does not match to count of parameter.

Note: Format should be CONST to use this bug pattern. Use SLF4J_FORMAT_SHOULD_BE_CONST bug pattern to check it.

class Foo {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    void method() {
        // invalid: this logging method has 2 placeholders, but given parameter is only 1.
        logger.info("{}, {}.", "Hello");

        // valid
        logger.info("{}, {}.", "Hello", "World");

        // invalid: Throwable instance does not need placeholder
        logger.error("{}, {}", "Hello", new RuntimeException());

        // valid
        logger.error("{}", "Hello", new RuntimeException());
    }
}

SLF4J_FORMAT_SHOULD_BE_CONST

This pattern checks given format is CONST or not. Alert if format is not CONST.

class Foo {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    void method() {
        // invalid: format is not CONST
        String format = new String("Hello, ");
        logger.info(format + "{}.", "World");

        // valid
        logger.info("Hello, {}.", "World");
    }
}

SLF4J_UNKNOWN_ARRAY

This pattern reports a bug if your code is using array which is provided as method argument or returned from other method. It makes our verification harder, so please stop using it.

class Foo {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    void method(Object[] args) {
        // invalid: using method argument as parameter
        logger.info("Hello, {}.", args);

        // valid
        logger.info("Hello, {}.", new Object[]{ "World" });
    }
}

SLF4J_LOGGER_SHOULD_BE_PRIVATE

This pattern reports non private field whose type is org.slf4j.Logger.

class Foo {
    // invalid: field is not private
    public final Logger logger = LoggerFactory.getLogger(getClass());

    // valid
    private final Logger logger = LoggerFactory.getLogger(getClass());
}

SLF4J_LOGGER_SHOULD_BE_FINAL

This pattern reports non final field whose type is org.slf4j.Logger.

class Foo {
    // invalid: field is not final
    private Logger logger = LoggerFactory.getLogger(getClass());

    // valid
    private final Logger logger = LoggerFactory.getLogger(getClass());
}

SLF4J_LOGGER_SHOULD_BE_NON_STATIC

This pattern reports static field whose type is org.slf4j.Logger.

Sometimes using static logger is better than using non-static one. See official FAQ for detail.

If you need to use static logger, you can use PMD's default rule for logger instead.

class Foo {
    // invalid: field is static
    private static final Logger LOGGER = LoggerFactory.getLogger(Foo.class);

    // valid
    private final Logger logger = LoggerFactory.getLogger(getClass());
}

SLF4J_ILLEGAL_PASSED_CLASS

This pattern reports that illegal class is passed to LoggerFactory.getLogger(Class)

class Foo {
    // invalid: illegal class is passed to Factory
    private final Logger logger = LoggerFactory.getLogger(Bar.class);

    // valid
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final Logger logger = LoggerFactory.getLogger(Foo.class);
}

SLF4J_SIGN_ONLY_FORMAT

This pattern reports that log format which contains only sign and spaces. To make log readable, you have to use letter to explain your log.

class Foo {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    void method() {
        // invalid: bad readability
        logger.info("{}", id);

        // valid
        logger.info("{} signed in", userId);
    }
}

SLF4J_MANUALLY_PROVIDED_MESSAGE

This pattern reports needless message which is returned by Throwable#getMessage() or Throwable#getLocalizedMessage(). Normally binding will call these methods when you provide throwable instance as the last argument, so you do not have to call them manually.

class Foo {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    void method() {
        // invalid: needless 'e.getMessage()'
        logger.info("Error occured. Message is {}", e.getMessage(), e);

        // valid
        logger.info("Error occured.", e);
    }
}

How to use with Maven

To use this product, please configure your spotbugs-maven-plugin like below.

      <plugin>
        <groupId>com.github.spotbugs</groupId>
        <artifactId>spotbugs-maven-plugin</artifactId>
        <version>3.1.12</version>
        <configuration>
          <plugins>
            <plugin>
              <groupId>jp.skypencil.findbugs.slf4j</groupId>
              <artifactId>bug-pattern</artifactId>
              <version>1.5.0</version>
            </plugin>
          </plugins>
        </configuration>
      </plugin>

How to use with Gradle

To use these detectors from a Gradle build, please follow the example below:

plugins {
  id "java"
  id "com.github.spotbugs" version "1.6.4"
}

repositories {
  jcenter()
}

dependencies {
  compile "org.slf4j:slf4j-api:1.7.25"
  spotbugsPlugins "jp.skypencil.findbugs.slf4j:bug-pattern:1.4.2@jar"
}

Change log

See CHANGELOG.md for detail.

Copyright and license

Copyright 2012-2020 Kengo TODA

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Versions

Version
1.5.0
1.4.2
1.4.1
1.4.0
1.3.0
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.1
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0
0.4
0.3
0.2
0.1