参考:
SpringBoot官方教程
http://blog.didispace.com/springbootlog/
http://www.mkyong.com/spring-boot/spring-boot-slf4j-logging-example/
1 SpringBoot内置日志系统
SpringBoot
对所有内部日志的记录使用的是Commons Logging
,但是它的底层日志实现是开放的,并对常用的日志系统进行了支持,例如Java Util Logging
,Log4J2
,Logback
。每种日志都可以进行配置,选择控制台或文件输出日志内容。
默认的,当你使用了Starters
,Logback
被用来记录日志。并且还包括了适当的Logback
路由,使得其他的日志系统例如Java Util Logging
,Commons Logging
,Log4J
或者SLF4J
能够正常的工作。
注:
这里的“
Starters
”表示的是在项目中引入的那些官方"starter
",在这些“starter
”中,SpringBoot
默认引入了spring-boot-starter
,而在spring-boot-starter
中又默认引入了spring-boot-starter-logging
,在spring-boot-starter-logging
中引入logback-classic
依赖。
1.1 日志的输出格式
默认的日志输出样式如下:
2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
输出内容的元素的含义:
- 日期和时间:精确到毫秒,方便排序。
- 日志级别:
ERROR
,WARN
,INFO
,DEBUG
orTRACE
。 - 进程ID
- 分隔符:
---
分隔符,标识日志内容的开始。 - 线程名:方括号括起来(控制台输出时可能会截断)。
- Logger名:通常是使用logger的类名(有时是简写)。
- 日志内容
Logback
没有FATAL
级别,被写入到ERROR
中。
1.2 日志输出到控制台
SpringBoot
中默认是将日志输出到控制台,默认输出ERROR
,WARN
,INFO
级别的日志。
可以通过两种方式开启DEBUG
日志:
- 添加
--debug
标志
$ java -jar myapp.jar --debug
- 在
application.properties
文件中配置debug=true
,该属性置为true
的时候,核心Logger
(包含嵌入式容器、hibernate、spring)会输出更多内容,但是你自己应用的日志并不会输出为DEBUG
级别。
debug=true
1.2.1 在控制台输出彩色的日志
如果你的终端支持ANSI
,可以将日志设置为彩色的输出样式,增强可读性。可以通过在application.properties
中设置spring.output.ansi.enabled
参数来提供彩色输出的支持,可选的参数值为:
NEVER
:禁用ANSI
彩色输出(默认设置)DETECT
:会检测终端是否支持ANSI
,如果支持则开启彩色输出(推荐)ALWAYS
:总是开启彩色输出,如果终端不支持,会输出很多干扰信息(不推荐)
下表展示了不同日志级别所对应的输出颜色:
日志级别 | 颜色 |
---|---|
FATAL |
Red |
ERROR |
Red |
WARN |
Yellow |
INFO |
Green |
DEBUG |
Green |
TRACE |
Green |
或者,也可以通过使用%clr
来指定文本的颜色,例如:
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}
下面是支持的颜色:
blue
cyan
faint
green
magenta
red
yellow
1.3 日志数输出到文件
SpringBoot
默认只配置了将日志输出到控制台,并不会写入到文件中。
如果需要增加将日志输出到文件中,需要在application.properties
中配置logging.file
或logging.path
属性。
logging.file |
logging.path |
例子 | 说明 |
---|---|---|---|
(none) | (none) | 日志只会输出到控制台 | |
指定文件 | (none) | my.log |
将日志输出到指定文件。可以是绝对路径或者相对路径。 |
(none) | 指定文件夹 | /var/log |
设置一个文件夹路径,会在该文件夹下面创建一个spring.log 文件记录日志。可以使绝对路径或者相对路径。 |
输出到文件的日志和控制台的级别保持一致,默认级别为ERROR
、WARN
、INFO
。日志文件达到10MB
时会被截断然后被存档,可以通过设置logging.file.max-size
来指定超过多大会被存档,也可以设置logging.file.max-history
来指定被存档的文件的个数。
1.4 日志级别控制
在Spring Boot
中只需要在application.properties
中进行配置,就能对日志记录的级别进行控制。
配置的格式为:logging.level.<logger-name>=<level>
- 可选的
<level>
:TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF 。 root
日志可以通过设置logging.level.root
来控制。
例如:
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
1.5 日志分组
可以对日志进行分组,这样可以一次性管理一个组的日志。
可以通过logging.group.<group-name>
来设置日志组和组内的成员:
logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat
一旦定义了上边的用户组,可以配置该组的日志级别:
logging.level.tomcat=TRACE
SpringBoot
默认提供了两个预定义的日志组,可以直接使用:
group-name | logger-name |
---|---|
web | org.springframework.core.codec , org.springframework.http , org.springframework.web |
sql | org.springframework.jdbc.core , org.hibernate.SQL |
1.6 自定义日志配置
由于日志服务一般都在ApplicationContext
创建前就初始化了,它并不是必须通过Spring
的配置文件控制。因此通过系统属性和传统的Spring Boot
外部配置文件依然可以很好的支持日志控制和管理。
根据不同的日志系统,你可以按如下规则组织配置文件名,就能被正确加载:
日志系统 | 配置文件(放在classpath下面) |
---|---|
Logback | logback-spring.xml , logback-spring.groovy , logback.xml , 或者 logback.groovy |
Log4j2 | log4j2-spring.xml 或者 log4j2.xml |
JDK (Java Util Logging) | logging.properties |
Spring Boot
官方推荐优先使用带有-spring
的文件名作为你的日志配置(如使用logback-spring.xml
,而不是logback.xml
)。
2 集成Logback配置
以前在使用Spring
框架的时候,我们通常可以在resources
目录下创建一个logback.xml
配置文件来自定义Logback
的输出。
在SpringBoot
中要想进行同样的设置,应该怎么做呢?
2.1 配置logback-spring.xml
首先,在resources
下面创建一个logback-spring.xml
文件,然后和之前的项目一样进行配置。我们可以通过<springProfile>
标签同时配置开发环境和生产环境的日志输出。
- 如果
profile
是dev
,日志同时输出到控制台和文件中。 - 如果
profile
是prod
,输出到文件中。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 说明: 1、日志级别及文件 日志记录采用分级记录,级别与日志文件名相对应,不同级别的日志信息记录到不同的日志文件中 例如:error级别记录到log.error.xxx.log或log.error.log(该文件为当前记录的日志文件),而log.error.xxx.log为归档日志,
日志文件按日期记录,同一天内,若日志文件大小等于或大于10M,则按0、1、2...顺序分别命名 例如log-level-2013-12-21.0.log
其它级别的日志也是如此。 2、文件路径 若开发、测试用,在Eclipse中运行项目,则到Eclipse的安装路径查找logs文件夹. 若部署到Tomcat下,则在Tomcat下的logs文件中.
${catalina.base}能够取到项目部署时候的tomcat目录。 3、Appender FILE-ERROR对应error级别,文件名以log.error.xxx.log形式命名
FILE-WARN对应warn级别,文件名以log.warn.xxx.log形式命名 FILE-INFO对应info级别,文件名以log.info.xxx.log形式命名
FILE-DEBUG对应debug级别,文件名以log.debug.xxx.log形式命名 STDOUT将日志信息输出到控制台上,为方便开发测试使用 -->
<!-- scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true. scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒.当scan为true时,此属性生效。默认的时间间隔为1分钟.
debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 在Eclipse中运行,请到Eclipse的安装目录中找log文件,Tomcat下,请到Tomcat目录下找 -->
<property name="LOG_PATH" value="${catalina.base}/logs"/>
<!-- 项目名称 -->
<property name="PROJECT_NAME" value="app"/>
<!-- 控制台打印日志的配置 -->
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level ${PROJECT_NAME} [%thread] [%logger{50}:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!-- 配置输出到文件,配置DEBUG, INFO, WARN, ERROR 日志的Appender -->
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${PROJECT_NAME}/${PROJECT_NAME}.log.error.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定, 可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${PROJECT_NAME}/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过10M,若超过10M,日志文件会以索引0开始, 命名日志文件,例如log-error-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
<!-- 日志文件保留天数 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志打印的格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level ${PROJECT_NAME} [%thread] [%logger{50}:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录error级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILE-WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${PROJECT_NAME}/${PROJECT_NAME}.log.warn.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定, 可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${PROJECT_NAME}/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过10M,若超过10M,日志文件会以索引0开始, 命名日志文件,例如log-warn-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
<!-- 日志文件保留天数 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志打印的格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level ${PROJECT_NAME} [%thread] [%logger{50}:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录warn级别,不记录大于warn级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILE-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${PROJECT_NAME}/${PROJECT_NAME}.log.info.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定, 可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${PROJECT_NAME}/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过10M,若超过10M,日志文件会以索引0开始, 命名日志文件,例如log-info-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
<!-- 日志文件保留天数 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志打印的格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level ${PROJECT_NAME} [%thread] [%logger{50}:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别,不记录大于info级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILE-DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${PROJECT_NAME}/${PROJECT_NAME}.log.debug.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定, 可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${PROJECT_NAME}/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过10M,若超过10M,日志文件会以索引0开始, 命名日志文件,例如log-debug-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
<!-- 日志文件保留天数 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志打印的格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level ${PROJECT_NAME} [%thread] [%logger{50}:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录debug级别,不记录大于debug级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- SPRING等框架类代码日志打印, 输出到OTHER文件中, 出厂默认WARN以上 -->
<appender name="OTHER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 此日志文件只记录warn级别及其以上的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<!-- 正在记录的日志文件的路径及文件名 -->
<File>${LOG_PATH}/${PROJECT_NAME}/${PROJECT_NAME}.log.other.log</File>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定, 可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${PROJECT_NAME}/log-other-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过10M,若超过10M,日志文件会以索引0开始, 命名日志文件,例如log-debug-2013-12-21.0.log -->
<maxFileSize>35MB</maxFileSize>
<!-- 日志文件保留天数 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志打印的格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %level ${PROJECT_NAME} [%thread] [%logger{50}:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!-- 开发环境 -->
<springProfile name="dev">
<!-- 出厂默认输出level级别INFO, 排查问题时, 可以通过工具切换为TRACE. 自定义模块日志打印 添加在后面. name需要修改为自己项目中的合适的package -->
<logger name="com.tao.myproject" level="DEBUG" additivity="false">
<appender-ref ref="FILE-ERROR"/>
<appender-ref ref="FILE-WARN"/>
<appender-ref ref="FILE-INFO"/>
<appender-ref ref="FILE-DEBUG"/>
<!-- 控制台输出 -->
<appender-ref ref="STDOUT"/>
</logger>
<!-- 其他的warn级别及其以上的日志,通过OTHER来记录 -->
<root level="WARN">
<appender-ref ref="OTHER"/>
</root>
</springProfile>
<!-- 生产环境 -->
<springProfile name="prod">
<!-- 出厂默认输出level级别INFO, 排查问题时, 可以通过工具切换为TRACE. 自定义模块日志打印 添加在后面. name需要修改为自己项目中的合适的package -->
<logger name="com.tao.myproject" level="DEBUG" additivity="false">
<appender-ref ref="FILE-ERROR"/>
<appender-ref ref="FILE-WARN"/>
<appender-ref ref="FILE-INFO"/>
<appender-ref ref="FILE-DEBUG"/>
</logger>
<!-- 其他的warn级别及其以上的日志,通过OTHER来记录 -->
<root level="WARN">
<appender-ref ref="OTHER"/>
</root>
</springProfile>
</configuration>
2.2 配置spring.profiles.active
然后,在application.properties
中指定是dev
还是prod
环境:
# 指定环境,dev或prod
spring.profiles.active=dev
2.3 打包项目为war包运行于外部tomcat容器
最后,不应该让项目以默认的嵌入式tomcat
容器运行,可以根据这个 教程 配置为常规的web
项目,部署到外部tomcat容器中。