Spring Boot 支持的日志框架有 Java Util Logging、Log4J2、Logback,默认使用 Logback。
配置方式有默认配置文件配置和引用外部配置文件配置。
默认配置文件配置
默认配置文件配置不建议使用,不够灵活,对 Log4j2 等支持不够友好。
控制台输出
日志级别从低到高分为 TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为 WARN,则低于 WARN 的信息都不会输出。 Spring Boot 中默认配置 ERROR、WARN 和 INFO 级别的日志输出到控制台。您还可以通过启动您的应用程序 –debug 标志来启用“调试”模式(开发的时候推荐开启),以下两种方式皆可:
- 在运行命令后加入 —debug 标志,如:$ java -jar springTest.jar —debug
- 在 application.properties 中配置 debug=true,该属性置为 true 的时候,核心 Logger(包含嵌入式容器、hibernate、spring)会输出更多内容,但是你自己应用的日志并不会输出为 DEBUG 级别。
文件输出
默认情况下,Spring Boot 将日志输出到控制台,不会写到日志文件。如果要编写除控制台输出之外的日志文件,则需在 application.properties 中设置 logging.file 或 logging.path 属性。
- logging.file,设置文件,可以是绝对路径,也可以是相对路径。比如:logging.file=my.log,或者是 /var/log/my.log
- logging.path,设置目录,会在该目录下创建 spring.log 文件,并写入日志内容,如:logging.path=/var/log
如果只配置 logging.file,会在项目的当前路径下生成一个 xxx.log 日志文件。
如果只配置 logging.path,在 /var/log 文件夹生成一个日志文件为 spring.log。
注意:二者不能同时使用,如若同时使用,则只有 logging.file 生效。
默认情况下,日志文件的大小达到10MB时会切分一次,产生新的日志文件,默认级别为:ERROR、WARN、INFO。
日志级别
在全局配置文件中设置日志级别,格式为:’logging.level.* = LEVEL’
- logging.level:日志级别控制前缀,*为包名或类名;
- LEVEL:选项 TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF;
举例:
- logging.level.com.dudu=DEBUG:com.dudu包下所有的 class 以 DEBUG 级别输出;
- logging.level.root=WARN:root 日志以 WARN 级别输出;
引用外部配置文件
根据不同的日志系统,你可以按如下规则组织配置文件名,就能被正确加载:
- Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy;
- Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml;
- Log4j2:log4j2-spring.xml, log4j2.xml;
- JDK (Java Util Logging):logging.properties;
Spring Boot 官方推荐优先使用带有 -spring 的文件名作为你的日志配置(如使用 logback-spring.xml,而不是 logback.xml),命名为 logback-spring.xml 的日志配置文件,spring boot 可以为它添加一些 spring boot 特有的配置项(下面会提到)。上面是默认的命名规则,并且放在 src/main/resources下面即可。
如果你即想完全掌控日志配置,但又不想用 logback-spring.xml 作为 Logback 配置的名字,可以通过 logging.config 属性指定自定义的名字:
logging.config=classpath:logging-config.xml
比如我们要打印控制台日志信息,根据日期和大小分割生成日志文件。
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>rabbit</contextName>
<!--application.yml传递参数 -->
<springProperty name="LOGGING_PATH" source="logging.path" />
<springProperty name="LOGGING_LEVEL" source="logging.level" />
<!-- 引入Spring Boot默认配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<!-- 输出到控制台 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 输出到文件,根据日期、大小生成日志文件 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOGGING_PATH}/rabbit-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<!-- 每个文件最大 50MB,保留7天历史文件,所有最多10GB -->
<maxFileSize>50MB</maxFileSize>
<maxHistory>7</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="${LOGGING_LEVEL}">
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
<!-- logback为java中的包 -->
<logger name="com.yjw.rabbit.biz.controller" />
<!--logback.LogbackDemo:类的全路径 -->
<logger name="com.yjw.rabbit.biz.controller.ExamController" level="WARN" additivity="false">
<appender-ref ref="console" />
</logger>
</configuration>
application-dev.yml
#日志配置
logging:
path: ./log
level:
ROOT: DEBUG
com.yjw.rabbit.biz.controller: ERROR
LOGGING_PATH 和 LOGGING_LEVEL 都是通过 application-dev.yml 配置。
根节点 包含的属性
- scan:当此属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认值为 true;
- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当 scan 为 true 时,此属性生效。默认的时间间隔为1分钟;
- debug:当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback 运行状态。默认值为 false;
根节点 configuration 的子节点:
configuration 下面一共有2个属性,3个子节点,分别是:
属性一:设置上下文名称
每个 logger 都关联到 logger 上下文,默认上下文名称为“default”。但可以使用设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改,可以通过
<contextName>logback</contextName>
属性二:设置变量
用来定义变量值的标签, 有两个属性,name 和 value;其中 name 的值是变量的名称,value 的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
这里使用了 springProperty,可以从 Spring Boot 的配置文件 application-dev.yml 中获取属性值,这样日志的部分属性就可以通过 application-dev.yml 统一配置了。
子节点一
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
- %d{HH: mm:ss.SSS}:日志输出时间
- %thread:输出日志的进程名字,这在 Web 应用以及异步任务处理中很有用
- %-5level:日志级别,并且使用5个字符靠左对齐
- %logger{36}:日志输出者的名字
- %msg:日志消息
- %n:平台的换行符
ThresholdFilter 为 logback 定义的拦截器,例如我们用 ThresholdFilter 来过滤掉 ERROR 级别以下的日志不输出到控制台中。如果不用记得注释掉,不然你控制台会发现没日志。
输出到文件
另一种常见的日志输出到文件,随着应用的运行时间越来越长,日志也会增长的越来越多,将他们输出到同一个文件并非一个好办法。RollingFileAppender 用于切分文件日志:
<!-- 输出到文件,根据日期、大小生成日志文件 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOGGING_PATH}/rabbit-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 每个文件最大 50MB,保留7天历史文件,所有最多10GB -->
<maxFileSize>50MB</maxFileSize>
<maxHistory>7</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
其中重要的是
如果你想把日志直接放到当前项目下,把 ${LOGGING_PATH}/ 去掉即可。
子节点二
root 节点是必选节点,用来指定最基础的日志输出级别,只有一个 level 属性。
- level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为 INHERITED 或者同义词 NULL。默认是 DEBUG。
可以包含零个或多个元素,标识这个 appender 将会添加到这个 logger。
<root level="${LOGGING_LEVEL}">
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
子节点三
<!-- logback为java中的包 -->
<logger name="com.rabbit.biz.controller" />
<!--logback.LogbackDemo:类的全路径 -->
<logger name="com.rabbit.biz.controller.ExamController" level="WARN" additivity="false">
<appender-ref ref="console" />
</logger>
- name:用来指定受此 logger 约束的某一个包或者具体的某一个类;
- level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特殊值 INHERITED 或者同义词 NULL,代表强制执行上级的级别。如果未设置此属性,那么当前 logger 将会继承上级的级别;
- addtivity:是否向上级 logger 传递打印信息,默认是 true;
第一种:带有 logger 的配置,不指定级别,不指定 appender
<logger name="com.rabbit.biz.controller" />
- 将控制 controller 包下的所有类的日志的打印,但是并没用设置打印级别,所以继承他的上级的日志级别“info”;
- 没有设置 addtivity,默认为 true,将此 logger 的打印信息向上级传递;
- 没有设置 appender,此 logger 本身不打印任何信息。
第二种:带有多个 logger 的配置,指定级别,指定 appender
<!--logback.LogbackDemo:类的全路径 -->
<logger name="com.rabbit.biz.controller.ExamController" level="WARN" additivity="false">
<appender-ref ref="console" />
</logger>
- 控制 com.rabbit.biz.controller.ExamController 类的日志打印,打印级别为“WARN”;
- additivity 属性为 false,表示此 logger 的打印信息不再向上级传递;
- 指定了名字为“console”的 appender;
如果你把 additivity=”false” 改成 additivity=”true” 的话,就会打印两次,因为打印信息向上级传递,logger 本身打印一次,root 接到后又打印一次。
注意:使用 mybatis 的时候,sql 语句是 debug 下才会打印,而这里我们只配置了 info,所以想要查看 sql 语句的话,有以下两种操作:
- 第一种把
改成 这样就会打印 sql,不过这样日志那边会出现很多其他消息。 - 第二种就是单独给 dao 下目录配置 debug 模式,代码如下,这样配置 sql 语句会打印,其他还是正常 info 级别。
<logger name="com.rabbit.biz.dao" level="DEBUG" additivity="false">
<appender-ref ref="console" />
</logger>
多环境日志输出
据不同环境(prod:生产环境,test:测试环境,dev:开发环境)来定义不同的日志输出,在 logback-spring.xml 中使用 springProfile 节点来定义,方法如下:
文件名称不是 logback.xml,想使用 spring 扩展 profile 支持,要以 logback-spring.xml 命名
<!-- 测试环境+开发环境. 多个使用逗号隔开. -->
<springProfile name="test,dev">
<logger name="com.rabbit.biz.controller" level="info" />
</springProfile>
<!-- 生产环境. -->
<springProfile name="prod">
<logger name="com.rabbit.biz.controller" level="ERROR" />
</springProfile>
可以启动服务的时候指定 profile (如不指定使用默认),如指定prod 的方式为:
java -jar xxx.jar –spring.profiles.active=prod
总结
推荐引用外部配置文件的方式来配置项目,代码中使用日志也很简单,在类里面添加如下代码:
private Logger logger = LoggerFactory.getLogger(this.getClass());