日志

日志

一 、 引言

1.1 日志概念

 在计算机领域,日志文件(logfile)是一个记录了发生在运行中的操作系统或其他软件中的事件的文件,或者记录了在网络聊天软件的用户之间发送的消息。

1.2 日志作用

	日志是个很重要的东西, 因为程序运行起来以后, 基本上就是一个黑盒子,如果程序的行为和预料的不一致,那就是出现Bug了,如何去定位这个Bug 呢?开发人员能用的工具只有两个。第一种就是单步调试,一步步地跟踪,查看代码中变量的值, 这种办法费时费力, 并且只能在程序员的机器上才能用。第二种就是在特定的地方打印日志, 通过日志的输出,帮助快速定位。

  日志记录了系统行为的时间、地点、状态等相关信息,能够帮助我们了解并监控系统状态,在发生错误或者接近某种危险状态时能够及时提醒我们处理,同时在系统产生问题时,能够帮助我们快速的定位、诊断并解决问题。 

二 、日志信息级别

  日志的级别有很多,不同的日志框架支持的级别不一样,这里就以log4j为例,说说log4j中支持的日志级别。log4j定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。 

ALL 最低等级的,用于打开所有日志记录。

TRACE 很低的日志级别,一般不会使用。

DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。

INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。

WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。

ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。

FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。

OFF 最高等级的,用于关闭所有日志记录。

大部分日志框架都支持ERROR,WARN,INFO,DEBUG级别,这四种级别也是开发中最常用的。

三、日志发展历程

3.1 System.out和System.err

这是最早的日志记录方式,但是不灵活也不可配置,要么就是全部打印,要么就是全部不打印,没有一个统一的日志级别 

3.2 Log4j

Ceki Gülcü (Lo4j的主要贡献者)于2001年发布了Log4j,后来成为Apache 基金会的顶级项目。Log4j 在设计上非常优秀,对后续的 Java Log 框架有长久而深远的影响,它定义的Logger、Appender、Level等概念如今已经被广泛使用。Log4j 的短板在于性能,在Logback 和 Log4j2 出来之后,Log4j的使用也减少了。

3.3 JUL

受Logj启发,Sun在Java1.4版本中引入了java.util.logging,但是j.u.l功能远不如log4j完善,开发者需要自己编写Appenders(Sun称之为Handlers),且只有两个Handlers可用(Console和File),j.u.l在Java1.5以后性能和可用性才有所提升。

3.4 JCL

由于项目的日志打印必然选择两个框架中至少一个,这时候,Apache的JCL(commons-logging)诞生了。JCL 是一个Log Facade,只提供 Log API,不提供实现,然后有 Adapter 来使用 Log4j 或者 JUL 作为Log Implementation。在程序中日志创建和记录都是用JCL中的接口,在真正运行时,会看当前ClassPath中有什么实现,如果有Log4j 就是用 Log4j, 如果啥都没有就是用 JDK 的 JUL。 

JCL结构图

在这里插入图片描述

不过,commons-logging对Log4j和j.u.l的配置问题兼容的并不好,使用commons-loggings还可能会遇到类加载问题,导致NoClassDefFoundError的错误出现。 

3.5 Slf4j

Ceki Gülcü(也就是Log4j的作者)由于一些原因离开了Apache,之后觉得JCL不好,于是于2005年自己撸出一个新工程,也就是一套新日志接口(有得也叫日志门面):Slf4j(Simple Logging Facade for Java),感觉粗来了么。。。这战争的硝烟,明显这个Slf4j是直指JCL啊,但是后面确实也证明了Slf4j是要比JCL在很多地方更优秀。

但是由于Slf4j出来的较晚,而且还只是一个日志接口,所以之前已经出现的日志产品,如JCL和Log4j都是没有实现这个接口的,所以尴尬的是光有一个接口,没有实现的产品也是很憋屈啊,就算开发者想用Slf4j也是用不了,这时候Ceki Gülcü想出一个桥接包模式,要让Sun或者Apache这两个庞然大物来实现我的接口。

Slf4j结构图

在这里插入图片描述

提供了桥接包后的结构

slf4j桥接包后的结构图

在这里插入图片描述

官方提供sl4j整合各种日志产品的图

sl4j整合各种日志产品的图
在这里插入图片描述

3.6 Logback

由于使用Slf4j,需要一次桥接包,也就是之前的日志产品都不是正统的Slf4j的实现,因此,2006年,出自Ceki Gülcü之手的日志产品Logback应运而生, logback是完美实现了Slf4j,于是现在日志系统变成了下面这样。

Logback结构图

在这里插入图片描述

Logback是log4j的升级版,当前分为三个目标模块:

  • logback-core:核心模块,是其它两个模块的基础模块
  • logback-classic:是log4j的一个改良版本,同时完整实现 SLF4J API 使你可以很方便地更换成其它日记系统如log4j 或 JDK14 Logging
  • logback-access:访问模块与Servlet容器集成提供通过Http来访问日记的功能,是logback不可或缺的组成部分

Logback相较于log4j有更多的优点:

  • 更快的执行速度

  • 更充分的测试

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

  • 使用XML配置文件或者Groovy

  • 自动重新载入配置文件

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

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

  • 自动压缩归档日志文件

  • 谨慎模式

  • Lilith

  • 配置文件中的条件处理

  • 更丰富的过滤

    ok了,现在咱们有了2个日志接口,3个日志产品,大家也都看起来相安无事。。。但。。。Slf4j+Logback的模式,显然很冲击JCL+Log4j,并且本身Logback确实比Log4j性能更优,设计更为合理,所以。。。老东家Apache可就坐不住了。

3.7 log4j2

现在有了更好的 SLF4J 和 Logback,慢慢取代JCL 和 Log4j ,事情到这里总该大统一圆满结束了吧。然而维护 Log4j 的人不这样想,他们不想坐视用户一点点被 SLF4J / Logback 蚕食,继而搞出了 Log4j2。

3.8 小结

常见的Java日志框架

  • log4j
  • logback
  • j.u.l (java.util.logging)

常见的Java日志门面

  • SLF4J
  • commons-logging

四、JCL+log4j

4.1 上手案例

4.1.1 添加依赖
    <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <!-- JCL依赖 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- log4j依赖 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
4.1.2 配置文件

在classpath下面新建属性文件log4j.properties,内容如下。

 ### 指定日志输出级别 ###  
log4j.rootLogger = debug,stdout
  
### 指定输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender

### 指定使用流的方式输出 ###
log4j.appender.stdout.Target=System.out

### 指定日志输出布局 ###
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

### 指定日志编码 ###
log4j.appender.stdout.Encoding=UTF-8

### 指定日志格式 ###
log4j.appender.stdout.layout.ConversionPattern= %d{yyy-MM-dd HH\:mm\:ss} %p %c {0}\: %L - %m%n

ConversionPattern 参数值说明

-X号: X信息输出时左对齐;

%p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,

%d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921

%r: 输出自应用启动到输出该log信息耗费的毫秒数

%c: 输出日志信息所属的类目,通常就是所在类的全名

%t: 输出产生该日志事件的线程名

%l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main (TestLog4.java:10)

%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。

%%: 输出一个"%"字符

%F: 输出日志消息产生时所在的文件名称

%L: 输出代码中的行号

%m: 输出代码中指定的消息,产生的日志具体信息

%n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行

4.1.3 API测试
public class Log4jTest {

    // 1.创建日志对象
    private static Log log = LogFactory.getLog(Log4jTest.class);

    @Test
    public void testLog(){

        // 2.调用不同的级别输出日志
        log.debug("这是debug级别");
        log.info("这是info级别");
        log.warn("这是warn级别");
        log.error("这是error级别");
    }
}
4.1.4 运行结果

运行结果

在这里插入图片描述

4.2 Appender 参数值

 Log4j日志系统还提供许多强大的功能,比如允许把日志输出到不同的地方,如控制台(Console)、文件(Files)等,可以根据天数或者文件大小产生新的文件,可以以流的形式发送到其它地方等等。

常使用的类如下:

类名说明
org.apache.log4j.ConsoleAppender日志输出控制台
org.apache.log4j.FileAppender日志输出到文件
org.apache.log4j.DailyRollingFileAppender每天产生一个日志文件
org.apache.log4j.RollingFileAppender文件大小到达指定尺寸的时候产生一个新的文件
org.apache.log4j.net.SMTPAppender将日志以已邮件的形式发送出去

4.3 Layout 参数值

 有时用户希望根据自己的喜好格式化自己的日志输出,Log4j可以在Appenders的后面附加Layouts来完成这个功能。Layouts提供四种日志输出样式,如根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式。 

常使用的类如下:

类名说明
org.apache.log4j.HTMLLayout以HTML表格形式布局
org.apache.log4j.PatternLayout可以灵活地指定布局模式
org.apache.log4j.SimpleLayout包含日志信息的级别和信息字符串
org.apache.log4j.TTCCLayout含日志产生的时间、线程、类别等信息

4.4日志输出到控制台

 ### #配置根Logger ###
log4j.rootLogger = debug,stdout

### 指定输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender

### 指定使用流的方式输出 ###
log4j.appender.stdout.Target=System.out

### 指定日志输出布局 ###
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

### 指定日志编码 ###
log4j.appender.stdout.Encoding=UTF-8

运行结果
在这里插入图片描述

4.5日志输出到文件

log4j.rootLogger = debug,E

##输出到日志文件
log4j.appender.E= org.apache.log4j.FileAppender

# 日志输出位置
log4j.appender.E.File = ./log/log.log

# 日志是否追加
log4j.appender.E.Append = true
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

运行结果

在这里插入图片描述

4.6 每天一个日志文件

log4j.rootLogger = debug,E
##每天一个日志文件
log4j.appender.E= org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = ./log/log.log
log4j.appender.E.Append = true
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

运行结果

在这里插入图片描述

4.7 按照文件大小产生文件

log4j.rootLogger = debug,E

# 文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.E= org.apache.log4j.RollingFileAppender

log4j.appender.E.File = ./log/log.log
log4j.appender.E.Append = true
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

# 当文件大小超过256KB时,新创建一个文件接收日志
log4j.appender.E.MaxFileSize=2KB

## 保存10个备份文件。
log4j.appender.E.MaxBackupIndex=10

运行结果

在这里插入图片描述

4.8 邮件发送日志

因为这里需要发送邮件,所以我们需要添加邮件相关的依赖包

  		<dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
        </dependency>

log4j.rootLogger = debug,MAIL

#自定义的Appender为邮件发送
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender

# 发送邮件的日志级别
log4j.appender.MAIL.Threshold=ERROR

#缓存文件大小,日志达到512K时发送Email
log4j.appender.MAIL.BufferSize=512

#发件人
log4j.appender.MAIL.From=13480743727@163.com

#发送邮件的服务器
log4j.appender.MAIL.SMTPHost=smtp.163.com

#发送邮件箱的用户
log4j.appender.MAIL.SMTPUsername=13480743727@163.com

#发送邮件箱的密码
log4j.appender.MAIL.SMTPPassword=dsx123456

#邮件的标题,log4j默认的读取是iso-8859-1,所以这里直接写中文会出现乱码情况
# 如果标题有中文用native2asii转换一下编码方式
log4j.appender.MAIL.Subject=\u65e5\u5fd7\u544a\u8b66\uff0c\u7cfb\u7edf\u51fa\u73b0\u9519\u8bef

# 收件人里面写上自己,否则会被163认为是垃圾邮件,导致发送失败。
log4j.appender.MAIL.To=854569279@qq.com,13480743727@163.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

4.9 Log4j XML配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

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

        <!--过滤器设置输出的级别-->
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <!-- 设置日志输出的最小级别 -->
            <param name="levelMin" value="INFO"/>
            <!-- 设置日志输出的最大级别 -->
            <param name="levelMax" value="ERROR"/>
        </filter>
    </appender>


    <!-- 输出日志到文件 -->
    <appender name="fileAppender" class="org.apache.log4j.FileAppender">
        <!-- 输出文件全路径名-->
        <param name="File" value="./log/log.log"/>
        <!--是否在已存在的文件追加写:默认时true,若为false则每次启动都会删除并重新新建文件-->
        <param name="Append" value="true"/>

        <param name="Threshold" value="INFO"/>
        <!--是否启用缓存,默认false-->
        <param name="BufferedIO" value="false"/>
        <!--缓存大小,依赖上一个参数(bufferedIO), 默认缓存大小8K  -->
        <param name="BufferSize" value="512"/>
        <!-- 日志输出格式 -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%p][%d{yyyy-MM-dd HH:mm:ss SSS}][%c]-[%m]%n"/>
        </layout>
    </appender>


    <!-- 输出日志到文件,当文件大小达到一定阈值时,自动备份 -->
    <appender name="rollingAppender" class="org.apache.log4j.RollingFileAppender">
        <!-- 日志文件全路径名 -->
        <param name="File" value="./log/log.log" />
        <!--是否在已存在的文件追加写:默认时true,若为false则每次启动都会删除并重新新建文件-->
        <param name="Append" value="true" />
        <!-- 保存备份日志的最大个数,默认值是:1  -->
        <param name="MaxBackupIndex" value="10" />
        <!-- 设置当日志文件达到此阈值的时候自动回滚,单位可以是KB,MB,GB,默认单位是KB,默认值是:10MB -->
        <param name="MaxFileSize" value="1KB" />
        <!-- 设置日志输出的样式 -->
        <layout class="org.apache.log4j.PatternLayout">
            <!-- 日志输出格式 -->
            <param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%-5p] [method:%l]%n%m%n%n" />
        </layout>
    </appender>

    <!-- 日志输出到文件,每天一个日志文件  -->
    <appender name="dailyRollingAppender" class="org.apache.log4j.DailyRollingFileAppender">
        <!-- 文件文件全路径名 -->
        <param name="File" value="./log/log.log"/>
        <param name="Append" value="true" />
        <!-- 设置日志备份频率,默认:为每天一个日志文件 -->
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />

        <!--每分钟一个备份-->
        <!--<param name="DatePattern" value="'.'yyyy-MM-dd-HH-mm'.log'" />-->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%p][%d{HH:mm:ss SSS}][%c]-[%m]%n"/>
        </layout>
    </appender>

    <!-- 发邮件(只有ERROR时才会发送!) -->
    <appender name="MAIL"  class="org.apache.log4j.net.SMTPAppender">
        <!-- 日志的错误级别 -->
        <param name="threshold" value="error" />
        <!-- 缓存文件大小,日志达到512K时发送Email -->
        <param name="BufferSize" value="512" /><!-- 单位K -->
        <param name="From" value="13480743727@163.com" />
        <param name="SMTPHost" value="smtp.163.com" />
        <param name="Subject" value="juyee-log4jMessage" />
        <param name="To" value="854569279@qq.com,13480743727@163.com" />
        <param name="SMTPUsername" value="13480743727@163.com" />
        <param name="SMTPPassword" value="dsx123456" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [%p]-[%c] %m%n" />
        </layout>
    </appender>

    <!--
        单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等
        name:包名
        additivity:是否继承root配置
    -->
    <logger name="com.qf.test.log4j"  additivity="false">
        <!--这个级别是对console的二次过滤 -->
        <level value ="error"/>
        <appender-ref ref="console"/>
    </logger>

    <!-- 根logger的设置,若代码中未找到指定的logger,则会根据继承机制,使用根logger-->
    <root>
        <appender-ref ref="console"/>
        <appender-ref ref="fileAppender"/>
        <appender-ref ref="rollingAppender"/>
        <appender-ref ref="dailyRollingAppender"/>
        <appender-ref ref="MAIL"/>
    </root>

</log4j:configuration>

五、SL4J+logback

5.1 上手案例

5.1.1 添加依赖
    <properties>
        <slf4j-api.version>1.6.4</slf4j-api.version>
        <logback-classic.version>0.9.28</logback-classic.version>
        <jcl-over-slf4j.version>1.6.4</jcl-over-slf4j.version>
    </properties>

    <dependencies>
        
        <!-- 日志框架API -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j-api.version}</version>
        </dependency>
        
        <!-- 日志实现提供者 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback-classic.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
            <scope>runtime</scope>
        </dependency>
        
        <!-- 拦截 apache commons logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${jcl-over-slf4j.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

    </dependencies>
5.1.2 配置文件

在classpath下面新建Logback.xml文件,内容如下。

<?xml version="1.0" encoding="UTF-8"?>
<!--

scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。

scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,
默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。

debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。
默认值为false。
-->
<configuration scan="false" scanPeriod="60 seconds" debug="false">

    <!-- 应用名称 -->
    <property name="APP_NAME" value="log-demo" />

    <!--日志文件的保存路径,首先查找系统属性-Dlog.dir,如果存在就使用其;否则,
    在当前目录下创建名为logs目录做日志存放的目录 -->
    <property name="LOG_HOME" value="D:/code/ideaworkspace3/log-demo/log" />

    <!-- 日志输出格式 -->
    <property name="ENCODER_PATTERN"
              value="%d{yyyy-MM-dd  HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n" />

    <contextName>${APP_NAME}</contextName>

    <!-- 控制台日志:输出全部日志到控制台 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>${ENCODER_PATTERN}</Pattern>
        </encoder>
    </appender>

    <!-- 文件日志:输出全部日志到文件 -->
    <appender name="file"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <Ecndoing>UTF_8</Ecndoing>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/output1.%d{yyyy-MM-dd}.log</fileNamePattern>
          <!-- 日志保留时间 7天-->
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>

    </appender>

    <!-- 错误日志:用于将错误日志输出到独立文件 -->
    <appender name="error_file"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>error</level>
        </filter>
    </appender>


    <!-- 指定包下的class指定不同的日志级别等-->
    <logger name="com.qf.sl4j.test.Sl4jTest" level="info" >
        <appender-ref ref="console" />
    </logger>

    <root>
        <level value="debug" />
        <appender-ref ref="console" />
        <appender-ref ref="file" />
        <appender-ref ref="error_file" />
    </root>
</configuration>
5.1.3 API测试
package com.qf.sl4j.test;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Sl4jTest {

    private final static Logger log = LoggerFactory.getLogger(Sl4jTest.class);

    @Test
    public void testSl4j(){
        log.debug("这是debug级别");
        log.info("这是info级别");
        log.warn("这是warn级别");
        log.error("这是错误级别1");
    }
}

5.1.4 运行结果

运行结果

在这里插入图片描述

  • 18
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值