logback常用配置

正文

添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

添加配置

RollingFileAppender使用

在resources文件夹下面添加logback.xml文件,配置如下

1
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
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>logback</contextName>
<property name="log.path" value="./log"/>
<property name="pattern" value="%d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level %msg%n"/>
<property name="CONSOLE_LOG_PATTERN"
value="%date{yyyy-MM-dd HH:mm:ss} | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %msg%n"/>

<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- 字符串System.out(默认)或者System.err -->
<target>System.out</target>
<!-- 对记录事件进行格式化 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>

<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建 -->
<file>${log.path}/xxx.log</file>
<!-- 当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 必要节点,包含文件名及"%d"转换符,"%d"可以包含一个java.text.SimpleDateFormat指定的时间格式,默认格式是 yyyy-MM-dd -->
<fileNamePattern>${log.path}/xxx_%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,如果是6,则只保存最近6个月的文件,删除之前的旧文件 -->
<maxHistory>6</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>

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

</configuration>

以上配置会让文件显示为彩色,并且生成文件还会每天压缩,在服务器上用 tail 或者 cat 命令会显示颜色,但是用 vim 打开并不会,相反会出现一些 口口 这样的字符

SiftingAppender使用

这里一个服务端对应多个客户端,需要在服务端将各个客户端的日志打印在不同的 log 日志里面,由于服务端和客户端已经建立的 netty 通信,所以这里就没有使用 Receiver
下面是服务端的配置,比上面不同的就是增加了一个 SIFT 的appender,以及一个 logger(这个类打印才是各个客户端上报的日志)

1
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
66
67
68
69
70
71
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">

<contextName>logback</contextName>
<property name="log.path" value="./log"/>
<property name="pattern" value="%d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level %msg%n"/>
<property name="CONSOLE_LOG_PATTERN"
value="%date{yyyy-MM-dd HH:mm:ss} | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %msg%n"/>

<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- 字符串System.out(默认)或者System.err -->
<target>System.out</target>
<!-- 对记录事件进行格式化 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>

<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建 -->
<file>${log.path}/antitamperserver.log</file>
<!-- 当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 必要节点,包含文件名及"%d"转换符,"%d"可以包含一个java.text.SimpleDateFormat指定的时间格式,默认格式是 yyyy-MM-dd -->
<fileNamePattern>${log.path}/antitamperserver_%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,如果是6,则只保存最近6个月的文件,删除之前的旧文件 -->
<maxHistory>6</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>

<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
<!-- 在缺少 class 属性的情况下,默认的 discriminator 类型为 ch.qos.logback.classic.sift.MDCBasedDiscriminator -->
<discriminator>
<key>clientId</key>
<defaultValue>unknown</defaultValue>
</discriminator>
<sift>
<appender name="FILE-${clientId}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/agent/agent_${clientId}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 必要节点,包含文件名及"%d"转换符,"%d"可以包含一个java.text.SimpleDateFormat指定的时间格式,默认格式是 yyyy-MM-dd -->
<fileNamePattern>${log.path}/agent_${clientId}%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,如果是6,则只保存最近6个月的文件,删除之前的旧文件 -->
<maxHistory>6</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%date{yyyy-MM-dd HH:mm:ss} | %X{clientId} | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %msg%n</pattern>
</encoder>
</appender>
</sift>
</appender>

<logger name="com.utstar.filemonitoring.netty.handler.AgentLogHandler" level="INFO" additivity="false">
<appender-ref ref="SIFT"/>
</logger>

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

</configuration>
1
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
package com.utstar.filemonitoring.netty.handler;

import com.alibaba.fastjson.JSON;
import com.utstar.filemonitoring.bean.LoggerMessage;
import com.utstar.filemonitoring.netty.Message;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;

/**
* FileName: AgentLogHandler
* Author: creambing
* Date: 2019-10-08 10:42
* Description:
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
@Slf4j
public class AgentLogHandler implements MessageHandler {

@Override
public void handlerMsg(Message msg) {
LoggerMessage loggerMessage = JSON.parseObject(msg.getMsgBody(), LoggerMessage.class);
if (loggerMessage == null) {
log.error("U cmd to obj is null,the cmd is:[{}]", msg.getMsgBody());
return;
}
MDC.put("clientId",msg.getClientId());
log.info(msg.getMsgBody());
}
}


package com.utstar.filemonitoring.bean;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* 〈一句话功能简述〉<br>
* 〈日志封装实体类〉
*
* @author creambing
* @since 1.0.0
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class LoggerMessage {
private String body;
private String timestamp;
private String threadName;
private String className;
private String level;
}

filter使用

如下是客户端的配置

1
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
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">

<contextName>logback</contextName>
<property name="log.path" value="./log"/>
<property name="pattern" value="%d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level %msg%n"/>
<property name="CONSOLE_LOG_PATTERN"
value="%date{yyyy-MM-dd HH:mm:ss} | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %msg%n"/>

<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="com.utstar.filemonitoring.filter.LogFilter"/>
<!-- 字符串System.out(默认)或者System.err -->
<target>System.out</target>
<!-- 对记录事件进行格式化 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>

<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建 -->
<file>${log.path}/antitamperagent.log</file>
<!-- 当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 必要节点,包含文件名及"%d"转换符,"%d"可以包含一个java.text.SimpleDateFormat指定的时间格式,默认格式是 yyyy-MM-dd -->
<fileNamePattern>${log.path}/antitamperagent_%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,如果是6,则只保存最近6个月的文件,删除之前的旧文件 -->
<maxHistory>6</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>

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

</configuration>

它与最上面的区别就是 console 的 appender 中多了下面这行,这行的作用是 console 捕获的消息都会被它拦截,在这里就可以把日志统一捕获并发送到服务端

1
<filter class="com.utstar.filemonitoring.filter.LogFilter"/>
1
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
/**
* Copyright (C), 2015-2019, 优地科技有限公司
* FileName: LogFilter
* Author: creambing
* Date: 2019-04-19 11:16
* Description: 日志拦截器
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
package com.utstar.filemonitoring.filter;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
import com.utstar.filemonitoring.bean.LoggerMessage;
import com.utstar.filemonitoring.netty.NettyClient;

import java.text.DateFormat;
import java.util.Date;

/**
* 〈一句话功能简述〉<br>
* 〈日志拦截器〉
*
* @author creambing
* @create 2019-04-19 11:16
* @since 1.0.0
*/
public class LogFilter extends Filter<ILoggingEvent> {

@Override
public FilterReply decide(ILoggingEvent event) {
LoggerMessage loggerMessage = new LoggerMessage(
event.getMessage()
, DateFormat.getDateTimeInstance().format(new Date(event.getTimeStamp())),
event.getThreadName(),
event.getLoggerName(),
event.getLevel().levelStr
);
NettyClient.sendUMsg(loggerMessage);
return FilterReply.ACCEPT;
}
}

参考资料

logback中文手册 http://www.logback.cn/

Cream Bing wechat
subscribe to my blog by scanning my public wechat account