对于一个web项目来说二,日志框架是必不可少的,日志的记录可以帮助我们在开发以及维护过程中快速的定位错误。相信很多人听说过slf4j,log4j,logback,JDK Logging等跟日志框架有关的词语,所以这里也简单介绍下他们之间的关系。
首先slf4j可以理解为规则的制定者,是一个抽象层,定义了日志相关的接口,log4j,logback,JDK Logging都是slf4j的实现层,只是处于不同。
其中slf4j + logback是当下最流行的日志框架。
在SpringBoot使用是非常方便的,不需要我们有复杂的配置,因为Spring Boot默认支持的就是slf4j + logback日志框架,而我们只需要在src/main/resources下添加配置文件logback-spring.xml即可。
logback-spring.xml配置规则
<configuration>
<scan>当配置文件发生修改时,是否重新加载该配置文件,默认为truescan>
<scanPeriod>检测“配置文件是否被修改”的时间周期,默认为1min,只有在scan = true时才生效scanPeriod>
<debug>是否打印logback内部日志,默认为falsedebug>
<appender>
<name>指定该节点的名称,方便之后的使用name>
<class>指定日志策略的类型的全限定名class>
appender>
<logger>
<name>用来指定受此约束的包或者类name>
<level>用来指定日志的输出级别,默认继承上级的级别level>
<additivity>是否向上级传递输出信息,默认为trueadditivity>
logger>
<root>
<level>用来指定日志的输出级别,默认继承上级的级别level>
root>
<property>
<name>变量名name>
<value>变量值value>
property>
configuration>
logback-spring.xml配置示例:定义了一个输出到控制台的ConsoleAppender以及输出到文件的FileAppender
<configuration>
<contextName>democontextName>
<property name="log.dir" value="logs"/>
<property name="log.appname" value="eran"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
appender>
<appender name="FILE_LOG" class="ch.qos.logback.core.FileAppender">
appender>
<logger name="com.demo" level="INFO"/>
<root level="debug">
<appender-ref ref="STDOUT" />
root>
configuration>
ConsoleAppender的功能
将日志输出到控制台
ConsoleAppender配置实例
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%npattern>
encoder>
appender>
ConsoleAppender的规则制定
%date{}:输出时间,可以在花括号内指定时间格式,例如-%data{yyyy-MM-dd HH:mm:ss}
%logger{}:日志的logger名称
%thread:产生日志的线程名,可简写为%t
%line:当前打印日志的语句在程序中的行号,可简写为%L
%level:日志级别,可简写为%le,%p
%message:程序员定义的日志打印内容,可简写为%msg,%m
%n:换行,即一条日志信息占一行
FileAppender的功能
FileAppender表示将日志输出到文件
FileAppender的配置实例
<appender name="FILE_LOG" class="ch.qos.logback.core.FileAppender">
<file>D:/test.logfile>
<append>trueappend>
<encoder>
<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%npattern>
encoder>
appender>
FileAppender的规则制定
:定义文件名和路径,可以是相对路径 , 也可以是绝对路径 , 如果路径不存在则会自动创建
:两个值true和false,默认为true,表示每次日志输出到文件走追加在原来文件的结尾,false则表示清空现存文件
:和ConsoleAppender一样
看示例就能懂其作用了
<appender name="ROL-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>D:/logs/test.%d{yyyy-MM-dd}.logfileNamePattern>
<maxHistory>7maxHistory>
<totalSizeCap>1GBtotalSizeCap>
rollingPolicy>
<encoder>
<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%npattern>
encoder>
appender>
TimeBasedRollingPolicy的规则制定
<fileNamePattern>:指定日志的路径以及日志文件名的命名规则,一般根据日志文件名+%d{}.log来命名,这边日期的格式默认为yyyy-MM-dd表示每天生成一个文件,即按天滚动yyyy-MM,表示每个月生成一个文件,即按月滚动
<maxHistory>:可选节点,控制保存的日志文件的最大数量,超出数量就删除旧文件,比如设置每天滚动,且<maxHistory> 是7,则只保存最近7天的文件,删除之前的旧文件
<encoder>:同上
<totalSizeCap>:这个节点表示设置所有的日志文件最多占的内存大小,当超过我们设置的值时,logback就会删除最早创建的那一个日志文件。
看示例就能看懂作用
<appender name="ROL-SIZE-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>D:/logs/test.%d{yyyy-MM-dd}.%i.logfileNamePattern>
<maxFileSize>100MBmaxFileSize>
<maxHistory>7maxHistory>
<totalSizeCap>1GBtotalSizeCap>
rollingPolicy>
<encoder>
<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%npattern>
encoder>
appender>
规则制定
1. 仔细观察上边demo中的<fileNamePattern>会发现比TimeBasedRollingPolicy中定义的
<fileNamePattern>多了.%i的字符,这个很关键,在SizeAndTimeBasedRollingPolicy中是必不可少的。
我们开发测试一般输出DEBUG级别的日志,生产环境配置只输出INFO级别的日志。
ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
过滤器通常配置在Appender中,一个Appender可以配置一个或者多个过滤器,有多个过滤器时按照配置顺序依次执行,其实大多数情况下我们都不需要配置,但是有的情况下又必须配置,所以这里也介绍下常用的也是笔者曾经使用过的两种过率机制:级别过滤器LevelFilter和临界值过滤器ThresholdFilter。
级别过滤器LevelFilter
设置了级别为INFO,满足的日志返回ACCEPT即立即处理,不满足条件的日志则返回DENY即丢弃掉,这样经过这一个过滤器就只有INFO级别的日志会被打印出输出。
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFOlevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
临界值过滤器ThresholdFilter
只处理INFO级别之上的日志,当日志级别等于或高于临界值时,过滤器返回NEUTRAL,当日志级别低于临界值时,返回DENY。
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFOlevel>
filter>
spring-logback.xml日志文件配置
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%contextName]%date [%thread %line] %level >> %msg >> %logger{10}%npattern>
encoder>
appender>
<appender name="FILE_LOG" class="ch.qos.logback.core.FileAppender">
<file>D:/test.logfile>
<append>trueappend>
<encoder>
<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%npattern>
encoder>
appender>
<appender name="ROL-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>D:/logs/test.%d{yyyy-MM-dd}.logfileNamePattern>
<maxHistory>7maxHistory>
<totalSizeCap>1GBtotalSizeCap>
rollingPolicy>
<encoder>
<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%npattern>
encoder>
appender>
<appender name="ROL-SIZE-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>D:/logs/test.%d{yyyy-MM-dd}.%i.logfileNamePattern>
<maxFileSize>100MBmaxFileSize>
<maxHistory>7maxHistory>
<totalSizeCap>1GBtotalSizeCap>
rollingPolicy>
<encoder>
<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%npattern>
encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFOlevel>
filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFOlevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
appender>
<appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">
<discardingThreshold >0discardingThreshold>
<queueSize>512queueSize>
<appender-ref ref ="FILE_LOG"/>
appender>
<logger name="com.example" level="DEBUG">logger>
<springProfile name="dev">
<root level="DEBUG">
<appender-ref ref="STDOUT" />
root>
springProfile>
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="ASYNC" />
root>
springProfile>
configuration>
当然,如果你的日志输出文件路径只填写了文件名,那输出日志就会默认存放在项目中
代码中使用日志
@Slf4j
public class App
{
public static void main( String[] args )
{
log.trace("trace级别的日志");
log.debug("debug级别日志");
log.info("info级别日志");
log.warn("warn级别的日志");
log.error("error级别日志");
String name = "bysen";
Integer age = 24;
log.info("姓名{}, 年龄{}",name,age);
}
}
项目启动后,SpringBoot默认读取的日志文件是spring-logback,所以名字错误可能就读不到了,那么在项目运行之后,就会在制定路径下生成一个日志文件了。