LogBack就是在项目中使用的日志配置文件,里面配置了日志的输出格式,输出位置,输出的级别等等,方便日后的排查,监控系统运行情况。
1.logback-spring.xml基本结构1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<logger name="com.zhaixin.controller" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
1.根节点< configuration>,包含下面三个属性:
scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
1
2
3 <configuration scan="true" scanPeriod="60 seconds" debug="false">
<!--其他配置省略-->
</configuration>
2.子节点< contextName>:用来设置上下文名称,每个logger都关联到logger上下文,默认上下文名称为default。但可以使用< contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
1
2
3
4 <configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>myAppName</contextName>
<!--其他配置省略-->
</configuration>
3.子节点< property> :用来定义变量值,它有两个属性name和value,通过< property>定义的值会被插入到logger上下文中,可以使“${}”来使用变量。
name: 变量的名称
value: 的值时变量定义的值
1
2
3
4
5 <configuration scan="true" scanPeriod="60 seconds" debug="false">
<property name="APP_Name" value="myAppName" />
<contextName>${APP_Name}</contextName>
<!--其他配置省略-->
</configuration>
4.子节点< timestamp>:获取时间戳字符串,他有两个属性key和datePattern
key: 标识此< timestamp> 的名字;
datePattern: 设置将当前时间(解析配置文件的时间)转换为字符串的模式,遵循java.txt.SimpleDateFormat的格式。
1
2
3
4
5 <configuration scan="true" scanPeriod="60 seconds" debug="false">
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<contextName>${bySecond}</contextName>
<!-- 其他配置省略-->
</configuration>
5.子节点< appender>:负责写日志的组件,它有两个必要属性name和class。name指定appender名称,class指定appender的全限定名
(1) ch.qos.logback.core.ConsoleAppender把日志输出到控制台,有以下子节点:
< encoder>:对日志进行格式化。
< target>:字符串System.out(默认)或者System.err
下面的代码表示在控制台输出DEBUG级别的日志,格式为< patten>
1
2
3
4
5
6
7
8
9
10
11 <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
(2) ch.qos.logback.core.FileAppender把日志添加到文件,有以下子节点:
< file>:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。
< append>:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。
< encoder>:对记录事件进行格式化。
< prudent>:如果是 true,日志会被安全的写入文件,即使其他的FileAppender也在向此文件做写入操作,效率低,默认是 false。
下面的代码是将DEBUG级别的日志输出到testFile.log中,格式为< pattern>
1
2
3
4
5
6
7
8
9
10
11
12
13 <configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
(3) ch.qos.logback.core.rolling.RollingFileAppender滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。有以下子节点:
< file>:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。
< append>:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。
< rollingPolicy>:当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类。其中class=”ch.qos.logback.core.rolling.TimeBasedRollingPolicy”是最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
rollingPolicy有以下子节点
< fileNamePattern>:必要节点,包含文件名及“%d”转换符,“%d”可以包含一个java.text.SimpleDateFormat指定的时间格式,如:%d{yyyy-MM}。如果直接使用 %d,默认格式是 yyyy-MM-dd。
其中RollingFileAppender的file字节点可有可无,通过设置file,可以为活动文件和归档文件指定不同位置,当前日志总是记录到file指定的文件(活动文件),活动文件的名字不会改变;
如果没设置file,活动文件的名字会根据fileNamePattern 的值,每隔一段时间改变一次。“/”或者“\”会被当做目录分隔符。
< maxHistory>:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,且< maxHistory>是30,则只保存最近30天的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除。
下面代码表示每天生成一个日志文件,保存30天的日志文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 <configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
< triggeringPolicy class=”ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy”>查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender 触发当前活动文件滚动。
只有一个节点:< maxFileSize>活动文件的大小,默认值是10MB。< rollingPolicy class=”ch.qos.logback.core.rolling.FixedWindowRollingPolicy”>这时第二个策略, 根据固定窗口算法重命名文件的滚动策略。
有以下子节点:
< minIndex>:窗口索引最小值
< maxIndex>:窗口索引最大值,当用户指定的窗口过大时,会自动将窗口设置为12。
< fileNamePattern>:生成文件的名称,必须包含“%i”例如,假设最小值和最大值分别为1和2,命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。还可以指定文件压缩选项,例如,mylog%i.log.gz 或者 没有log%i.log.zip注意:
< prudent>:当为true时,不支持FixedWindowRollingPolicy。支持TimeBasedRollingPolicy,但是有两个限制,a.不支持也不允许文件压缩,b.不能设置file属性,必须留空。下面的代码表示按照固定窗口模式生成日志文件,当文件大于5MB时,生成新的日志文件。窗口大小是1到3,当保存了3个归档文件后,将覆盖最早的日志。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 <configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>tests.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
6.< logger>:用来设置某一个包或具体的某一个类的日志打印级别、以及指定< appender>。指定项目中某个包,当有日志操作行为时的日志记录级别,级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE ,其中当additivity=false 表示匹配之后,不再继续传递给其他的logger
常用的Logger
1
2
3
4
5
6
7
8
9
10
11
12 !-- 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" />
<!--myibatis 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"/>
2.logback实例及自定义appender
logback-spring/xml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,%i索引【从数字0开始递增】,,, -->
<!-- appender是configuration的子节点,是负责写日志的组件。 -->
<!-- ConsoleAppender:把日志输出到控制台 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d [%t] %-5level %logger{36}.%M\(%file:%line\) - %msg%n</pattern>
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="errorAlarm" class="com.zhaixin.config.ServiceAlarm">
<!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是demo.log -->
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过1KB时,对当前日志进行分割 重命名-->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 INFO 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
<!-- TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
<!-- 文件名:log/demo.2018-06-23.0.log -->
<fileNamePattern>logs/log_file.%d.%i.log</fileNamePattern>
<!-- 每产生一个日志文件,该日志文件的保存期限为30天 -->
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成1KB看效果 -->
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<!-- pattern节点,用来设置日志的输入格式 -->
<pattern>
%d %p (%file:%line\)- %m%n
</pattern>
<!-- 记录日志的编码:此处设置字符集 - -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
<!-- additivity=false 表示匹配之后,不再继续传递给其他的logger-->
<logger name="com.zhaixin.controller" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
<appender-ref ref="errorAlarm"/>
</logger>
<!-- 控制台输出日志级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
自定义appernder1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28package com.zhaixin.config;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
public class ServiceAlarm extends AppenderBase<ILoggingEvent> {
private static final long INTERVAL = 10*1000*60;
private long lastAlarmTime = 0;
protected void append(ILoggingEvent iLoggingEvent) {
if(canAlarm()) {
doAlarm(iLoggingEvent.getFormattedMessage());
}
}
private boolean canAlarm() {
long now = System.currentTimeMillis();
if(now - lastAlarmTime >= INTERVAL) {
lastAlarmTime = now;
return true;
}else {
return false;
}
}
private void doAlarm(String content) {
// send email
}
}
参考:
https://juejin.cn/post/6844903624259141639
https://www.cnblogs.com/warking/p/5710303.html