springboot的日志框架slf4j (使用logback输出日志以及使用)

Posted 小虾米的java梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot的日志框架slf4j (使用logback输出日志以及使用)相关的知识,希望对你有一定的参考价值。

1、为什么使用logback?

       ——在开发中不建议使用System.out因为大量的使用会增加资源的消耗。因为使用System.out是在当前线程执行的,写入文件也是写入完毕之后才继续执行下面的程序。而使用Log工具不但可以控制日志是否输出,怎么输出,它的处理机制也是通知写日志,继续执行后面的代码不必等日志写完。

       ——个人推荐使用SLF4J(Simple Logging Façade For Java)的logback来输出日志,其比log4j效率高。

    ——Spring Boot 提供了一套日志系统,logback是最优先的选择。

2、logback,slf4j,log4j之间的关系

  Slf4j是The Simple Logging Facade for Java的简称,是一个简单日志门面抽象框架,它本身只提供了日志Facade API和一个简单的日志类实现,一般常配合Log4j,LogBack,java.util.logging使用。Slf4j作为应用层的Log接入时,程序可以根据实际应用场景动态调整底层的日志实现框架(Log4j/LogBack/JdkLog...)

LogBack和Log4j都是开源日记工具库,LogBack是Log4j的改良版本,比Log4j拥有更多的特性,同时也带来很大性能提升。

3、Logback的结构

LogBack被分为3个组件,logback-core, logback-classic 和 logback-access.

其中logback-core提供了LogBack的核心功能,是另外两个组件的基础。

logback-classic则实现了Slf4j的API,所以当想配合Slf4j使用时,需要将logback-classic加入classpath。

logback-access是为了集成Servlet环境而准备的,可提供HTTP-access的日志接口;

spring-boot默认支持logback,所以无需引用任何以来只需要,配置application.properties即可,如果要功能丰富些,则配置下logback.xml

4、为什么Spring Boot推荐使用logback-spring.xml来替代logback.xml来配置logback日志的问题分析

 

即,logback.xml加载早于application.properties,所以如果你在logback.xml使用了变量时,而恰好这个变量是写在application.properties时,那么就会获取不到,只要改成logback-spring.xml就可以解决。

5、具体的配置

在application.yml中的配置:

 

在logback-spring.xml中的配置;
多环境的配置:

 

多环境日志输出

根据不同环境(prod:生产环境,test:测试环境,dev:开发环境)来定义不同的日志输出,在 logback-spring.xml 中使用 springProfile 节点来定义,方法如下:

 

【注意文件名称不是logback.xml,想使用spring扩展profile支持,要以logback-spring.xml命名】

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <logger name="org.springframework.web" level="INFO"/>
    <logger name="org.springboot.sample" level="TRACE" />
   
    <!-- 测试环境+开发环境. 多个使用逗号隔开. -->
     <springProfile name="test,dev">
        <logger name="org.springframework.web" level="INFO"/>
        <logger name="org.springboot.sample" level="INFO" />
        <logger name="com.kfit" level="info" />
    </springProfile>
 
   
    <!-- 生产环境. -->
    <springProfile name="prod">
        <logger name="org.springframework.web" level="ERROR"/>
        <logger name="org.springboot.sample" level="ERROR" />
        <logger name="com.kfit" level="ERROR" />
    </springProfile>
   
</configuration>
 

 

  6、日志的级别

默认输出该等级之上的日志,顺序是由高到底,ERROR--WARN--INFO--DEBUG--TRACE

@RunWith就是一个运行器

@RunWith(JUnit4.class)就是指用JUnit4来运行

@RunWith(SpringJUnit4ClassRunner.class),让测试运行于Spring测试环境

@RunWith(Suite.class)的话就是一套测试集合,

@RunWith 翻译成中文就是 测试运行器,JUnit所有的测试方法都是由测试运行器负责执行。

JUnit为单元测试提供了一个默认的测试运行器BlockJUnit4ClassRunner,但是没有限制必须使用默认的运行器。

我们常用的有参数运行器

@RunWith(Suit.Class)

@SuitClasses(MyTest.Class,MyTest2.Class)

这个是打包测试功能,多个class 可以一起执行测试,不需要一个一个执行,这样节省时间,提高效率

@RunWith(Parameteried.Class)

模拟不同的参数方法进行测试,如果为每个类型参数创建一个方法,那是很耗时,傻瓜式的。

@RunWith(SpringJUnit4ClassRunner.class)

这个是用springmvc的容器

@RunWith(Parameterized.class)

  

 

 

 

 

7、在java类中如何使用呢,springboot是约定大于配置,所以我们使用注解的方式来配置

在日志中输出变量的方式:

8、logback-spring.xml的具体的配置我们可以参考如下博客

https://blog.csdn.net/qianyiyiding/article/details/76565810

http://412887952-qq-com.iteye.com/blog/2307244

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="LOG_NAME" value="/home"></property>
    <!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,,,, -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--<pattern>%d %p (%file:%line\\)- %m%n</pattern>-->
            <!--格式化输出:%d:表示日期    %thread:表示线程名     %-5level:级别从左显示5个字符宽度  %msg:日志消息    %n:是换行符-->
            <pattern>1-%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
            <charset>GBK</charset>
        </encoder>
    </appender>
    <!--<include resource="org/springframework/boot/logging/logback/base.xml"/>-->
    <contextName>RestAPI</contextName>
    <property name="LOG_PATH" value=".logs"/>
    <!--设置系统日志目录-->
    <property name="APPDIR" value="app"/>
    <!--
          说明:
          1、日志级别及文件
              日志记录采用分级记录,级别与日志文件名相对应,不同级别的日志信息记录到不同的日志文件中
              例如:error级别记录到log_error_xxx.log或log_error.log(该文件为当前记录的日志文件),而log_error_xxx.log为归档日志,
              日志文件按日期记录,同一天内,若日志文件大小等于或大于2M,则按0、1、2...顺序分别命名
              例如log-level-2013-12-21.0.log
              其它级别的日志也是如此。
          2、文件路径
              若开发、测试用,在Eclipse中运行项目,则到Eclipse的安装路径查找logs文件夹,以相对路径../logs。
              若部署到Tomcat下,则在Tomcat下的logs文件中
          3、Appender
              FILEERROR对应error级别,文件名以log-error-xxx.log形式命名
              FILEWARN对应warn级别,文件名以log-warn-xxx.log形式命名
              FILEINFO对应info级别,文件名以log-info-xxx.log形式命名
              FILEDEBUG对应debug级别,文件名以log-debug-xxx.log形式命名
              CONSOLE将日志信息输出到控制上,为方便开发测试使用
       -->
    <!-- 日志记录器,日期滚动记录 -->
    <appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${LOG_PATH}/${APPDIR}/log_error.log</file>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
            而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
            <fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
            命名日志文件,例如log-error-2013-12-21.0.log -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>2MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 追加方式记录日志 -->
        <append>true</append>
        <!-- 日志文件的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 日志记录器,日期滚动记录 -->
    <appender name="FILEWARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${LOG_PATH}/${APPDIR}/log_warn.log</file>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
            而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
            <fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
            命名日志文件,例如log-error-2013-12-21.0.log -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>2MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 追加方式记录日志 -->
        <append>true</append>
        <!-- 日志文件的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 日志记录器,日期滚动记录 -->
    <appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${LOG_PATH}/${APPDIR}/log_info.log</file>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
            而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
            <fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
            命名日志文件,例如log-error-2013-12-21.0.log -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>2MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 追加方式记录日志 -->
        <append>true</append>
        <!-- 日志文件的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--日志异步到数据库  -->
    <!--<appender name="DBAPPENDER" class="ch.qos.logback.classic.db.DBAppender">-->
    <!--<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">-->
    <!--<dataSource class="com.zaxxer.hikari.HikariDataSource">-->
    <!--<driverClassName>com.mysql.jdbc.Driver</driverClassName>-->
    <!--<jdbcUrl>jdbc:mysql://localhost:3306/albedo-new?useUnicode=true&characterEncoding=utf8&useSSL=false</jdbcUrl>-->
    <!--<username>root</username>-->
    <!--<password>123456</password>-->
    <!--<poolName>HikariPool-logback</poolName>-->
    <!--</dataSource>-->
    <!--</connectionSource>-->
    <!--<!– 此日志文件只记录info级别的 –>-->
    <!--<filter class="ch.qos.logback.classic.filter.LevelFilter">-->
    <!--<level>warn</level>-->
    <!--<onMatch>ACCEPT</onMatch>-->
    <!--<onMismatch>DENY</onMismatch>-->
    <!--</filter>-->
    <!--<!– 此日志文件只记录info级别的 –>-->
    <!--<filter class="ch.qos.logback.classic.filter.LevelFilter">-->
    <!--<level>error</level>-->
    <!--<onMatch>ACCEPT</onMatch>-->
    <!--<onMismatch>DENY</onMismatch>-->
    <!--</filter>-->
    <!--</appender>-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
            <!--<charset>GBK</charset>-->
        </encoder>
    </appender>
    <logger name="com.minlia" level="DEBUG"/>
    <logger name="org.springframework.data.mybatis" level="DEBUG"/>
    <logger name="org.springframework.aop.aspectj" level="ERROR"/>

    <logger name="javax.activation" level="WARN"/>
    <logger name="javax.mail" level="WARN"/>
    <logger name="javax.xml.bind" level="WARN"/>
    <logger name="ch.qos.logback" level="INFO"/>
    <logger name="com.codahale.metrics" level="WARN"/>
    <logger name="com.ryantenney" level="WARN"/>
    <logger name="com.sun" level="WARN"/>
    <logger name="com.zaxxer" level="WARN"/>
    <logger name="io.undertow" level="WARN"/>
    <logger name="net.sf.ehcache" level="WARN"/>
    <logger name="org.apache" level="WARN"/>
    <logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/>
    <logger name="org.bson" level="WARN"/>
    <logger name="org.hibernate.validator" level="WARN"/>
    <logger name="org.hibernate" level="WARN"/>
    <logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/>
    <logger name="org.springframework.web" level="INFO"/>
    <logger name="org.springframework.security" level="WARN"/>
    <logger name="org.springframework.cache" level="WARN"/>
    <logger name="org.thymeleaf" level="WARN"/>
    <logger name="org.xnio" level="WARN"/>
    <logger name="springfox" level="WARN"/>
    <logger name="sun.rmi" level="WARN"/>
    <logger name="liquibase" level="WARN"/>
    <logger name="sun.rmi.transport" level="WARN"/>

    <logger name="jdbc.connection" level="ERROR"/>
    <logger name="jdbc.resultset" level="ERROR"/>
    <logger name="jdbc.resultsettable" level="INFO"/>
    <logger name="jdbc.audit" level="ERROR"/>
    <logger name="jdbc.sqltiming" level="ERROR"/>
    <logger name="jdbc.sqlonly" level="INFO"/>

    <!--<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">-->
    <!--<resetJUL>true</resetJUL>-->
    <!--</contextListener>-->

    <springProfile name="production">
        <root level="DEBUG">
            <!--<appender-ref ref="FILEERROR"/>-->
            <!--<appender-ref ref="FILEWARN"/>-->
            <!--<appender-ref ref="FILEINFO"/>-->
            <!--<appender-ref ref="DBAPPENDER"/>-->
            <appender-ref ref="STDOUT"/>

        </root>
    </springProfile>


    <springProfile name="dev">
        <root level="DEBUG">
            <!--<appender-ref ref="FILEERROR"/>-->
            <!--<appender-ref ref="FILEWARN"/>-->
            <!--<appender-ref ref="FILEINFO"/>-->
            <!--<appender-ref ref="DBAPPENDER"/>-->
            <appender-ref ref="CONSOLE"/>

        </root>
    </springProfile>

</configuration>

  

<?xml version="1.0" encoding="UTF-8"?>  
<configuration>      
    <!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,%i索引【从数字0开始递增】,,, -->      
    <!-- appender是configuration的子节点,是负责写日志的组件。 -->  
    <!-- ConsoleAppender:把日志输出到控制台 -->  
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">      
        <encoder>      
            <pattern>%d %p (%file:%line\\)- %m%n</pattern>    
            <!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->  
            <charset>UTF-8</charset>     
        </encoder>      
    </appender>      
    <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->  
    <!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是demo.log -->  
    <!--             2.如果日期没有发生变化,但是当前日志的文件大小超过1KB时,对当前日志进行分割 重命名-->  
    <appender name="demolog" class="ch.qos.logback.core.rolling.RollingFileAppender">      
        <File>log/demo.log</File>      
        <!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->  
        <!-- TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">      
            <!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->  
            <!-- 文件名:log/demo.2017-12-05.0.log -->  
            <fileNamePattern>log/demo.%d.%i.log</fileNamePattern>   
            <!-- 每产生一个日志文件,该日志文件的保存期限为30天 -->   
            <maxHistory>30</maxHistory>     
            <timeBasedFileNamingAndTriggeringPolicy  class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">      
                <!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成1KB看效果 -->    
                <maxFileSize>1KB</maxFileSize>      
            </timeBasedFileNamingAndTriggeringPolicy>      
        </rollingPolicy>      
        <encoder>      
            <!-- pattern节点,用来设置日志的输入格式 -->  
            <pattern>      
                %d %p (%file:%line\\)- %m%n    
            </pattern>      
            <!-- 记录日志的编码:此处设置字符集 - -->  
            <charset>UTF-8</charset>  
        </encoder>      
    </appender>      
    <!-- 控制台输出日志级别 -->  
    <root level="info">      
        <appender-ref ref="STDOUT" />      
    </root>      
    <!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->  
    <!-- com.liyan为根包,也就是只要是发生在这个根包下面的所有日志操作行为的权限都是DEBUG -->  
    <!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE  -->  
    <logger name="com.liyan" level="DEBUG">      
        <appender-ref ref="demolog" />      
    </logger>      
</configuration>  

  关于配置log日志的输出路径的问题:配置一个property,然后filenamePattern添加上去就行了。

 

以上是关于springboot的日志框架slf4j (使用logback输出日志以及使用)的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot使用日志

SpringBoot----日志框架和配置

SpringBoot学习

spring boot怎么配日志

springboot的日志框架slf4j (使用logback输出日志以及使用)

SpringBoot 整合 slf4j 日志打印