详解slf4j log4j logback log4j2

Posted 工匠小猪猪的技术世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解slf4j log4j logback log4j2相关的知识,希望对你有一定的参考价值。

当前浏览器不支持播放音乐或语音,请在微信或其他浏览器中播放 详解slf4j log4j logback log4j2 详解slf4j log4j logback log4j2

首先性能最好的当然是log4j2,详细阅读文章:


当然,如果你想通过编程顺利找到女朋友,可以阅读这篇文章:

部分来源:https://www.cnblogs.com/Sinte-Beuve/p/5758971.html

(本文版权归原作者所有。转载文章仅为传播更多信息之目的,如有侵权请与我们联系,我们将及时处理。)

详解slf4j log4j logback log4j2

slf4j log4j logback的关系

The Simple Logging Facade for Java是什么?

笼统的讲就是slf4j是一系列的日志接口,而log4j logback是具体实现了的日志框架。接下来我们跟着官方文档详细的来看一下他们的关系。

The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks, such as java.util.logging, logback and log4j. SLF4J allows the end-user to plug in the desired logging framework at deployment time. Note that SLF4J-enabling your library/application implies the addition of only a 
single mandatory dependency, namely slf4j-api-1.7.21.jar.

官方文档的这一段话已经明确描述了三者的关系。slf4j译为简单日志门面,是日志框架的抽象。而log4j和logback是众多日志框架中的几种。

这里写了几行简单的代码来验证一下。

public class Program {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(Program.class);
        logger.info("hello world");
    }
}

详解slf4j log4j logback log4j2

从运行结果可以看到,由于没有给出具体的logger实现,无法在控制台输出日志。也就是说我们在具体开发中,需要绑定一个日志框架,才能正常的使用slf4j。

log4j和logback呢?

而log4j和logback就是两个受欢迎的日志框架。但两者又有不同。

  • log4j是apache实现的一个开源日志组件。(Wrapped implementations)

  • logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架。是slf4j的原生实现。(Native implementations)

详解slf4j log4j logback log4j2

上图可以看到应用程序对日志框架的调用关系。应用程序调用slf4j api,而日志的输出最终是由底层的日志框架来实现的。这张图也提现了log4j和logback的不同。

详解slf4j log4j logback log4j2

官方文档对logback的描述

NATIVE IMPLEMENTATION There are also SLF4J bindings external to the SLF4J project, e.g. logback which implements SLF4J natively. Logback's ch.qos.logback.classic.Logger class is a direct implementation of SLF4J's org.slf4j.Logger interface. Thus, using SLF4J in conjunction with logback involves strictly zero memory and computational overhead.

可以看到logback是直接实现了slf4j的接口,是不消耗内存和计算开销的。而log4j不是对slf4j的原生实现,所以slf4j api在调用log4j时需要一个适配层。

总结:

  1. slf4j是java的一个日志门面,实现了日志框架一些通用的api,log4j和logback是具体的日志框架。

  2. 他们可以单独的使用,也可以绑定slf4j一起使用。

  • 单独使用。分别调用框架自己的方法来输出日志信息。

  • 绑定slf4j一起使用。调用slf4j的api来输入日志信息,具体使用与底层日志框架无关(需要底层框架的配置文件)

显然这里我们不推荐单独使用日志框架。假设项目中已经使用了log4j,而我们此时加载了一个类库,而这个类库依赖另一个日志框架。这个时候我们就需要维护两个日志框架,这是一个非常麻烦的事情。而使用了slf4j就不同了,由于应用调用的抽象层的api,与底层日志框架是无关的,因此可以任意更换日志框架。

使用slf4j绑定日志系统的优势

  • 1)软件工程的角度。抽象,解耦,便于维护。可以参考一下上面的例子。

  • 2)语法设计角度。slf4j有{}占位符,而log4j需要用“+”来连接字符串,既不利于阅读,同时消耗了内存(heap memory)。

  • 3)详细的描述可以参考:http://www.importnew.com/7450.html

log4j与logback

作为log4j的开发者,对log4j一定不陌生,他是apache的一个开源日志框架。而logback相对于log4j来说,更新一点,是由log4j的作者设计实现的,第一个版本是2011推出的。无论从设计上还是实现上,Logback相对log4j而言有了相对多的改进。但是两者的用法几乎差别不大。下面是logback的优势:

  • 更快的执行速度

  • 充分的测试

  • logback-classic 非常自然的实现了SLF4J

  • 丰富的扩展文档

  • 可以使用使用XML配置文件或者Groovy

  • 自动重新载入配置文件

  • 优雅地从I/O错误中恢复

  • 自动清除旧的日志归档文件

  • 自动压缩归档日志文件

  • 更多优点可以参考官方文档。中文版 英文版

以上,从性能的角度,可以尽快从log4j迁移到logback上来。

更快的执行速度

基于我们先前在log4j上的工作,logback 重写了内部的实现,在某些特定的场景上面,甚至可以比之前的速度快上10倍。在保证logback的组件更加快速的同时,同时所需的内存更加少。


为什么要推荐logback作为首推的日志框架,仅看上面这一点,就觉得logback的强悍和优秀!


详解slf4j log4j logback log4j2

1、commons-loggin,slf4j只是一种日志抽象门面,不是具体的日志框架。

2、log4j,logback是具体的日志框架。

3、一般首选使用slf4j+logback,或者slf4j+log4j,commons-logging+log4j。

slf4j绑定log4j的用法

由于现在log4j使用的还比较多,所以介绍下他的基本用法。

ide相关设置

这里我们使用的IntelliJ IDEA2016.1和maven。

  1. 在pom.xml添加相关依赖。

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

详解slf4j log4j logback log4j2

此时会自动添加三个jar包。

配置文件

log4j的正常运行需要配置文件,配置文件类型:log4j配置文件可以是log4j.xml也可以是log4j.properties。需要为其配置root、appender、layout等信息。

虽然网上大多数教程都是用log4j.properties来配置的(键值对),但是我个人觉得用xml配置,节点更清晰,而且在idea下有代码提示,可以降低配置错误的概率。下面我就就不具体讲配置文件了,只提几个关键的地方。

  1. 必须配置root logger和一个appender。

  2. 日志输出级别,由高到低为

        FATAL        
        ERROR      
        WARN        
        INFO        
        DEBUG    

下面给出配置文件。

<?xml version="1.0"  encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>

    <!--若干个appender的定义-->
    <!--org.apache.log4j.ConsoleAppender 输出到控制台-->
    <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
        <!--输出格式-->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>

        </layout>
    </appender>

    <!--org.apache.log4j.DailyRollingFileAppender 每天产生一个日志文件-->
    <appender name="myFile" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="output.log"/><!--文件位置-->
        <param name="Append" value="true"/><!--是否选择追加-->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>

        </layout>
    </appender>

    <!--org.apache.log4j.RollingFileAppender 滚动日志文件输出 文件大小到达一定尺寸时重新产生新的文件-->
    <!--<appender name="myFile" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="D:/output.log" />
        <param name="Append" value="true" />
        <param name="MaxFileSize" value="500KB"/>
        <param name="MaxBackupIndex" value="10" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
        </layout>
    </appender>-->


    <!--将各个包中的类日志输出到不同的日志文件中
        这样可以便于日志的分类。
        可以通过这个设置,把业务逻辑的日志添加到数据库。起到过滤的作用
    -->

    <!--这段配置的就是说把包名为“com.zjut.a1”且优先级为debug的日志通过myFile这个appender来处理。
    -->

    <category name="com.zjut.a1">
        <priority value="debug"/>
        <appender-ref ref="myFile"/>
    </category>


    <!-- 根logger的设置-->
    <root>
        <!--优先级设置,假设设置为“info”,则无法输出debug级别的日志-->
        <priority value="debug"/>
        <!--<priority value="info"/>-->
        <!--<priority value="warn"/>-->
        <!--<priority value="error"/>-->
        <!--<priority value="fatal"/>-->

        <!--添加刚才设置的appender-->
        <appender-ref ref="myConsole"/>
        <appender-ref ref="myFile"/>
    </root>
</log4j:configuration>
 
     

控制台输出日志的配置文件(复制可以直接用)

<?xml version="1.0"  encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
    <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>

        </layout>
    </appender>
    <root>
        <priority value="debug"/>
        <appender-ref ref="myConsole"/>
    </root>
</log4j:configuration>

配置文件详解,可以参考:http://zengxiantao.iteye.com/blog/1881700

应用调用

// 类名.class
Logger logger = LoggerFactory.getLogger(Program.class);
// 输出字符串
logger.debug("this is a debug msg");
// 占位符
logger.debug("hi,welcome {},today is {}","admin","Sunday");

slf4j绑定logback的用法

pom.xml添加依赖

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

网上教程添加了很多,其实只要添加这一个,其他的依赖jar都会被下载下来。

配置文件

配置文件几乎和log4j差不多,如下。选择需要的appender就可以了。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>


    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->

        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
        </encoder>
    </appender>

    <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
         the key "bySecond" into the logger context. This value will be
         available to all subsequent configuration elements. -->

    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>testFile-${bySecond}.log</file>
        <append>true</append>
        <!-- encoders are assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->

        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="DAYFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logFile.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

            <!-- keep 30 days' worth of history capped at 3GB total size -->
            <maxHistory>30</maxHistory>
            <totalSizeCap>3GB</totalSizeCap>

        </rollingPolicy>

        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="DAYFILE"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

详细配置文件,可以参考http://logback.qos.ch/manual/index.html
虽然是英文的,但是写的已经是非常清楚了。

程序调用

同为slf4j的api,代码相同。

 // 类名.class
Logger logger = LoggerFactory.getLogger(Program.class);
// 输出字符串
logger.debug("this is a debug msg");
// 占位符
logger.debug("hi,welcome {},today is {}","admin","Sunday");

参考文献

  • http://www.slf4j.org/manual.html

  • http://logging.apache.org/log4j/1.2/manual.html

  • http://www.importnew.com/7450.html

  • http://logback.qos.ch/manual/index.html



关注猪猪


以上是关于详解slf4j log4j logback log4j2的主要内容,如果未能解决你的问题,请参考以下文章

详解slf4j log4j logback log4j2

log4j的详解

logback最佳实践

logback介绍和配置详解

从 log4j 迁移到 logback

slf4j log4j logback