前言
在本系列《第四章:日志管理》中,由于工作中日志这块都是走默认配置,也没有深入了解过,因为部署过程中直接使用了
linux
中的输出重定向
功能,如java -jar xx.jar > app.log 2>&1 &
,直接输出到某个日志文件了。所以也就没有认真关心过默认的日志格式了。系列文章出来后,也看见有网友反馈说如何进行日志的相关配置,或者配置失效问题。本着负责的原则,本文就来详细介绍下SpringBoot
中日志管理相关配置问题。也是最近熟悉了下,有不足之处,还望指出!
一点知识
细说各日志框架整合配置前,我们先来大致了解下,最常见的日志的几个级别:ERROR
, WARN
, INFO
, DEBUG
和TRACE
。像其他的,比如ALL
、OFF
和FATAL
之类的开发过程中应该基本上是不会涉及的。所以以下从低到高一次介绍下常见的日志级别。
- TRACE:追踪。一般上对核心系统进行性能调试或者跟踪问题时有用,此级别很低,一般上是不开启的,开启后日志会很快就打满磁盘的。
- DEBUG:调试。这个大家应该不陌生了。开发过程中主要是打印记录一些运行信息之类的。
- INFO:信息。这个是最常见的了,大部分默认就是这个级别的日志。一般上记录了一些交互信息,一些请求参数等等。可方便定位问题,或者还原现场环境的时候使用。此日志相对来说是比较重要的。
- WARN:警告。这个一般上是记录潜在的可能会引发错误的信息。比如启动时,某某配置文件不存在或者某个参数未设置之类的。
- ERROR:错误。这个也是比较常见的,一般上是在捕获异常时输出,虽然发生了错误,但不影响系统的正常运行。但可能会导致系统出错或是宕机等。
如果将日志设置在某个等级,则比此级别高的都能打印出来。比如,设置了INFO
,那么ERROR
, WARN
等都能输出打印了,而DEBUG
、TRACE
等就被忽略了。
而为了能很好的对各日志框架的支持,开发过程中,一般上都是使用Commons Logging
或者SL4J
这些门面
日志工具。其底层封装了统一日志的操作,屏蔽了不同日志组件之间的差异。使得我们使用或者切换某个日志框架时,只需要引入相关的依赖包就可替换完毕,而无需去修改源码。其最后日志的实际操作还是由像log4j2
、logback
这些日志框架去实现的。
从前面章节,我们知道。SpringBoot
中,内部日志也是使用Commons Logging
,同时默认配置也提供了对常用日志的支持,如:Java Util Logging
,Log4J
, Log4J2
和Logback
。每种Logger
都可以通过配置使用控制台或者文件输出日志内容。
关于日志的自定义配置等相关知识点,这里就不阐述了,可直接移步《Spring Boot | 第四章:日志管理》了解。本章节主要就探讨下常用的log4j2
及logback
相关配置。
整合log4j2
log4j2
是log4j
的升级版本,号称比第一版具有更高的性能,当然现在也慢慢被logback
替代了。
配置依赖
0.移除SpringBoot默认的logback
依赖包。由于我们直接引入了spring-boot-starter-web
,所以直接排除了相应包。
题外话:真正引入spring-boot-starter-logging
包的是spring-boot-starter
依赖,所以我们也可以直接在spring-boot-starter
下排除即可。
1 | <!-- 排除logging --> |
或者
1 | <dependency> |
- 加入
log4j2
依赖。1
2
3
4
5<!-- 引入log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
配置文件
按官网的说明,默认是支持
XML
,JSON
,YAML
和properties
格式。
xml文件形式
按SpringBoot官网的说明,我们命名一个log4j2-spring.xml
文件作为默认的日志配置文件。
log4j2-spring.xml(本配置改造自:聊一聊log4j2配置文件log4j2.xml):
1 | <?xml version="1.0" encoding="UTF-8"?> |
我觉得这个配置步骤就是:先配置appenders
,按需求进行个性化配置,如按天记录等等,然后可以使用logger
个性化配置一些包的level
日志等级,最后配置下root
的appender
。
properties文件形式
从官网文档获悉,从2.4版本后才提供了通过配置文件的支持,这使用时要注意。详细使用语法可查看官网:Configuration with Properties,这里以官网的例子简单说明下:
1 | # log4j2内部自身的日志级别 |
此处需要额外设置配置文件属性值(logging.config
),本地测试时,就目录rolling
会生成文件,但里面是空的。加上后就正常了:1
logging.config=classpath:log4j2.properties
题外话:设置完,对properties配置规则还是不太了解。。感觉怎么配好像都可以输出,还望有网友能分享下具体的配置规则。对比完,还是觉得xml
格式比较直观也容易理解。
其他格式
按官网说明,还可以以
json
和yml
格式进行配合,但需要加入相应依赖。
格式 | 依赖包 | 文件名 |
---|---|---|
YAML | com.fasterxml.jackson.core:jackson-databind 、com.fasterxml.jackson.dataformat:jackson-dataformat-yaml |
log4j2.yaml 、log4j2.yml |
JSON | com.fasterxml.jackson.core:jackson-databind |
log4j2.json 、log4j2.jsn |
按需要添加相应依赖包即可。这里就不细说了。
格式化符号说明
对于格式化输出时,会看见有不同的格式化符号,起初看了也是一头雾水,下面搜索相关资料后进行简单整理归纳下。
题外话:SpringBoot
默认的log4j2配置文件在:spring-boot-1.5.15.RELEASE.jar/org/springframework/boot/logging/log4j2/log4j2.xml
。
具体官网有说明:http://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout
1 | ######### 常见参数 ######### |
多环境配置
可直接通过多环境配置文件,设置logging.config
的值,如
application-test.properties1
logging.config=classpath:log4j2-test-spring.xml
application-prod.properties1
logging.config=classpath:log4j2-prod-spring.xml
整合logback
logback
是由log4j创始人设计的又一个开源日志组件。同时也是SpringBoot
默认记录日志的框架。
xml形式
由于默认就是使用logback
,所以只需要配置一个logback-spring.xml
文件在resources
目录即可,会自动识别的。
logback-spring.xml(修改自: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
42
43
44
45<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
<property name="LOG_HOME" value="/home" />
<!-- 控制台输出 -->
<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"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/TestoKong.log.%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>
</encoder>
<!--日志文件最大的大小 -->
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 自定义包下设置为INFO,则可以看见输出的日志不包含debug输出了 -->
<logger name="cn.lqdev.learning" level="INFO" />
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
多环境配置:springProfile
使用扩展属性 springProfile
与 springProperty
让 logback-spring.xml
配置实现多环境配置的效果。
1 | <!-- 生产环境生效 --> |
springProfile
还支持读取Spring Environment
的属性值1
2
3
4
5
6
7<!-- 读取 spring.application.name 属性来生成日志文件名
scope:作用域
name:在 logback-spring.xml 使用的键
source:application.properties 文件中的键
defaultValue:默认值
-->
<springProperty scope="context" name="logName" source="spring.application.name" defaultValue="myapp.log"/>
之后就可以直接使用${logName}
获取到变量值了。
logback格式化符号说明
和
log4j2
类似,具体可去官网查看:PatternLayout。
- %m:输出代码中指定的消息
- %p:输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
- %r:输出自应用启动到输出该log信息耗费的毫秒数
- %c:输出所属的类目,通常就是所在类的全名
- %t:输出产生该日志事件的线程名
- %n:输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
- %d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH\:mm\:ss,SSS},输出类似:2002年10月18日 22:10:28,921
- %l:输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlogback.main(TestLogback.java:10)
题外话:SpringBoot
默认的logback配置文件在:spring-boot-1.5.15.RELEASE.jar/org/springframework/boot/logging/logback/defaults.xml
。
参考资料
关于详细属性配置,大家可以自行搜索下。以下是编写此文时,参考的一些网站信息。
https://docs.spring.io/spring-boot/docs/1.5.15.RELEASE/reference/htmlsingle/#boot-features-logging
http://logging.apache.org/log4j/2.x/manual/configuration.html
总结
本文主要是简单介绍了日志相关知识点,同时对于常用的
log4j2
和logback
相关配置进行了简单介绍。对于详细的配置信息,可去官网查阅下。另外,对于日志而言,不是越多越好,毕竟日志输出是会有性能损坏的。个人是建议,记录该记录的,保留事故现场的及一些错误都是需要进行日志记录的。而像一些无意义的输出,本身就是多余的。最后,不要随意打日志!打印日志时也注意不能用字符串拼接,需要使用占位符或者先判断日志级别!不要让日志拖慢了你的系统!下一章节,主要会介绍下利用AOP
实现统一的访问日志管理。
最后
目前互联网上很多大佬都有
SpringBoot
系列教程,如有雷同,请多多包涵了。本文是作者在电脑前一字一句敲的,每一步都是自己实践和理解的。若文中有所错误之处,还望提出,谢谢。
老生常谈
- 个人QQ:
499452441
- 微信公众号:
lqdevOps
个人博客:http://blog.lqdev.cn
完整示例:https://github.com/xie19900123/spring-boot-learning/tree/master/chapter-23