Java 杂谈Java学习笔记

logback 详解

2019-05-30  本文已影响0人  hxy__

简介

Java 日志框架众多——常用的有 java.util.logginglog4jlogbackcommons-logginglogback 是 Log4j 框架的作者开发的新一代日志框架,它效率更高、能够适应诸多的运行环境,同时天然支持 SLF4J。默认情况下,Spring Boot 默认使用logback 来记录日志,并用 INFO 级别输出到控制台。新建一个 Spring Boot 项目在不配置的情况下,已经可以看到许 INFO 级别的日志输出到控制台了。

springboot 启动日志

从上图可以看到,日志输出内容元素具体如下:

默认属性配置支持

Spring Boot 为我们提供了很多默认的日志配置,所以,只要将 spring-boot-starter-logging 作为依赖加入到当前应用的classpath,则“开箱即用”。下面介绍几种在 application.properties 就可以配置的日志相关属性。

控制台输出

日志级别从低到高分为 TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为 WARN,则低于 WARN 的信息都不会输出。

Spring Boot 中默认配置 ERRORWARNINFO 级别的日志输出到控制台。您还可以通过启动您的应用程序 –debug 标志来启用“调试”模式(开发的时候推荐开启),以下两种方式皆可:

文件输出

默认情况下,Spring Boot 将日志输出到控制台,不会写到日志文件。如果要编写除控制台输出之外的日志文件,则需在 application.properties 中设置 logging.file 或 logging.path 属性。

如果只配置 logging.file,会在项目的当前路径下生成一个 xxx.log 日志文件。
如果只配置 logging.path,在 /var/log 文件夹生成一个日志文件为 spring.log

注:二者不能同时使用,如若同时使用,则只有logging.file生效

*默认情况下,日志文件的大小达到 10 MB 时会切分一次,产生新的日志文件,默认级别为:ERROR、WARN、INFO

级别控制

所有支持的日志记录系统都可以在 Spring 环境中设置记录级别(例如在 application.properties 中)格式为:logging.level.* = LEVEL

举例:

自定义日志配置

由于日志服务一般都在 ApplicationContext 创建前就初始化了,它并不是必须通过 Spring 的配置文件控制。因此通过系统属性和传统的 Spring Boot 外部配置文件依然可以很好的支持日志控制和管理。

根据不同的日志系统,你可以按如下规则组织配置文件名,就能被正确加载:

Spring Boot 官方推荐优先使用带有 -spring 的文件名作为你的日志配置(如使用 logback-spring.xml,而不是logback.xml),命名为 logback-spring.xml 的日志配置文件,spring boot 可以为它添加一些 spring boot 特有的配置项。**

上面是默认的命名规则,并且放在 src/main/resources 下面即可。

虽然有默认的命名规则,但是如果你想针对不同运行环境使用不同的日志配置文件,也可以通过 loggin.config 来指定 logback 的配置文件名:

logging.config: classpath:loggin-confi.xml

配置文件详解

下面以一个简单的 logback.xml 例子来讲解 logback 的各个配置的作用:

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>logback</contextName>
    <property name="log.path" value="E:\\test\\logback.log" />
    <!--输出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
       <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>-->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--输出到文件-->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logback.%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="file" />
    </root>

    <!-- logback为java中的包 -->
    <logger name="com.dudu.controller"/>
    <!--logback.LogbackDemo:类的全路径 -->
    <logger name="com.dudu.controller.LearnController" level="WARN" additivity="false">
        <appender-ref ref="console"/>
    </logger>
</configuration>
image.gif

configuration

appender

appender 用来格式化日志输出节点,有俩个属性 name 和 class,class 用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略。

encoder

encoder 表示对日志进行编码

ThresholdFilter 为系统定义的拦截器,例如我们用 ThresholdFilter 来过滤掉 ERROR 级别以下的日志不输出到文件中。如果不用记得注释掉,不然你控制台会发现没日志~

contextName

每个 logger 都关联到 logger 上下文,默认上下文名称为 default。但可以使用设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改,可以通过 %contextName 来打印日志上下文名称。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <contextName>TestProject</contextName>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--%contextName的值为"TestProject"-->
            <pattern>%contextName%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>
            <charset>utf8</charset>
        </encoder>
        <!--日志输出级别-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>
    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

property

用来定义变量值的标签, 有两个属性,name 和 value;其中 name 的值是变量的名称,value 的值时变量定义的值。通过定义的值会被插入到 logger 上下文中。定义变量后,可以使 ${} 来使用变量。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n" />

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--引用property的值-->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!--日志输出级别-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>
    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>
image.gif

rollingPolicy

<fileNamePattern>logback.%d{yyyy-MM-dd}.log</fileNamePattern> 定义了日志的切分方式——把每一天的日志归档到一个文件中,<maxHistory>30</maxHistory> 表示只保留最近30天的日志,以防止日志填满整个磁盘空间。同理,可以使用 %d{yyyy-MM-dd_HH-mm} 来定义精确到分的日志切分方式。<totalSizeCap>1GB</totalSizeCap> 用来指定日志文件的上限大小,例如设置为 1GB 的话,那么到了这个值,就会删除旧的日志。如果想保留旧日志,可以使用 TimeBasedRollingPolicy 策略,后面会用到。

root

root 节点是必选节点,用来指定最基础的日志输出级别,只有一个 level 属性。

logger

<loger> 用来设置某一个包或者具体的某一个类的日志打印级别、以及指定 <appender><loger> 仅有一个 name 属性,一个可选的 level 和一个可选的 addtivity 属性。

多环境日志输出

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

<!-- 测试环境+开发环境. 多个使用逗号隔开. -->
<springProfile name="test,dev">
    <logger name="com.dudu.controller" level="info" />
</springProfile>
<!-- 生产环境. -->
<springProfile name="prod">
    <logger name="com.dudu.controller" level="ERROR" />
</springProfile>
image.gif

可以在 yml 或 properties 文件中指定 profile,也可以启动服务的时候指定 profile (如不指定使用默认),如指定 prod 的方式为:
java -jar xxx.jar –spring.profiles.active=prod

指定日志颜色

用过 spring boot 的人都知道,spring boot 启动的时候的日志输出是有颜色的。这是由于 spring boot 默认的 logback 配置了日志的输出颜色。logback 提供了很多默认的颜色(black,red,green 等),如果想将日志设置成对应的颜色,只需将输出内容放到 %颜色名() 括号中就可以了,如:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--时间的输入颜色为红色-->
    <property name="CONSOLE_LOG_PATTERN" value="%red(%d{yyyy-MM-dd HH:mm:ss}) [%class:%line] - %m%n" />

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--引用 property 的值-->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!--日志输出级别-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>
    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>
image.gif

更多的颜色可以到 logback 中查看:https://logback.qos.ch/manual/layouts.html#coloring

完整配置示例

最后贴出一个我认为比较好的配置,大家只需要把该文件命名为 logback-spring.xml 然后放到 spring boot 工成的 resources 目录下就能用啦(因为做了多环境配置,记得指定 spring.profile.active 属性哦~)。该日志采用了与 spring boot 默认的配置一样的颜色搭配,info 为绿色,warn 为黄色,error 为红色。而且日志按天跟大小分割存放到指定目录下。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <contextName>HuangXiaoyu</contextName>
    <property name="log.home" value="F:\\logs"/>

    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 (INFO:绿色  WARN:黄色  ERROR:红色)-->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%5p) %magenta(${PID:- }) --- [%15.15thread] %cyan(%-40.40logger{39}) : %m%n"/>
    <!-- Console 输出设置 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
        <!--日志输出级别-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>

    <springProfile name="prod">
        <!-- 文件保存日志的相关配置 ERROR -->
        <appender name="ERROR-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 保存日志文件的路径 -->
            <file>${log.home}/error.log</file>
            <!-- 日志格式 -->
            <encoder>
                <pattern>%d{HH:mm:ss} [%class:%line] : %m%n</pattern>
            </encoder>
            <!-- 日志级别过滤器 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!-- 过滤的级别 -->
                <level>ERROR</level>
                <!-- 匹配时的操作:接收(记录) -->
                <onMatch>ACCEPT</onMatch>
                <!-- 不匹配时的操作:拒绝(不记录) -->
                <onMismatch>DENY</onMismatch>
            </filter>
            <!-- 循环政策:基于时间创建日志文件 -->
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <!-- 日志文件名格式 -->
                <fileNamePattern>${log.home}/error/%d{yyyy-MM-dd}-error.%i.log</fileNamePattern>
                <!-- 最大保存时间:30天-->
                <maxHistory>30</maxHistory>
                <maxFileSize>10MB</maxFileSize>
            </rollingPolicy>
        </appender>

        <!-- 文件保存日志的相关配置 INFO,按时间跟大小进行分割 -->
        <appender name="INFO-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 保存日志文件的路径 -->
            <file>${log.home}/info.log</file>
            <!-- 日志格式 -->
            <encoder>
                <pattern>%d{HH:mm:ss} [%class:%line] : %m%n</pattern>
            </encoder>
            <!-- 日志级别过滤器 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!-- 过滤的级别 -->
                <level>INFO</level>
            </filter>
            <!-- 循环政策:基于时间创建日志文件 -->
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <!-- 日志文件名格式 -->
                <fileNamePattern>${log.home}/info/%d{yyyy-MM-dd}-info.%i.log</fileNamePattern>
                <!-- 最大保存时间:30天-->
                <maxHistory>30</maxHistory>
                <maxFileSize>10MB</maxFileSize>
            </rollingPolicy>
        </appender>
    </springProfile>

    <!-- 基于info处理日志:具体控制台或者文件对日志级别的处理还要看所在appender配置的filter,如果没有配置filter,则使用root配置 -->
    <springProfile name="prod">
        <root level="info">
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="INFO-OUT"/>
            <appender-ref ref="ERROR-OUT"/>
        </root>
    </springProfile>

    <springProfile name="dev,test">
        <!-- 输出mybatis的sql语句,没有这句就无法输出mybatis的sql语句,name属性指定到要输出日志的dao,即mybatis要代理的dao -->
        <logger name="com.huang.mmall.dao" level="DEBUG"/>

        <root level="info">
            <appender-ref ref="STDOUT"/>
        </root>
    </springProfile>

</configuration>
image.gif

感谢:http://tengj.top/2017/04/05/springboot7/

上一篇 下一篇

猜你喜欢

热点阅读