self4j 与 logback 配置详解—logger、root

https://blog.csdn.net/u012129558/article/details/79947477

https://segmentfault.com/a/1190000039127436

背景
java web 下有好几种日志框架,比如:logback,log4j,log4j2(slj4f 并不是一种日志框架,它相当于定义了规范,实现了这个规范的日志框架就能够用 slj4f 调用)。其中性能最高的应该使 logback 了,而且 springboot 默认使用的也是 logback 日志,所以本篇将会详细的讲解 logback 的日志配置方案。

本篇主要内容如下:

  • logback 配置文件的构成
  • 如何将日志输出到文件
  • 如何按时间,按大小切分日志
  • 如何将让一个日志文件中只有一种日志级别
  • 如何将指定包下的日志输出到指定的日志文件中

简单使用

  如果无需复杂的日志配置,执行简单设置日志打印级别,打印方式可直接再 application.yml 中配置。

  默认情况下 Spring Boot 将 info 级别的日志输出到控制台中,不会写到日志文件,且不能进行复杂配置。

打印到文件中

  想要将日志输出到文件中,可通过如下两个配置:

logging:
  # 配置输出额日志文件名,可以带路径
  #  file: out.log
  # 配置日志存放路径,日志文件名为:spring.log
  path: ./log
  file:
    # 设置日志文件大小
    max-size: 10MB

注意:file 和 path 是不能同时配置的,如果同时配置path不会生效。

打印级别控制

  可通过配置控制日志打印级别,格式如下:

logging.level.*=TRACE/DEBUG/INFO/...

*可以为包名或 Logger 名,如下:

logging:
  level:
    # root日志以WARN级别输出
    root: info
    # 此包下所有class以DEBUG级别输出
    com.example.log_demo.log1: warn

logback 详细配置

  接下来说明如何通过独立的 xml 配置文件来配置日志打印。虽然 springboot 是要消灭 xml 的,但是有些复杂功能还是得编写 xml。使用 xml 后要将 application.yml 中的配置去掉,避免冲突.

  根据不同的日志系统,按照指定的规则组织配置文件名,并放在 resources 目录下,就能自动被 spring boot 加载:

  • Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
  • Log4j: log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
  • Log4j2: log4j2-spring.xml, log4j2.xml
  • JDK (Java Util Logging): logging.properties

想要自定义文件名的可配置:logging.config指定配置文件名:

logging.config=classpath:logging-config.xml

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

logback 配置文件的组成

  根节点<configuration>有 5 个子节点,下面来进行一一介绍。

<root>节点

  root 节点是必选节点,用来指定最基础的日志输出级别,只有一个 level 属性,用于设置打印级别,可选如下:TRACE,DEBUG,INFO,WARN,ERROR,ALL,OFF

  root 节点可以包含 0 个或多个元素,将appender添加进来。如下:

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

appender 也是子节点之一,将会在后面说明。

<contextName>节点

  设置上下文名称,默认为default,可通过%contextName来打印上下文名称,一般不使用此属性。

<property>节点

  用于定义变量,方便使用。有两个属性:name,value。定义变量后,可以使用${}来使用变量。如下:

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

<appender>节点

  appender 用来格式化日志输出的节点,这个最重要。有两个属性:

  • name:该本 appender 命名
  • class:指定输出策略,通常有两种:控制台输出,文件输出

下面通过例子来说明这个怎么用:

  1. 输出到控制台/按时间输出日志
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--设置存储路径变量-->
    <property name="LOG_HOME" value="./log"/>

    <!--控制台输出appender-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!--设置输出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <!--设置编码-->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--文件输出,时间窗口滚动-->
    <appender name="timeFileOutput" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志名,指定最新的文件名,其他文件名使用FileNamePattern -->
        <File>${LOG_HOME}/timeFile/out.log</File>
        <!--文件滚动模式-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名,可设置文件类型为gz,开启文件压缩-->
            <FileNamePattern>${LOG_HOME}/timeFile/info.%d{yyyy-MM-dd}.%i.log.gz</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
            <!--按大小分割同一天的-->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>

        <!--输出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <!--设置编码-->
            <charset>UTF-8</charset>
        </encoder>

    </appender>

    <!--指定基础的日志输出级别-->
    <root level="INFO">
        <!--appender将会添加到这个loger-->
        <appender-ref ref="console"/>
        <appender-ref ref="timeFileOutput"/>
    </root>
    </configuration>
  1. 设置只输出单个级别

  在 appender 中设置,filter 子节点,在默认级别上再此过滤,配置 onMatch,onMismatch 可实现只输出单个级别

<appender ...>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>INFO</level>
        <!--接受匹配-->
        <onMatch>ACCEPT</onMatch>
        <!--拒绝不匹配的-->
        <onMismatch>DENY</onMismatch>
    </filter>
</appender>

<logger>节点

构成

  此节点用来设置一个包或具体的某一个类的日志打印级别、以及指定<appender>,有以下三个属性:

  • name: 必须。用来指定受此 loger 约束的某个包或者某个具体的类
  • level:可选。设置打印级别。默认为 root 的级别。
  • addtivity: 可选。是否向上级 loger(也就是 root 节点)传递打印信息。默认为 true。

使用示例如下:

  1. 不指定级别,不指定 appender

<!-- 控制com.example.service下类的打印,使用root的level和appender -->
<logger name="com.example.service"/>

2.指定级别,不指定 appender

<!-- 控制com.example.service下类的打印,使用root的appender打印warn级别日志 -->
<logger name="com.example.service" level="WARN"/>

3.指定级别,指定 appender

<!-- 控制com.example.service下类的打印,使用console打印warn级别日志 -->
<!-- 设置addtivity是因为这里已经指定了appender,如果再向上传递就会被root下的appender再次打印 -->

<logger name="com.example.service" level="WARN" addtivity="false">
    <appender-ref ref="console">
</logger>

通过指定 appender 就能将指定的包下的日志打印到指定的文件中。

多环境日志输出

  通过设置文件名为-spring 结尾,可分环境配置 logger,示例如下:

<configuration>
    <!-- 测试环境+开发环境. 多个使用逗号隔开. -->
    <springProfile name="test,dev">
        <logger name="com.example.demo.controller" level="DEBUG" additivity="false">
            <appender-ref ref="console"/>
        </logger>
    </springProfile>
    <!-- 生产环境. -->
    <springProfile name="prod">
        <logger name="com.example.demo" level="INFO" additivity="false">
            <appender-ref ref="timeFileOutput"/>
        </logger>
    </springProfile>
</configuration>

通过配置spring.profiles.active也能做到切换上面的 logger 打印设置

目录

正文

1、根节点<configuration>包含的属性

scan:

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

scanPeriod:

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

debug:

当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。

例如:

 <configuration scan="true" scanPeriod="60 seconds" debug="false">  
      <!-- 其他配置省略-->  
</configuration>

回到顶部

2、根节点<configuration>的子节点

  

 2.1、设置上下文名称:<contextName>

  1. 默认方式:<contextName>
    每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
     <configuration scan="true" scanPeriod="60 seconds" debug="false">  
          <contextName>myAppName</contextName>  
          <!-- 其他配置省略-->  
    </configuration>
  2. 设置变量: <property>
    用来定义变量值的标签,<property> 有两个属性,name和value;其中name的值是变量的名称,value的值时变量定义的值。通过<property>定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
    例如使用<property>定义上下文名称,然后在<contentName>设置logger上下文时使用。
     <configuration scan="true" scanPeriod="60 seconds" debug="false">  
          <property name="APP_Name" value="myAppName" />   
          <contextName>${APP_Name}</contextName>  
          <!-- 其他配置省略-->  
    </configuration>
  3. 获取时间戳字符串:<timestamp>
    两个属性 key:标识此<timestamp> 的名字;datePattern:设置将当前时间(解析配置文件的时间)转换为字符串的模式,遵循java.txt.SimpleDateFormat的格式。
    例如将解析配置文件的时间作为上下文名称:
     <configuration scan="true" scanPeriod="60 seconds" debug="false">  
          <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>   
          <contextName>${bySecond}</contextName>  
          <!-- 其他配置省略-->  
    </configuration>

 2.2、设置loger、root

  1. 设置loger
    用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。<loger>仅有一个name属性,一个可选的level和一个可选的addtivity属性。
    name:用来指定受此loger约束的某一个包或者具体的某一个类。
    level:用来设置打印级别(日志级别),大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。
    addtivity:是否向上级loger传递打印信息。默认是true。

    <loger>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger。
  2. 设置root
    也是<loger>元素,但是它是根loger。只有一个level属性,应为已经被命名为"root".
    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。默认是DEBUG。

    <root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger。
  3. 举例说明-demo
    例如:LogbackDemo.java类

    复制代码

     package logback;  
      
    import org.slf4j.Logger;  
    import org.slf4j.LoggerFactory;  
      
    public class LogbackDemo {  
        private static Logger log = LoggerFactory.getLogger(LogbackDemo.class);  
        public static void main(String[] args) {  
            log.trace("======trace");  
            log.debug("======debug");  
            log.info("======info");  
            log.warn("======warn");  
            log.error("======error");  
        }  
    }

    复制代码

    logback.xml配置文件

    第1种:只配置root

    复制代码

     <configuration>   
       
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">   
        <!-- encoder 默认配置为PatternLayoutEncoder -->   
        <encoder>   
          <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>   
        </encoder>   
      </appender>   
       
      <root level="INFO">             
        <appender-ref ref="STDOUT" />   
      </root>     
         
     </configuration>

    复制代码

    其中appender的配置表示打印到控制台(稍后详细讲解appender );
    <root level="INFO">将root的打印级别设置为“INFO”,指定了名字为“STDOUT”的appender。

    当执行logback.LogbackDemo类的main方法时,root将级别为“INFO”及大于“INFO”的日志信息交给已经配置好的名为“STDOUT”的appender处理,“STDOUT”appender将信息打印到控制台;
    打印结果如下:

    13:30:38.484 [main] INFO  logback.LogbackDemo - ======info  
    13:30:38.500 [main] WARN  logback.LogbackDemo - ======warn  
    13:30:38.500 [main] ERROR logback.LogbackDemo - ======error

    第2种:带有loger的配置,不指定级别,不指定appender,

    复制代码

     <configuration>   
       
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">   
        <!-- encoder 默认配置为PatternLayoutEncoder -->   
        <encoder>   
          <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>   
        </encoder>   
      </appender>   
       
      <!-- logback为java中的包 -->   
      <logger name="logback"/>   
       
      <root level="DEBUG">             
        <appender-ref ref="STDOUT" />   
      </root>     
         
     </configuration>

    复制代码

    其中appender的配置表示打印到控制台(稍后详细讲解appender );
    <logger name="logback" />将控制logback包下的所有类的日志的打印,但是并没用设置打印级别,所以继承他的上级<root>的日志级别“DEBUG”;
    没有设置addtivity,默认为true,将此loger的打印信息向上级传递;
    没有设置appender,此loger本身不打印任何信息。
    <root level="DEBUG">将root的打印级别设置为“DEBUG”,指定了名字为“STDOUT”的appender。

    当执行logback.LogbackDemo类的main方法时,因为LogbackDemo 在包logback中,所以首先执行<logger name="logback" />,将级别为“DEBUG”及大于“DEBUG”的日志信息传递给root,本身并不打印;
    root接到下级传递的信息,交给已经配置好的名为“STDOUT”的appender处理,“STDOUT”appender将信息打印到控制台;
    打印结果如下:

    13:19:15.406 [main] DEBUG logback.LogbackDemo - ======debug  
    13:19:15.406 [main] INFO  logback.LogbackDemo - ======info  
    13:19:15.406 [main] WARN  logback.LogbackDemo - ======warn  
    13:19:15.406 [main] ERROR logback.LogbackDemo - ======error

     第3种:带有多个loger的配置,指定级别,指定appender 

    复制代码

     <configuration>   
       <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">   
        <!-- encoder 默认配置为PatternLayoutEncoder -->   
        <encoder>   
          <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>   
        </encoder>   
      </appender>   
       
      <!-- logback为java中的包 -->   
      <logger name="logback"/>   
      <!--logback.LogbackDemo:类的全路径 -->   
      <logger name="logback.LogbackDemo" level="INFO" additivity="false">  
        <appender-ref ref="STDOUT"/>  
      </logger>   
        
      <root level="DEBUG">             
        <appender-ref ref="STDOUT" />   
      </root>     
    </configuration>

    复制代码

    其中appender的配置表示打印到控制台(稍后详细讲解appender );

    <logger name="logback" />将控制logback包下的所有类的日志的打印,但是并没用设置打印级别,所以继承他的上级<root>的日志级别“DEBUG”;
    没有设置addtivity,默认为true,将此loger的打印信息向上级传递;
    没有设置appender,此loger本身不打印任何信息。

    <logger name="logback.LogbackDemo" level="INFO" additivity="false">控制logback.LogbackDemo类的日志打印,打印级别为“INFO”;

    additivity属性为false,表示此loger的打印信息不再向上级传递,

    指定了名字为“STDOUT”的appender。

    <root level="DEBUG">将root的打印级别设置为“DEBUG”,指定了名字为“STDOUT”的appender。

    当执行logback.LogbackDemo类的main方法时,先执行<logger name="logback.LogbackDemo" level="INFO" additivity="false">,将级别为“INFO”及大于“INFO”的日志信息交给此loger指定的名为“STDOUT”的appender处理,在控制台中打出日志,不再向次loger的上级 <logger name="logback"/> 传递打印信息;

    <logger name="logback"/>未接到任何打印信息,当然也不会给它的上级root传递任何打印信息;
    打印结果如下:

    14:05:35.937 [main] INFO  logback.LogbackDemo - ======info  
    14:05:35.937 [main] WARN  logback.LogbackDemo - ======warn  
    14:05:35.937 [main] ERROR logback.LogbackDemo - ======error

    如果将<logger name="logback.LogbackDemo" level="INFO" additivity="false">修改为 <logger name="logback.LogbackDemo" level="INFO" additivity="true">那打印结果将是什么呢?
    没错,日志打印了两次,想必大家都知道原因了,因为打印信息向上级传递,logger本身打印一次,root接到后又打印一次
    打印结果如下:

    复制代码

    14:09:01.531 [main] INFO  logback.LogbackDemo - ======info  
    14:09:01.531 [main] INFO  logback.LogbackDemo - ======info  
    14:09:01.531 [main] WARN  logback.LogbackDemo - ======warn  
    14:09:01.531 [main] WARN  logback.LogbackDemo - ======warn  
    14:09:01.531 [main] ERROR logback.LogbackDemo - ======error  
    14:09:01.531 [main] ERROR logback.LogbackDemo - ======error

    复制代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值