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
- TimeBaseRollingPolicy :最常用的滚动策略,根据时间来制定滚动策略,即负责滚动也负责触发滚动。
(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);