这里是一个学习过程笔记的汇总:Spring Boot学习汇总
讲Spring Boot日志管理前,先看看目前有哪些常用的日志框架吧。
我们熟悉的应该有:log4j, log4j2, logback, slf4j, 还有不太熟悉的,JUL, JCL, Jboss-logging...
具体的资料可以百度看一下。
这些日志框架可以分为两大类,一类是日志门面,一类是日志实现,看字面意思大概就能明白了,日志门面得依靠日志实现,搭配干活。具体分类如下:
日志门面 | 日志实现 |
JCL(Jakarta Commons Logging), slf4j(Simple Logging Facade for Java), jboss-logging |
Log4j, JUL(java.util.logging) Log4j2, Logback |
1、Spring Boot 中的默认日志依赖
Spring Boot框架默认的日志门面是:slf4j, 默认的日志实现是:logback
默认的日志实现的jar都已经封装好了,在spring-boot-starter.jar包中,这个前面讲过,springboot中会有一系列的spring-boot-starter开头的jar包(场景启动器),适用于不同的场景,而spring-boot-starter包就是所有的starter的父依赖,所以你导入任何一个场景启动器,默认的日志实现就导入进来了。
快速创建一个Spring Boot项目,只导入一个web模块(就是导入spring-boot-starter-web.jar)。
然后打开pom.xml文件,操作如下:
此操作可以看一下项目中的pom依赖关系图,如下是我们刚创建的项目依赖关系,默认的日志依赖一目了然:
2、聊聊slf4j
百度百科解释:
SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志System。
可以看到上面的jar依赖图,倒数第二层,有logback-classic, jul-to-slf4j, log4j-to-slf4j。这三个jar包是将其他的日志框架转为slf4j, 相当于日志实现和日志门面的一个中间转换,即将不同的日志实现框架,使用相应的中间转换jar包,最终转换为slf4j,但底层的实现还是具体的日志框架。
可以看下slf4j官网:slf4j官网
3、具体配置
刚创建好的SpringBoot项目,启动时就可以看到控制台有日志输出。这说明都有默认的日志配置。
项目中使用日志输出很简单,只需要如下一行代码即可:
private final Logger logger = LoggerFactory.getLogger(this.getClass());
那么具体的输出日志格式怎么配置呢?还有日志级别怎么设置?
3.1、先看日志级别设置
日志级别一共五种,从低到高: trace<debug<info<warn<error
设置日志输出级别后,日志就只从设置的级别往更高的级别输出
先不做任何设置,输出五个级别:
@RestController
@RequestMapping("/hello")
public class HelloController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping("/sayHello")
public void sayHello(@RequestParam("name") String name) {
logger.trace("trace级别日志");
logger.debug("debug级别日志");
logger.info("info级别日志");
logger.warn("warn级别日志");
logger.error("error级别日志");
}
}
控制台:
只输出info, warn, error级别的日志,这说明spring boot 的默认日志级别是info。
然后再主配置文件设置日志输出级别为trace
spring.profiles.active=dev
# 设置日志级别(xxx为包名)
logging.level.com.xxx=trace
重启,运行,看控制台:
五个级别都输出,说明修改成功。
3.2、再看输出格式
先写个例子看一下:
package com.xxx.demo.controller;
import com.xxx.demo.service.HelloService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author pavel
* @date 2018/11/10
*/
@RestController
@RequestMapping("/hello")
public class HelloController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private HelloService helloService;
@RequestMapping("/sayHello")
public String sayHello(@RequestParam("name") String name) {
logger.info("==== say hello to {} ==== ", name);
return helloService.sayHello(name);
}
}
访问后控制台输出:
2018-11-10 18:05:00.715 INFO 20968 --- [nio-8092-exec-4] c.e.demo.controller.HelloController : ==== say hello to curry ====
这个是默认的输出格式,可以在下面jar包中的这几个文件看到默认的输出格式是怎么配置的:
下面我们来改一下这些输出格式:
spring.profiles.active=dev
# 设置日志级别
logging.level.com.xxx=trace
# 设置控制台日志输出格式 日期(年月日) 线程名 日志级别 logger类信息 日志消息
logging.pattern.console=%date{yyyy-MM-dd} [%thread] %-5level %logger{36} - %msg%n
输出格式为:
2018-11-10 [http-nio-8091-exec-1] INFO c.e.demo.controller.HelloController - ==== say hello to curry ====
对比着看一下,日期格式不一样了吧
具体的格式如下,可以自己试着改,然后看控制台输出:
符号 | 含义 |
%d(yyyy-MM-dd) | 日期(日期格式) |
%thread | 线程名 |
%-5level | 级别从左显示五个宽度 |
%logger{36} | logger的名字(36指具体的全类名打印长度) |
%msg | 打印的日志消息 |
%n | 换行 |
3.3、说说日志输出到文件
如下配置:
spring.profiles.active=dev
# 设置日志输出到文件:
logging.file=logs/springboot.log
日志便输出到如下路径,没有目录的会自行创建
如果不指定文件名称的话,会默认生成一个名为的spring.log文件。
4、多环境配置
日志也支持profile配置,不同环境,日志文件内容有些不同,比入说开发环境和生产环境的日志文件保存路径不同。日志多profile配置是建立在总配置文件的多profile配置下的。
如下,resources文件夹下创建log文件夹,并创建三个文件,分别对应:
开发(logback-spring-dev.xml),
测试(logback-spring-test.xml),
生产(logback-spring-prod.xml),
文件命名尽量带有 dev, test, prod标识,比较好区分。
然后写上一些内容,这里先配置简单一些,做个测试,将dev环境的日志输出时间格式设置为:年月日时分秒
,test环境的日志输出时间格式设置为:年月日
修改配置文件:
application-dev.properties(开发环境),加上如下代码:
application-test.properties(测试环境), 加上如下代码:
测试:
修改总配置文件,激活开发环境配置文件:
启动项目,控制台输出:
日志输出日期格式 为 年月日时分秒
再激活测试环境配置文件:
启动项目,控制台输出:
日志输出日期格式为 年月日
可见,配置生效。
5、配置文件详解
现在来聊聊日志配置文件的内容,如下。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志路径 -->
<property name="logDir" value="/opt/logs/dev"/>
<!-- 控制台日志输出-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<!--滚动日志 -->
<appender name="rollingFileApp" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 一个总的日志文件-->
<file>${logDir}/demo.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志存储路径
%d: 日期
%i: 日志文件累加,从0开始
举例(2018-11-12的日志文件名称):
demo.2018-11-12.0.log
demo.2018-11-12.1.log
demo.2018-11-12.2.log -->
<fileNamePattern>${logDir}/demo.%d.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- 滚动日志文件最大大小,当天日志达到这个大小后,会自动以上面格式生成下一个日志文件-->
<maxFileSize>1 MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<!-- logger:
用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。
<loger>仅有一个name属性,一个可选的level和一个可选的addtivity属性。
name:用来指定受此loger约束的某一个包或者具体的某一个类。
level:用来设置打印级别(日志级别),大小写无关; TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。
addtivity:是否向上级loger传递打印信息。默认是true。
-->
<logger name="com.xxx" level="DEBUG" />
<!-- root:
也是<loger>元素,但是它是根loger。只有一个level属性,应为已经被命名为"root".
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。默认是DEBUG。
<root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。
-->
<root level="INFO">
<!-- 控制台-->
<appender-ref ref="console" />
<!-- 滚动日志-->
<appender-ref ref="rollingFileApp" />
</root>
</configuration>
没得聊了,可以聊的都写在上面的配置文件的相应注释了。还有不清楚的可以百度下。
6、日志框架切换
Spring Boot默认用的是logback实现,那我要是想切换到log4j实现怎么搞呢?
先在pom.xml文件上右键-->diagrams-->show dependencies打开依赖关系图
找到logback-classic和logback-core分别右键Exclude,排除掉这两个依赖,因为slf4j同时只能有一个实现,我们要使用log4j实现就必须先排除logback,不然会报错,冲突。
然后在pom文件中引入如下jar包:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
这个包是链接slf4j-api和log4j中间的适配器,加上之后,slf4j就会使用log4j实现日志的输出记载。
然后在resources文件夹下创建一个简单的log4j.properties配置文件,如下(日期格式精确到分):
### 配置根 ###
log4j.rootLogger = debug,console
### 配置输出到控制台 ###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm} %5p %c{1}:%L - %m%n
启动,控制台输出:
切换其他日志框架也是一样,总之slf4j同一时间只能有一个实现的框架,切换之前,先把之前的实现框架去掉。可以自己尝试一下。
好了,Spring Boot日志配置就是这么多了,后期有想到其他的再更上来。