目录
为什么 Logger 对象声明 private static final
Spring Boot 日志依赖关系
Spring boot 官网文档:boot-features-logging
1、Sping-boot-starter 是Spring Boot 启动器,每一个 Spring boot 应用都会依赖到它
2、Sping-boot-starter 依赖 Sping-boot-starter-looging
3、Spring Boot 底层默认使用 slf4j+logback 的方式进行日志记录
4、Spring Boot 使用中间替换包把其的日志框架都替换成了slf4j;
5、所以开发中如果要引入其他框架,则一定要把这个框架的默认日志依赖移除掉,否则会起冲突。如 Spring 框架默认用的是commons-logging;而 Spring Boot 底层用的就是Spring ,所以自己也要移除掉Spring 的日志框架:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring‐core</artifactId>
<exclusions>
<exclusion>
<groupId>commons‐logging</groupId>
<artifactId>commons‐logging</artifactId>
</exclusion>
</exclusion
6、总而言之:Spring Boot 能自动适配所有的日志框架,且底层使用 slf4j+logback 的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可;
Spring boot 全局日志设置
1、日志的级别由低到高分别为:trace(跟踪) < debug(调试) < info(信息) < warn(警告) < error(错误)
2、在配置文件中调整输出的日志级别,日志就只会在这个级别及以后的高级别生效,Spring Boot 默认使用 info 级别。
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Date;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CocoApplicationTests {
//获取日志记录器
private static Logger logger = LoggerFactory.getLogger(CocoApplicationTests.class);
@Test
public void contextLoads() {
logger.trace("这是 trace 日志...");
logger.debug("这是 debug 日志...");
logger.info("这是 info 日志...");
logger.warn("这是 warn 日志...");
logger.error("这是 error 日志...");
}
}
3、Spring Boot 的全局配置文件 "application.properties"或者"application.yml" 中可以修改日志配置项:
# 指定特定包下面所有类的日志输出级别,未指定的仍然按Spring Boot的默认级别 info 输出.
logging.level.com.lct=debug
#表示在当前项目根目录下生成app.log日志文件,可以是绝对路径或者相对路径,如 logging.file: logs/app.txt
logging.file=app.log
# 在项目根路径下创建spring/log目录,然后使用 spring.log 作为默认日志文件,可以使用绝对或者相对路径
# 当 logging.path 与 logging.file 同时配置时,则以 logging.file 为准,logging.path 此时不再生效
logging.path=spring/log
# 指定控制台输出的日志格式,如:
# %d{yyyy-MM-dd HH:mm:ss} -- [%thread] %-5level %logger{50} %msg%n
# 1、%d 表示日期时间,
# 2、%thread 表示线程名,
# 3、%‐5level 级别从左显示5个字符宽度
# 4、%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
# 5、%msg 日志消息,
# 6、%n 换行符
# 7、%line 显示日志输出位置的行号,方便寻找位置
logging:
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{50}:%line %msg%n'
logging.pattern.file=%d{yyyy-MM-dd HH:mm} -- [%thread] %-5level %logger{50} %msg%n
1、默认情况下,日志文件超过10M 时,会新建文件进行递增,比如 spring.log、spring1.log、spring2.log.....,可以使用
logging.file.max-size
更改大小限制。2、默认情况下,日志只记录到控制台,不写入日志文件,如果要在控制台输出之外写入到日志文件,则需要设置 logging.file 或 logging.path 属性。
6、Spring boot 官网 日志全部配置项:
# LOGGING
logging.config= # Location of the logging configuration file. For instance, `classpath:logback.xml` for Logback.
logging.exception-conversion-word=%wEx # Conversion word used when logging exceptions.
logging.file= # 日志文件名(例如"app.log"). 名称可以绝对路径或者相对路径
logging.file.max-history=0 # Maximum of archive log files to keep. Only supported with the default logback setup.
logging.file.max-size=10MB # Maximum log file size. Only supported with the default logback setup.
logging.level.*= # 指定特定包下面所有类的日志输出级别,未指定的仍然按Spring Boot的默认级别 info 输出.如 logging.level.org.springframework=DEBUG.
logging.path= # 日志文件的位置。例如,`/var/log`,与 logging.file 同时存在时,以 logging.file 优先.
logging.pattern.console= # 用于输出到控制台的追加器模式。仅支持默认的日志恢复设置。
logging.pattern.dateformat=yyyy-MM-dd HH:mm:ss.SSS # Appender pattern for log date format. Supported only with the default Logback setup.
logging.pattern.file= #用于输出到文件的追加器模式。仅支持默认的日志恢复设置。
logging.pattern.level=%5p # Appender pattern for log level. Supported only with the default Logback setup.
logging.register-shutdown-hook=false # Register a shutdown hook for the logging system when it is initialized.
全局配置中的日志配置优先级高于第三方日志框架配置文件!
7、这些配置是非常有用的,比如命令行启动一个 jar 包,但是它一执行就自动报错,然后退出了,都来不急看清错误信息,此时则可以拷贝出它的配置文件(如 application.yml),然后加上一句:logging.file: logs/app.txt,表示在当前目录下生成日志文件,接着再次启动时,错误信息就会自动存放进去。
Spring boot Log Levels 日志级别
1、通过配置 logging.level.<logger name>=<level> 可以设置所有受支持的日志系统的日志级别,其中 level 是 ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF 之一。官网 26.4 Log Levels。
2、可以使用 logging.level.root 配置根日志记录器:
logging.level.root=WARN #根节点日志级别,即整个应用的日志级别设置,默认为 info
logging.level.org.springframework.web=DEBUG #单独某个包的日志级别设置,spring web 包日志输出级别
logging.level.org.hibernate=ERROR # 单独某个包的日志级别设置,hibernate 日志输出级别
logging.level.com.wmx=info #自己项目中指定包下的日志输出级别
#未特别指定的仍然按 Spring Boot 的默认的 logging.level.root 设置输出.
Spring boot Log Groups 日志记录器组
1、将相关的记录器组合在一起,以便可以同时对它们进行配置,这通常是很有用的。Spring Boot 允许在 Spring 环境中定义日志组。例如下面通过将 “tomcat” 组添加到 application.properties 中来定义它:
logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat
2、定义后,可以用一行更改组中所有记录器的级别:logging.level.tomcat=TRACE
3、Spring Boot 包括以下预定义的日志记录组,可以开箱即用:
Name | Loggers |
---|---|
web |
|
sql |
|
Logback 日志配置文件详解
1、可以直接在 Spring Boot 的全局配置文件中修改 slf4j 的默认配置,也可以使用 slf4j 实现框架的自己的配置文件。直接放置再类路径下即可,
2、官网参考链接,根据日志记录系统的不同,各自的配置文件文件也不同:
Logging System(日志系统) | Customization(日志文件名称) |
---|---|
Logback | logback-spring.xml , logback-spring.groovy , logback.xml or logback.groovy |
Log4j2 | log4j2-spring.xml,log4j2.xml |
JDK (Java Util Logging) | logging.properties |
3、因为 Spring Boot 底层默认采用 slf4j+logback 的日志组合,所以这里以 logback 的 logback.xml(使用 logback-spring.xml 文件名也是可以的) 为例,将配置为文件放入到类路径下(其它的日志框架实现也是同理)。
在线演示源码:src/main/resources/logback.xml · 汪少棠/yuanyuan - Gitee.com
<property name="LOG_HOME" value="logs"/>:定义日志存放的根目录,可以是相对路径,或者绝对路径(E:/temp/logs). <property name="appName" value="systemLog"></property>:定义日志文件名称. <file>${LOG_HOME}/${appName}.txt</file>:指定日志文件存放的全路径. <logger name="com.wmx" level="debug"/>:指定应用中指定包路径下的输出日志类型、级别,必须根据实际情况改写成自己的. <root level="INFO">:root 与 logger 是父子关系,没有指定 logger 的,全部统一用 root 配置的日志级别处理. |
java -jar 启动设置日志输出级别
1、可以在启动的时候通过命令行参数指定日志输出级别,相当于 logging.level.root 配置的根日志记录器。
PS D:\project\IDEA_project\java-se\target> java -jar .\java-se-1.0-SNAPSHOT.jar --debug
[08:29:51:970] [INFO] - [main] - org.springframework.boot.StartupInfoLogger.logStarting(StartupInfoLogger.java:55) - Starting JavaseApplication v1.0-SNAPSHOT on wangMaoXiong with PID 85676 (D:\project\IDEA_project\java-se\target\java-se-1.0-SNAPSHOT.jar started by Think in D:\project\IDEA_project\java-se\target)
[08:29:51:976] [INFO] - [main] - org.springframework.boot.SpringApplication.logStartupProfileInfo(SpringApplication.java:651) - No active profile set, falling back to default profiles: default
[08:29:51:978] [DEBUG] - [main] - org.springframework.boot.SpringApplication.load(SpringApplication.java:679) - Loading source class org.example.JavaseApplication
[08:29:52:078] [DEBUG] - [main] - org.springframework.boot.logging.DeferredLog.logTo(DeferredLog.java:222) - Loaded config file 'jar:file:/D:/project/IDEA_project/java-se/target/java-se-1.0-SNAPSHOT.jar!/BOOT-INF/classes!/application.yml' (classpath:/application.yml)
动态切换 Logback 日志输出级别
logback.xml 配置文件定时监控
方式1:修改 logback.xml 配置文件,定时监控配置变化情况。
<!--scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒;当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
1、如果是在本地 IDE 编辑器中测试,注意修改的是 classes 编译目录下的 logback.xml 文件,而不是 resources 目录下的源文件。
2、鉴于现在都是微服务开发,分布式部署,而且为了方便管理,基本都是打包后部署在一些平台上面。直接修改日志配置文件不太现实。
LoggerContext 切换日志输出级别
1、与 log4j2 的方式非常类似:LoggerConfig 动态修改日志记录器(推荐)
2、自己提供一个 Controller 请求接口,用于动态修改日志输出级别,想设置什么级别,只需要调用一下接口,传递一下参数即可,无论是设置整个 root 级别,还是对指定包或者类都能轻松设置,不用重启服务就能立马生效。
3、在线演示源码:
src/main/resources/logback.xml · 汪少棠/yuanyuan - Gitee.com
src/main/java/com/wmx/yuanyuan/controller/LogbackController.java · 汪少棠/yuanyuan - Gitee.com
/**
* logback 动态切换指定包或者类的日志输出级别,立即生效.
* http:localhost:8080/logback/setLevel
* http:localhost:8080/logback/setLevel?level=DEBUG
* http:localhost:8080/logback/setLevel?level=DEBUG&clazz=com.wmx
*
* @param level :日志级别,可选值有:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF,默认为 debug。不区分大小写.
* @param clazz :指定的包或者类路径,为空时默认设置全局(root)日志级别。路径不存在时,照样会设置这个路径,不会影响全局级别,这一点与 log4j2 不同.
* 比如 org.springframework。
* @return map :返回指定路径的当前日志级别,root 表示全局级别
*/
@GetMapping(value = "/logback/setLevel")
public Map<String, Object> setLevel(String level, String clazz) {
Map<String, Object> dataMap = new HashMap<>(8);
dataMap.put("code", 200);
Logger logger;
try {
// 返回正在使用的 ILoggerFactory 实例.
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
if (clazz == null || "".equals(clazz.trim())) {
//Logger getLogger(final String name) :根据包路径或类路径获取日志记录器,"ROOT" 表示根记录器
logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
dataMap.put("clazz", Logger.ROOT_LOGGER_NAME);
} else {
//Logger getLogger(final String name) :根据包路径或类路径获取日志记录器,"ROOT" 表示根记录器
//路径不存在也没有关系,照样会返回它的日志记录器,然后设置输出级别.
logger = loggerContext.getLogger(clazz);
dataMap.put("clazz", clazz);
}
//Level toLevel(String sArg):转换为日志级别,如果转换失败,则默认为 debug 级别.
//synchronized void setLevel(Level newLevel):为日志记录器设置日志输出级别,立即生效.
logger.setLevel(Level.toLevel(level));
//获取日志记录器的日志输出级别.
String logLevel = logger.getLevel().toString();
dataMap.put("level", logLevel);
} catch (Exception e) {
dataMap.put("code", 500);
dataMap.put("msg", e.getMessage());
log.error(e.getMessage(), e);
}
return dataMap;
}
SpringBoot Actuator 监控管理日志
1、好处1:不用编码,只需要引用 Spring Boot Actuator 监控,然后开启访问端点 /loggers,即可轻松查看日志输出级别,并进行切换。
2、好处2:解耦日志框架,无论使用的 logback 还是 log4j2 ,都能轻松切换。
<!--监控和管理应用程序-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3、开启日志访问端点: /loggers
management:
endpoint:
health:
show-details: ALWAYS #展示节点的详细信息
endpoints:
web:
exposure:
include: info,health,logfile,loggers #指定公开的访问端点
4、查看级别
A、发送 GET 请求:http://localhost:8080/actuator/loggers 获取日志等级
B、http://localhost:8080/actuator/loggers/x.j.z :表示指定包或者类的日志输出级别
C、返回的信息非常详细,包含了 ROOT,以及程序中各个包和类的日志级别
D、其中 configuredLevel 表示配置级别,effectiveLevel 表示有效级别,configuredLevel 可能为 null,因为没有配置。
5、修改日志级别
A、post 请求:http://localhost:8080/actuator/loggers/x.j.z,x.j.z 表示指定的包或者类路径,比如修改 root 全局日志输出级别:http://localhost:8080/actuator/loggers/root
B、请求 Body 的内容格式:{"configuredLevel":"error"}
src/main/resources/application.yml · 汪少棠/yuanyuan - Gitee.com
pom.xml · 汪少棠/yuanyuan - Gitee.com