springbook日志框架详细配置

SpringBoot 日志详解

一.日志框架介绍

spring boot2.* 使用sl4j+logback的日志框架,其中sl4j是通用的日志门面,我们记录日志的时候,用的是sl4j的方式去记录,底层则是更具你使用的具体日志框架去引用不同的jar包,Spring Boot通过jul-to-slf4j.jar去适配了JUL日志框架,通过log4j-to-slf4j.jar去适配了log4j日志框架,spring适用log4j,logback,jul。Spring Boot2.x相对于Spring Boot1.x来说去除了对JCL的适配。

二.logback 日志配置模板

我们一般是在类路径下建立一个logback.xml,也可命名为(logback-spring.xml , logback-spring.groovy , logback.xml ,logback.groovy)
指定加载的日志文件logback-test.xml

logging:
  config: classpath:logback-test.xml

(ps:springboot只会读取一个logback日志模板,如果是spring-boot-starter中也存在一个日志模板的话,会有冲突.)
日志模板

<?xml version="1.0" encoding="UTF-8"?>
    <!--scan是否开启定时扫描更新配置,scanPeriod定时扫描的时间,debug是否输出logback内部日志-->
<configuration  scan="false" scanPeriod="60 seconds" debug="false">
    <!--上下文名称-->
    <contextName>spring-boot-logging</contextName>
    <!--定义日志保存位置-->
    <property name="log.path" value="../log" />
    <!--输出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 级别过滤 只接受WARN级别的日志其他进行丢弃 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--接受ERROR级别和以上的日志,其他丢弃
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        -->
        <!--
        日志输出格式 %d{HH:mm:ss.SSS} 输出当前时间,格式为12:00:00.00;
        %contextName 输出上下文名称;
        %thread : 输出日志的进程名字,这在Web应用以及异步任务处理中很有用;
        %-5level 输出日志级别,限定5个字符
        %logger{36} 输出日志记录者的名称,一般是类名,字符长度最长36个字符,否则按照句点分割
        %msg 输出日志信息
        %n 换行-->
        <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}/spring-boot-logging.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/spring-boot-logging.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
            <!-- 日志保存周期 30天-->
            <maxHistory>30</maxHistory>
            <!-- 文件大小1GB-->
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--输出到文件 只保存com.xzc.main包下的方法-->
    <appender name="testLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/testLog.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/testLog.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
            <!-- 日志保存周期 -->
            <maxHistory>30</maxHistory>
            <!-- 总大小 -->
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--输出到文件 只保存aop中的日志-->
    <appender name="aopLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/aopLog.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/aopLog.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
            <!-- 日志保存周期 -->
            <maxHistory>30</maxHistory>
            <!-- 总大小 -->
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- logback为java中的包
        name 指定想要记录的类包的名字
        level 指定日志级别
        additivity 是否向上级传递,如果是true的话,那么会在下面appender的中file和console中再打印一次
    -->
    <logger name="com.xzc.main" level="info" additivity="false">
        <appender-ref ref="testLog"/>
    </logger>
    <!-- logback为java中的包 -->
    <logger name="com.xzc.aop" level="info" additivity="false">
        <appender-ref ref="aopLog"/>
    </logger>

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

</configuration>

1.根节点包含的属性

<configuration></configuration>
  • scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true
  • scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟
  • debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false

2.设置上下文名称

<contextName>spring-boot-logging</contextName>

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

3.设置变量

<property name="log.path" value="log" />

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

4.子节点appender

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

控制台输出ConsoleAppender
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <!-- 级别过滤 -->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

filter是一个过滤器,表示对输出到控制台的日记进行过滤。有两种过滤器,分别为LevelFilter 和ThresholdFilter。执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一。返回DENY,日志将立即被抛弃不再经过其他过滤器;返回NEUTRAL,有序列表里的下个过滤器接着处理日志;返回ACCEPT,日志会被立即处理,不再经过剩余过滤器。

其中LevelFilter 为级别过滤器,根据日志级别进行过滤。其下有三个子节点,level表示过滤的级别,用于配置符合过滤条件的操作,ACCEPT符合级别的输出到控制台,用于配置不符合过滤条件的操作,DENY不符合的拒绝输出到控制台。

ThresholdFilter为临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。

表示对日志进行格式化

  • %d{HH:mm:ss.SSS} :日志的输出时间
  • %contextName : 上下文名称
  • %thread : 输出日志的进程名字,这在Web应用以及异步任务处理中很有用
  • %-5level : 日志级别,并且使用5个字符靠左对齐
  • %logger{36} : 日志输出者的名字(一般为类名),名字最长36个字符,否则按照句点分割
  • %msg : 具体的日志消息
  • %n :换行符
输出到文件RollingFileAppender
<!--输出到文件-->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/spring-boot-logging.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/spring-boot-logging.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
            <!-- 日志保存周期 -->
            <maxHistory>30</maxHistory>
            <!-- 总大小 -->
            <totalSizeCap>1GB</totalSizeCap>
            <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
            命名日志文件,例如spring-boot-logging.0.log -->
            <timeBasedFileNamingAndTriggeringPolicy
					class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<maxFileSize>100MB</maxFileSize>
			</timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

常见的日志输出到文件,随着应用的运行时间越来越长,日志也会增长的越来越多,将他们输出到同一个文件并非一个好办法。RollingFileAppender用于切分文件日志。

其中file属性定义文件的带全路径的文件名,重要的是rollingPolicy的定义。

class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"是最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责触发滚动

<fileNamePattern>${log.path}/spring-boot-logging.%d{yyyy-MMdd}.log.zip</fileNamePattern>定义了日志的切分方式——把每一天的日志归档到一个文件中,同理,可以使用%d{yyyy-MM-dd HH-mm}来定义精确到分的日志切分方式。

<maxHistory>30</maxHistory>表示只保留最近30天的日志

<totalSizeCap>1GB</totalSizeCap>用来指定日志文件的上限大小,例如设置为1GB的话,那么到了这个值,就会删除旧的日志
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy>
用来指定日志的大小超过指定,那么就会将日志进行分割,超出大小的一部分重新创建文件,并按0,1的index进行重命名如spring-boot-logging.0.log

5.子节点root
<root level="info">
    <appender-ref ref="console" />
    <appender-ref ref="file" />
</root>

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

其中可以包含零个或多个元素,表示我们定义的appender将会添加到我们定义的loger子节点中。

6.子节点logger

<loger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>

<loger>仅有一个name属性,一个可选的level和一个可选的addtivity属性

  • name:用来指定受此loger约束的某一个包或者具体的某一个类。
  • level:用来设置打印级别,如果未设置此属性,那么当前loger将会继承上级的级别。
  • addtivity:是否向上级loger传递打印信息。默认是true。
    <loger> 的实际使用有两种情况
第一种是不指定level,不指定appender
<root level="info">
    <appender-ref ref="console" />
    <appender-ref ref="file" />
</root>
<logger name="com.baiding.logging.SpringBootLoggingApplicationTests"/>
<!-- logback为java中的包 -->
<logger name="com.xzc.aop" level="info" additivity="false">
    <appender-ref ref="aopLog"/>
</logger>

此logger指定了level为warn,addtivityfalse,不在向上级传递打印信息,若设置了<appender-ref>属性,但没有设置addtivity为false,则com.baiding包下的日志会先在名为console的appender记录一次,之后传递给上级,root又会在名为console和file的appender记录一次,这样就打印了两次了。

Spring Boot在使用logback记录日志时,推荐使用logback-spring.xml的格式,这样的话,日志框架就不直接加载日志的配置项,而是由SpringBoot解析日志配置,就可以使用SpringBoot 的高级Profile功能

如下logback-spring.xml

<springProfile name="dev">
    <logger name="com.baiding" level="info"/>
</springProfile>

<springProfile name="prod">
    <logger name="com.baiding" level="warn"/>
</springProfile>

可以在不同的节点中使用springProfile功能,用于指定某段配置只在某个环境下生效 。当然使用前,要激活profile。

7.扩展

使用<springProperty>标签引用spring配置中的属性

<!-- scope 指定这个属性所在的域,这里context是上下文,
      name 指定引用时的名字,
      source 指定在spring配置文件中的配置名 
      defaultValue 指定默认的名字,在该值为空的时候进行替换-->
<springProperty scope="context" name="logName" source="spring.log.name" defaultValue="springLog"/>
三 Springboot下使用Log4j框架

Spring Boot虽然默认使用Logback日志框架,但其内部也集成了Log4j2框架。

1. 导入框架

首先,要在Spring Boot使用Log4j2的话,那么第一件事就是去除Logback的jar包,并引入Log4j2的jar。

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
    </dependencies>
2 模板内容
<?xml version="1.0" encoding="UTF-8"?>

<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->

<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="INFO" monitorInterval="30">

    <Properties>
        <Property name="log.path">../log</Property>
    </Properties>

    <!--先定义所有的appender-->
    <appenders>
        <!--这个输出控制台的配置-->
        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
        </console>

        <File name="log" fileName="${log.path}/test.log" append="false">
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
        </File>

        <RollingFile name="RollingFileInfo" fileName="${log.path}/info.log"

                     filePattern="${log.path}/logs/${date:yyyy-MM}/info-%d{yyyy-MM-dd}.log.zip">

            <!--只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>

            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p]-[%t] - %l - %m%n"/>

            <Policies>
                <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
            </Policies>

        </RollingFile>
    </appenders>

    <!--然后定义logger,只有定义了logger并引入appender,appender才会生效-->
    <loggers>
        <root level="info">
            <appender-ref ref="Console"/>
        </root>
        <!-- 默认不打印location信息,诸如代码行号,类,方法等。 如果需要的话需要加上includeLocation="true",但是按官方说法会慢30-100倍。-->
        <AsyncLogger name="com.xcz.controller" level="info" additivity="false" includeLocation="true">
            <appender-ref ref="RollingFileInfo"/>
        </AsyncLogger>
        <!--<logger name="com.xcz.controller" level="info" additivity="false" >
            <appender-ref ref="RollingFileInfo"/>
        </logger>-->
    </loggers>

</configuration>


1. 根节点属性

根节点Configuration有两个属性,status和monitorinterval,与logback中的根节点一样,具有相同的功能

  • status : status用来指定log4j2本身的日志的级别
  • monitorinterval : monitorinterval用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s
2.Properties标签

配置属性,在之后的配置中可以使用${}引用

<Properties>
    <Property name="log.path">../log</Property>
</Properties>

3.Appender节点

和logback一样,Appender是用来定义日志输出点的,一般常用有三个子节点,分别为Console、RollingFile、File。下面介绍一下各个子节点的用处及常用的属性

Console节点用来定义输出到控制台的Appender:
  • name : 指定Appender的名字,用于Logger节点引用
  • target : SYSTEM_OUT 或 SYSTEM_ERR,一般设置为:SYSTEM_OUT
  • PatternLayout : 指定日志输出格式,默认为%m%n
        <!--这个输出控制台的配置-->
        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
        </console>
File节点用来定义输出到指定位置的文件的Appender:
  • name : 指定Appender的名字,用于Logger节点引用
  • fileName : 指定输出日志的目的文件带全路径的文件名
  • append : 是否追加,默认为ture。ture是将新日志追加到原日志文件尾部,false则是删除已有文件,重建新文件
  • PatternLayout : 指定日志输出格式,默认为%m%n
RollingFile节点用来定义输出到指定位置的文件的Appender,但其记录的内容可拆分:

File对文件的约束很简单,而RollingFile则比较灵活,其可根据文件大小来分拆,还可以根据时间来分拆

  • name : 指定Appender的名字,用于Logger节点引用
  • fileName : 指定输出日志的目的文件带全路径的文件名
  • filePattern:指定拆分出去的日志文件的全路径的文件名以及格式
  • PatternLayout : 指定日志输出格式,默认为%m%n,输出当前时间%d{yyyy/MM/dd HH:mm:ss,SSS}%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数,%p 显示该条日志的优先级 ,%t 输出产生该日志事件的线程名。更多的格式
  • Policies : 指定滚动日志的策略,就是什么时候进行新建日志文件输出日志.
    基于大小的策略,单位有:KB,MB,GB<SizeBasedTriggeringPolicy size="10 MB"/>
    基于corn表达式的策略 <CronTriggeringPolicy schedule="0/5 * * * * ?" />
    基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。
<Policies>
<!-- 这里有两个参数,其中`interval`指定的是偏移量的大小,这里的偏移量与`filePattern`有关,
日期格式精确到哪一位,interval也精确到哪一个单位。如%d{yyyy-MM-dd HH},最小粒度为小时,
则每一个小时生成一个文件。`modulate`指定是否是以0点为边界进行偏移计算,如modulate为5,
时间粒度为时,上次的封存时间为3时,那么下次封存文件的时间为5时,10时-->
    <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
</Policies>
  • Strategy滚动策略 : <DefaultRolloverStrategy max="10"/>默认滚动策略常用参数:max,保存日志文件的最大个数,默认是7,大于此值会删除旧的日志文件。
  • ThresholdFilter : 日志过滤器,用来过滤掉所有级别低于它定义的级别的日志
    这里说一下TimeBasedTriggeringPolicy这个滚动策略的属性interval,它是指日志进行滚动的间隔,那么它的单位具体是什么呢?关键点在于filePattern的日志文件名所含有的日期格式%d{yyyy-MM-dd},这里日期格式具体到了天,那么以天为单位,若是日期具体到%d{yyyy-MM-dd-HH-mm}分钟的话,那么就是以分钟为单位。

这里还提到了日志过滤器,Log4j提供了许多的日志过滤器,具体可以看下文档 Filters。但我们一般采用ThresholdFilter,这个过滤器一般用来过滤掉所有级别低于它定义的级别的日志。

5.Loggers 节点

Loggers下包含两个节点 rootlogger这里与logback是一致的,root中配置根节点,logger中对指定的包下的日志进行过滤,可以将对应包下的日志单独过滤输出
root节点用来指定项目的根日志,如果没有单独指定logger,那么就会默认使用该root日志输出。

  • level :日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
  • appender-ref :root的子节点,用来指定该日志输出到哪个Appender
<root level="info">
    <appender-ref ref="Console"/>
    <appender-ref ref="RollingFileInfo"/>
</root>

Logger节点用来单独指定日志的形式,比如要为某个包下所有的class或者某个具体的class指定不同的日志级别等。

  • level : 日志输出级别
  • name : 用来指定该Logger所适用的类或者包.
  • AppenderRef :Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root
  • additivity :是否向上级传递日志 true(默认)或false
<loggers>
        <root level="info">
            <appender-ref ref="Console"/>
        </root>
        <!--  这里指定了过滤com.xcz.controller 包下面的日志,additivity设置为false 不向上面的console传递日志-->
        <logger name="com.xcz.controller" level="info" additivity="false">
            <appender-ref ref="RollingFileInfo"/>
        </logger>
    </loggers>

如果指定了logger,而没有添加appender,那么会过滤该日志,不进行输出

四. Log4j2异步输入日志

Log4j2有个突出的功能就是支持高效低延迟的异步化写日志。日志异步输出的好处在于,使用单独的进程来执行日志打印的功能,可以提高日志执行效率,减少日志功能对正常业务的影响。

日志的异步输出使用了disruptor这个开源的并发框架,所以首先得导入disruptor.jar包

		<dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.4.0</version>
        </dependency>

异步输出分为两种情况,一种为全异步模式,一种为异步和非异步混合输出模式。通过官方的性能对比,一般线程数在2-16之间的话,混合使用同步和异步的logger来打印日志,性能是最好的。

异步和非异步混合模式

这种模式的启用,主要在于两个节点的使用,分别为AsyncRootAsyncLogger,这两个节点可以和RootLogger节点混合使用。

在这里修改一下上述的log4j2.xml文件中Loggers节点就可以了。

<!-- 默认不打印location信息,诸如代码行号,类,方法等。 如果需要的话需要加上includeLocation="true",但是按官方说法会慢30-100倍。-->
        <AsyncLogger name="com.xcz.controller" level="info" additivity="false" includeLocation="true">
            <appender-ref ref="RollingFileInfo"/>
        </AsyncLogger>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值