Spring5.x与日志框架的整合

一、spring整合logback

logback介绍

(1)、根节点<configuration>有三个属性debug 、scan 、scanPeriod 

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

<configuration>有<appender>、<logger>、<root>三个子节点。

基本结构可以描述为:以<configuration>开头,后面有零个或多个<appender>元素,有零个或多个<logger>元素,有最多一个<root>元素

(2)、<appender> 是负责写日志的组件。

appender 有两个必要属性 name ,class 。name指定appender 的名称, class 指定appender的全限定名
class 包括 :ch.qos.logback.core.ConsoleAppender / ch.qos.logback.core.FileAppender/ ch.qos.logback.core.RollingFileAppender。

  • ConsoleAppender:把日志添加到控制台
    • <encoder> : 对日志进行格式化。
    • <target> : 字符串System.out 或者 System.err, 默认 System.out;
  • FileAppender:把日志添加到文件
    • <file>: 被写入的文件名,可以是相对目录 , 也可以是绝对目录 , 如果目录不存在则会自动创建
    • <append> : 如果是true , 日志被追加到文件结尾 , 如果是false,清空现存文件 , 默认是true
    • <encoder> : 对日志进行格式化
    • <prodent> : 如果是true,日志会被安全的写入文件 , 即使其他的FileAppender也会向此文件做写入操作 , 默认是false
  • RollingFileAppender [常用]:滚动记录文件,先将日志记录到指定文件,当符合某种条件时,将日志记录到其他文件
    • <file> : 被写入的文件名,可以是相对目录,也可以解决目录,如果目录不存在则自动创建。
    • <append> : 如果是true,日志被追加到文件结尾,如果是false,清空现存文件,默认是true;
    • <encoder> : 对日志进行格式化
    • <rollingPolicy> : 当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。
      • TimeBaseRollingPolicy :最常用的滚动策略,根据时间来制定滚动策略,即负责滚动也负责触发滚动。
        • <fileNamePattern> :必要节点,包含文件及“%d” 转换符,“%d”可以包含一个java.text.SimpleDateFormat 制定的时间格式,如:%d{yyyy-MM},如果直接使用 %d ,默认格式是 yyyy-MM-dd。必须包含“%i” 例如:设置最小值,和最大值分别为1和2,命名模式为 log%i.log,会产生归档文件log1.log和log2.log,还可以指定文件压缩选项,例如:log%i.log.gz 或者 log%i.log.zip
        • <maxHistory>:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件,假设设置每个月滚动,且<maxHistory> 是6,则只保存最近6个月的文件,删除之前的旧文件,注意:删除旧文件是哪些为了归档而创建的目录也会被删除。
        • <triggeringPolicy> :告知RollingFileAppender   激活RollingFileAppender滚动
      • SizeBasedTriggeringPolicy :查看当前活动文件的大小 , 如果超过指定大小会告知 RollingFileAppender , 触发当前活动滚动 , 只有一个节点 , 用来规定文件大小
        • <maxFileSize> : 活动文件的大小 , 默认10MB

(3) logger节点用来设置某一个包或者具体的某一个类的日志打印级别,以及指定<appender>, logger 仅有一个name属性,两个可选属性 level/addtivity 。

  • name : 用来指定受此loger约束的某一个包或者具体的某一个类
  • level:用来设置打印级别,大小写无关,TRACE,DEBUG,INFO,WARE,ERROR,ALL和OFF,还有一个特殊值INHERITED 或者 同义词NULL,代表强制执行上级的级别。
    • 如果未设置此属性,那么当前logger将会继承上级的级别。
    • level大小:ERROR > WARN > INFO > DEBUG > TRACE,程序会打印高于或等于所设置级别的日志。
  • addtivity : 是否向上级loger传递打印信息,默认为true;

<logger> 可以包含零个或多个<appender-ref>元素,表示这个appender将会添加到logger。 

(4)、root节点:元素配置根 logger。该元素有一个 level 属性。没有 name 属性,因为已经被命名 为“root”

level 属性的值大小写无关,其值为下面其中一个字符串:TRACE、DEBUG、INFO、 WARN、ERROR、ALL 和 OFF。注意不能设置为“INHERITED” 或“NULL”。 元素可以包含零个或多个元素。与元素类似,声明 元素后,会先关闭然后移除全部当前 appender,只引用声明了的 appender。如果 root 元素没 有引用任何 appender,就会失去所有 appender。 

(5)、filter过滤节点

Logback 的过滤器基于三值逻辑(ternary logic),允许把它们组装或成链,从而组成任 意的复合过滤策略。

这里的所谓三值逻辑是说,过滤器的返回值只能是 ACCEPT、DENY 和 NEUTRAL 的其中一个。

过滤器一般分为如下几类 :

  • 级别过滤器(LevelFilter):LevelFilter 根据记录级别对记录事件进行过滤。如果事件的级别等于配置的级别,过滤器会根据 onMatch 和 onMismatch 属性接受或拒绝事件。
  • 临界值过滤器(ThresholdFilter):ThresholdFilter 过滤掉低于指定临界值的事件 . 当记录的级别等于或高于临界值时 , ThresholdFilter 的decide()方法会返回NEUTRAL ; 当记录级别低于临界值时 , 事件会被拒绝。
  • 求值过滤器(EvaluatorFilter):EvaluatorFilter 封装了 EventEvaluator(ch.qos.logback.core.boolex.EventEvaluator) , 评估 是否符合指定的条件。
添加logback依赖
<!-- 日志文件管理包 -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
<dependency>
    <groupId>org.logback-extensions</groupId>
    <artifactId>logback-ext-spring</artifactId>
    <version>0.1.5</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.7.30</version>
</dependency>
<!-- 日志文件管理包 -->

logback-classic:包含了logback本身所需的slf4j-api.jar、logback-core.jar及logback-classsic.jar。 

logback-ext-spring:由官方提供的对Spring的支持,它的作用就相当于log4j中的Log4jConfigListener。

jcl-over-slf4j:用来把Spring源代码中大量使用到的commons-logging替换成slf4j,只有在添加了这个依赖之后才能看到Spring框架本身打印的日志–即info文件中打印出的spring启动日志信息,否则只能看到开发者自己打印的日志。

扫描xml

尽量的在pom的build标签中加入如下内容,以扫描到logback.xml文件。

<build>
        <!--扫描全局xml, 以便扫描到相关配置文件-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
引入logback.xml日志配置文件

这里特别注意引入位置(maven工程)在src/main/resource这个根目录下。

logback.xml配置信息

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

    <!-- 模块名 -->
    <contextName>OS_PRO</contextName>

    <!--定义日志文件的存储地址 logs为当前项目的logs目录 还可以设置为../logs -->
    <property name="LOG_HOME" value="logs" />

    <!--控制台日志, 控制台输出 -->
    <appender name="STDOUT" 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>
        </encoder>
    </appender>

    <!--文件日志, 按照每天生成日志文件 -->
    <appender name="FILE_ERROR" 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>30</maxHistory>
        </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>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>10MB</maxFileSize>
        </triggeringPolicy>
        <!-- 过滤掉 低于ERROR级别的-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>WARN</level>
        </filter>
    </appender>

    <!--文件日志, 按照每天生成日志文件 -->
    <appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <fileNamePattern>${LOG_HOME}/debugAndInfo-%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志文件保留天数-->
            <maxHistory>30</maxHistory>
        </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>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>10MB</maxFileSize>
        </triggeringPolicy>
        <!-- 过滤掉 低于DEBUG级别的-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>

    <!-- spring及apache-->
    <logger name="org.springframework" level="INFO" />
    <logger name="org.apache.http" level="INFO" />

    <!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
    <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
    <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
    <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />

    <!-- mybatis log configure-->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>

    <!--日志的输出级别由低到高(越来问题越严重)trace->debug->info->warn->error -->
    <!-- 日志输出级别 生成上禁止DEBUG, 至少INFO级别-->
    <root level="INFO">
        <!-- 生产上 STDOUT 要注释掉 -->
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE_DEBUG"/>
        <appender-ref ref="FILE_ERROR"/>
    </root>
</configuration>

这样使用:

private static Logger logger = LoggerFactory.getLogger(当前类.class);

二、spring整合log4j

log4j介绍
关于配置文件的名称以及在项目中的存放位置

log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",".json"或者".jsn"。

系统选择配置文件的优先级(从先到后)如下:

(1)、classpath下的名为log4j2-test.json 或者log4j2-test.jsn的文件.

(2)、classpath下的名为log4j2-test.xml的文件.

(3)、classpath下名为log4j2.json 或者log4j2.jsn的文件.

(4)、classpath下名为log4j2.xml的文件.

我们一般默认使用log4j2.xml进行命名。如果本地要测试,可以把log4j2-test.xml放到classpath,而正式环境使用log4j2.xml,则在打包部署的时候不要打包log4j2-test.xml即可。

缺省默认配置文件
<?xml version="1.0" encoding="UTF-8"?>
 <Configuration status="WARN">
   <Appenders>
     <Console name="Console" target="SYSTEM_OUT">
       <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
     </Console>
   </Appenders>
   <Loggers>
     <Root level="error">
       <AppenderRef ref="Console"/>
     </Root>
   </Loggers>
 </Configuration>
配置文件节点解析

(1)、根节点Configuration有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers(表明可以定义多个Appender和Logger)。

  • status用来指定log4j本身的打印日志的级别。
  • monitorinterval用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s。

(2)、Appenders节点,常见的有三种子节点:Console、RollingFile、File

  • Console节点用来定义输出到控制台的Appender
    • name:指定Appender的名字。
    • target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认SYSTEM_OUT。
    • PatternLayout:输出格式,不设置默认为:%m%n.
  • File节点用来定义输出到指定位置的文件的Appender
    • name:指定Appender的名字。
    • fileName:指定输出日志的目的文件带全路径的文件名。
    • PatternLayout:输出格式,不设置默认为:%m%n。
  • RollingFile节点用来定义超过指定大小自动删除旧的创建新的的Appender
    • name:指定Appender的名字.
    • fileName:指定输出日志的目的文件带全路径的文件名.
    • PatternLayout:输出格式,不设置默认为:%m%n.
    • filePattern:指定新建日志文件的名称格式.
    • Policies:指定滚动日志的策略,就是什么时候进行新建日志文件输出日志
      • TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am。
      • SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小。
    • DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)。

(3)、Loggers节点,常见的有两种:Root和Logger。

  • Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出。
    • level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
    • AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender.
  • Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。
    • level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
    • name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.
    • AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity="false"只在自定义的Appender中进行输出。

(4)、关于日志level。

共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

  • All:最低等级的,用于打开所有日志记录.
  • Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.
  • Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.
  • Info:消息在粗粒度级别上突出强调应用程序的运行过程.
  • Warn:输出警告及warn以下级别的日志.
  • Error:输出错误信息日志.
  • Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志.
  • OFF:最高等级的,用于关闭所有日志记录.

程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少。

引入log4j依赖
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.14.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.14.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.14.0</version>
</dependency>
log4j.xml配置信息

在src/main/resource这个根目录下创建,比较完整的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="30">
    <!--先定义所有的appender-->
    <appenders>
        <!--这个输出控制台的配置-->
        <console name="Console" target="SYSTEM_OUT">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符-->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
        </console>
        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
        <File name="log" fileName="logs/test.log" append="false">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
        </File>
        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileInfo" fileName="./logs/info.log"
                     filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>

        </RollingFile>
        <RollingFile name="RollingFileWarn" fileName="./logs/debug.log"
                     filePattern="./logs/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
            <DefaultRolloverStrategy max="20"/>
        </RollingFile>
        <RollingFile name="RollingFileError" fileName="./logs/error.log"
                     filePattern="./logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
        </RollingFile>
    </appenders>
    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.springframework" level="INFO"></logger>
        <logger name="org.mybatis" level="INFO"></logger>
        <root level="all">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
        </root>
    </loggers>
</configuration>

使用方法:

private static final Logger log = LoggerFactory.getLogger(当前类.class);

 

posted @ 2020-11-26 09:07  codedot  阅读(862)  评论(0编辑  收藏  举报