zoukankan      html  css  js  c++  java
  • Slf4j与log4j及log4j2、logbak的关系及使用方法

    Slf4j与log4j及log4j2的关系及使用方法

    slf4j

    slf4j仅仅是一个为Java程序提供日志输出的统一接口,并不是一个具体的日志实现方案,就比如JDBC一样,只是一种规则而已,所以单独的slf4j是不能工作的,必须搭配其他具体的日志实现方案,比如log4j或者log4j2,要在系统中使用slf4j,我们需要引入的核心包为:slf4j-api-1.6.4.jar。

    如果不想每次都写private  final Logger logger = LoggerFactory.getLogger(XXX.class); 可以在方法前用注解@Slf4j,然后直接使用log.info去打印日志。如果注解@Slf4j注入后找不到变量log,那就给IDE安装lombok插件(idea中:1、File  → settings →  Plugins,  然后点击“Browse repositories”;2、输入 lombok 搜索插件, 点install安装,安装完重启idea)。

    log4j

    如果在我们系统中单独使用log4j的话,我们只需要引入log4j的核心包就可以了,我这里用的是:log4j-1.2.17.jar,然后在系统中使用如下代码输出日志:

    private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(Log4jTest.class);

    在系统的src目录下添加依赖的配置文件:
     

    log4j2
      如果在我们系统中单独使用log4j2的话,我们只需要引入log4j2的核心包就可以了,我这里用的是:log4j-api-2.7.jar和log4j-core-2.7.jar,然后在系统中使用如下代码输出日志:

    private static org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getLogger(Log4jTest.class);

     在系统的src目录下添加依赖的配置文件。

    关于log4j2的官方文档介绍,请查看:http://logging.apache.org/log4j/2.x/index.html

    关于log4j2相关配置文件,大家可以从官方文档中了解,也可以参考:http://java12345678.iteye.com/blog/2382929

    log4j与log4j2的区别:

    1.获取Logger的api不一样,log4j的api为org.apache.log4j.Logger,而log4j2的api为org.apache.logging.log4j.Logger
    2.配置方式不一样,log4j2对properties的配置支持不是很好,它的格式一般为xml格式或者yaml格式,这种格式的可读性比较好,各种配置一目了然
    3.Log4j2.0基于LMAX Disruptor的异步日志在多线程环境下性能会远远优于Log4j 1.x和logback(官方数据是10倍以上)。

    slf4j+log4j
    如果我们在系统中需要使用slf4j和log4j来进行日志输出的话,我们需要引入下面的桥接jar包:
    log4j核心jar包:log4j-1.2.17.jar
    slf4j核心jar包:slf4j-api-1.6.4.jar
    slf4j与log4j的桥接包:slf4j-log4j12-1.6.1.jar,这个包的作用就是使用slf4j的api,但是底层实现是基于log4j.

             private static final Logger logger = LoggerFactory.getLogger(Slf4jTest2.class);

    slf4j+log4j2
    如果我们在系统中需要使用slf4j和log4j2来进行日志输出的话,我们需要引入下面的jar包:
    log4j2核心jar包:log4j-api-2.7.jar和log4j-core-2.7.jar
    slf4j核心jar包:slf4j-api-1.6.4.jar
    slf4j与log4j2的桥接包:log4j-slf4j-impl-2.7.jar,这个包的作用就是使用slf4j的api,但是底层实现是基于log4j2.

      private static final Logger logger = LoggerFactory.getLogger(Slf4jTest2.class);

    slf4j+log4j不修改代码升级到log4j2
    如果我们系统中刚开始用的是slf4j和log4j,然后出于性能考虑,要升级到slf4j和log4j2,并且不需要改动任何代码的话(因为我们系统可能是一个大工程,然后基本上每个类都会有日志输出,改动代码可能牵一发而动全身),出于这个考虑,我们可以这样来进行修改(修改依赖):
    1、删除项目中存在的Log4j1.x所必须的log4j和slf4j-log4j12等依赖,例如从我们上面做的去升级的话,需要删除log4j-1.2.17.jar和slf4j-log4j12-1.6.1.jar
    2、添加log4j2和slf4j桥接包:log4j-slf4j-impl-2.7.jar替换log4j和slf4j桥接包:slf4j-log4j12-1.6.1.jar
    3、如果我们在系统中使用了log4j的api去获取Logger的话:

    org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(Log4jTest.class);

    我们需要添加log4j-1.2-api-2.7.jar去替换log4j-1.2.17.jar
    4、将log4j的properties文件修改为log4j2的xml文件
    然后,同样在系统中使用slf4j的方式获取日志:

    org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Self4jTest.class);

    使用slf4j库作为你的Java应用日志API层有很多好处,这里我会展示一小部分关于如何使用和配置它的例子。

    你可以把slf4j想成一个Java的接口,然后你需要实现这个接口,从而在运行时提供实际的日志记录,例如把日志写到控制台(STDOUT)或者一个文件上等等。每种实现(或成为绑定)都显而易见地有他们自己的方式来配置日志的输出,但是你的应用对实现者并无感知并且一直使用相同的org.slf4j.Logger API。让我们看看如何在实际中使用它。

    使用slf4j做简单的日志记录

    创建基于Maven的工程,在pom.xml中添加如下内容

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.5</version>
    </dependency>

    现在你可以在你的Java代码中这样使用Logger

    package deng;
    
    import org.slf4j.*;
    
    public class Hello {
        static Logger LOGGER = LoggerFactory.getLogger(Hello.class);
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++)
                if (i % 2 == 0)
                    LOGGER.info("Hello {}", i);
                else
                    LOGGER.debug("I am on index {}", i);
        }
    }

    以上代码可以编译通过,但是当你运行它时,你会看到这样的输出

    bash> java deng.Hello
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

    上面的意思是,在运行时,你没有做日志的实现(或者说日志的绑定),所以slf4j简简单单的使用了一个什么也不会做的空实现。
    为了看到正确的输出,你应该尝试使用一个简单(simple)的实现,这个实现根本不需要任何配置!只要回到pom.xml然后添加如下配置

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.5</version>
    </dependency>

    现在你可以在控制台(STDOUT)看见INFO级别的日志输出了。这个简单的logger会默认显示任何INFO或者更高级别的信息。想要看DEBUG级别的信息,你需要在Java启动时传入这个系统属性(system property)

    -Dorg.slf4j.simpleLogger.defaultLogLevel=DEBUG

    使用slf4j与Log4j日志

    现在我们可以试验并更换不同的日志实现,但你的程序代码可以保持不变。
    我们要做的是用另一个流行的日志实现来替换掉slf4j-simple,比如Log4j。

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.5</version>
    </dependency>

    又一次,我们必须对我们选的每一个日志实现做配置。在这个例子中,我们需要一个文件src/main/resources/log4j.properties

    log4j.rootLogger=DEBUG, STDOUT
    log4j.logger.deng=INFO
    log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
    log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
    log4j.appender.STDOUT.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

    重运行你的程序,你会看到同样的输出结果。

    使用slf4j和JDK日志

    JDK实际上带有一个日志包,你可以在pom.xml中替换为另一个日志实现。

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-jdk14</artifactId>
        <version>1.7.5</version>
    </dependency>

    现在JDK日志的配置起来有一点困难。这里不仅需要一个配置文件src/main/resources/logging.properties,你还需要添加一个系统属性

    -Djava.util.logging.config.file=logging.properties

    这是一个logging.properties的示例

    level=INFO
    handlers=java.util.logging.ConsoleHandler
    java.util.logging.ConsoleHandler.level=FINEST
    deng.level=FINEST

    使用slf4j和Logback日志

    Logback日志实现是一个高质量的实现。如果你想在项目中写认真的代码,你会想要考虑这中方式。还是修改你的pom.xml文件,替换成这样

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.0.13</version>
    </dependency>

    这是一个简单的配置src/main/resources/logback.xml

     
    <configuration>
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
    
        <logger name="deng" level="DEBUG"/>
    
        <root level="INFO">
            <appender-ref ref="STDOUT" />
        </root>
    </configuration>
  • 相关阅读:
    记一道乘法&加法线段树(模版题)
    2021CCPC网络赛(重赛)题解
    Codeforces Round #747 (Div. 2)题解
    F. Mattress Run 题解
    Codeforces Round #744 (Div. 3) G题题解
    AtCoder Beginner Contest 220部分题(G,H)题解
    Educational Codeforces Round 114 (Rated for Div. 2)题解
    Codeforces Global Round 16题解
    Educational Codeforces Round 113 (Rated for Div. 2)题解
    AtCoder Beginner Contest 182 F
  • 原文地址:https://www.cnblogs.com/cfas/p/11179246.html
Copyright © 2011-2022 走看看