SpringBoot解决方案之 统一日志

配置时考虑点

在配置日志时需要考虑哪些因素?

  • 支持日志路径,日志level等配置
  • 日志控制配置通过application.yml下发
  • 按天生成日志,当天的日志>50MB回滚
  • 最多保存 10 天日志
  • 生成的日志中 Pattern 自定义
  • Pattern中添加用户自定义的MDC字段,比如用户信息(当前日志是由哪个用户的请求产生),request信息。此种方式可以通过AOP切面控制,在MDC中添加 requestID,在 logback_spring.xml 中配置 Pattern。
  • 根据不同的运行环境设置 Profile - dev,test,product
  • 对控制台,Err 和 全量日志 分别配置
  • 对第三方包路径日志控制

实现范例

application.yml 方式

1
2
3
4
5
logging:
level:
root: debug
file:
path:

logback_spring.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
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

<!-- 日志根目录-->
<springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="/data/logs/springboot-logback-demo"/>

<!-- 日志级别 -->
<springProperty scope="context" name="LOG_ROOT_LEVEL" source="logging.level.root" defaultValue="DEBUG"/>

<!-- 标识这个"STDOUT" 将会添加到这个logger -->
<springProperty scope="context" name="STDOUT" source="log.stdout" defaultValue="STDOUT"/>

<!-- 日志文件名称-->
<property name="LOG_PREFIX" value="spring-boot-logback" />

<!-- 日志文件编码-->
<property name="LOG_CHARSET" value="UTF-8" />

<!-- 日志文件路径+日期-->
<property name="LOG_DIR" value="${LOG_HOME}/%d{yyyyMMdd}" />

<!-- 对日志进行格式化 -->
<!--控制台日志格式:彩色日志-->
<!-- magenta:洋红 -->
<!-- boldMagenta:粗红-->
<!-- cyan:青色 -->
<!-- white:白色 -->
<!-- magenta:洋红 -->
<!-- <property name="LOG_MSG" value="- | [%X{requestUUID}] | [%d{yyyyMMdd HH:mm:ss.SSS}] | [%level] | [${HOSTNAME}] | [%thread] | [%logger{36}] | &ndash;&gt; %msg|%n "/>-->
<property name="LOG_MSG" value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/>

<!--文件大小,默认10MB-->
<property name="MAX_FILE_SIZE" value="50MB" />

<!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
<property name="MAX_HISTORY" value="10"/>

<!--输出到控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 输出的日志内容格式化-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${LOG_MSG}</pattern>
</layout>
</appender>

<!--输出到文件-->
<appender name="0" class="ch.qos.logback.core.rolling.RollingFileAppender">
</appender>

<!-- 定义 ALL 日志的输出方式:-->
<appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志文件路径,日志文件名称-->
<File>${LOG_HOME}/all_${LOG_PREFIX}.log</File>

<!-- 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!--日志文件路径,新的 ALL 日志文件名称,“ i ” 是个变量 -->
<FileNamePattern>${LOG_DIR}/all_${LOG_PREFIX}%i.log</FileNamePattern>

<!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
<MaxHistory>${MAX_HISTORY}</MaxHistory>

<!--当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>

</rollingPolicy>

<!-- 输出的日志内容格式化-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${LOG_MSG}</pattern>
</layout>
</appender>

<!-- 定义 ERROR 日志的输出方式:-->
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 下面为配置只输出error级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<OnMismatch>DENY</OnMismatch>
<OnMatch>ACCEPT</OnMatch>
</filter>
<!--日志文件路径,日志文件名称-->
<File>${LOG_HOME}/err_${LOG_PREFIX}.log</File>

<!-- 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!--日志文件路径,新的 ERR 日志文件名称,“ i ” 是个变量 -->
<FileNamePattern>${LOG_DIR}/err_${LOG_PREFIX}%i.log</FileNamePattern>

<!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
<MaxHistory>${MAX_HISTORY}</MaxHistory>

<!--当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>

<!-- 输出的日志内容格式化-->
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${LOG_MSG}</Pattern>
</layout>
</appender>

<!-- additivity 设为false,则logger内容不附加至root ,配置以配置包下的所有类的日志的打印,级别是 ERROR-->
<logger name="org.springframework" level="ERROR" />
<logger name="org.apache.commons" level="ERROR" />
<logger name="org.apache.zookeeper" level="ERROR" />
<logger name="com.alibaba.dubbo.monitor" level="ERROR"/>
<logger name="com.alibaba.dubbo.remoting" level="ERROR" />

<!-- ${LOG_ROOT_LEVEL} 日志级别 -->
<root level="${LOG_ROOT_LEVEL}">

<!-- 标识这个"${STDOUT}"将会添加到这个logger -->
<appender-ref ref="${STDOUT}"/>

<!-- FILE_ALL 日志输出添加到 logger -->
<appender-ref ref="FILE_ALL"/>

<!-- FILE_ERROR 日志输出添加到 logger -->
<appender-ref ref="FILE_ERROR"/>
</root>

<!-- 开发环境和测试环境 -->
<springProfile name="dev,test">
<logger name="com.chen" level="INFO">
<appender-ref ref="STDOUT" />
</logger>
</springProfile>

<!-- 生产环境 -->
<springProfile name="prod">
<logger name="org.springframework.web" level="INFO"/>
<logger name="com.chen.springbootlogback" level="INFO"/>
<logger name="com.chen" level="ERROR">
<appender-ref ref="FILE_ERROR" /><!-- 采用err 滚动日志 -->
</logger>
<root level="DEBUG">
<appender-ref ref="FILE_ALL"/><!-- 采用全量 滚动日志 -->
</root>
</springProfile>
</configuration>