理解SpringBoot 的日志设计
在项目中导入spring-boot-starter.jar依赖,它会传递 导入spring-boot-starter-logging.jar依赖,依赖关系如下图:
spring-boot-starter-logging.jar依赖三个jar包:
- logback-classic.jar:它传递依赖于logback-core.jar和slf4j-api.jar
- log4j-to-slf4j.jar:它传递依赖于log4j-api.jar和slf4j-api.jar
- jul-to-slf4j.jar:它传递依赖于slf4j-api.jar
java的日志框架比较多,常见的包括:SLF4J、Log4j、Log4j2、Logback、common-logging(JCL)、java.util.logging(JUL)、JBoss Logging等,这些日志框架又分:
- 门面类(抽象层):SLF4J、JCL、JBoss Logging
- 日志实现:Log4j、Log4j2、Logback、common-logging(JCL)
SpringBoot默认使用SLF4J+Logback组合,SLF4J作为日志门面(应用程序输出日志时应该面向改API),Logback作为日志实现。
由于SpringBoot要整合大量的第三方框架,这些框架可能使用JCL、Log4j、JUL等。因此SpringBoot提供对应的日志路由,将其他框架生成的日志信息统一路由给SLF4J处理。从上面依赖关系可以看出:
- log4j-to-slf4j.jar:负责将Log4j日志路由到SLF4J
- jul-to-slf4j.jar:负责将JUL日志路由到SLF4J
虽然SpringBoot默认采用Logback作为底层日志实现,但通过配置允许将底层日志实现改为其他框架。SpringBoot允许将Logback依赖排除出去,添加其他日志实现(比如log4j)的依赖。
需要注意的是:当吧SpringBoot应用部署到Web服务器或应用服务器上时,JUL生成的日志不会被路由到SpringBoot应用的日志中,这是为了避免将服务器或者服务器上的其他应用的日志也路由到SpringBoot的日志中,否则会造成日志混乱。
日志级别与格式
代码示例:控制器类- @RestController
- public class HelloController
- {
- Logger logger = LoggerFactory.getLogger(this.getClass());
- @GetMapping
- public Map<String, Object> hello()
- {
- logger.trace("-------TRACE级别的日志-------");
- logger.debug("-------DEBUG级别的日志-------");
- logger.info("-------INFO级别的日志-------");
- logger.warn("-------WARN级别的日志-------");
- logger.error("-------ERROR级别的日志-------");
- return Map.of("hello", "Hello");
- }
- }
复制代码 日志级别主要分为(级别由低到高):
- all:输出所有日志
- trace
- debug
- info
- warn
- error
- fatal:log4j增加的一种日志级别,代表“致命错误”,比error级别更高。(由于SpringBoot不支持此级别,因此会被自动转换为error级别)
- off:关闭所有日志
日志系统有一个规则:当日志的输出方法的级别高于或等于日志的设置级别,该日志才会实际输出。
比如日志级别设为info,当程序使用info()、warn()、error()输出时,日志才会实际输出;使用trace()、debug()输出的日志会被忽略。
因此,日志级别越高,输出日志就越精简,性能开销越小;日志级别越低,输出日志就越详细,性能开销越大。一般项目处于开发、测试、试运行阶段,日志级别设置的低;在项目实际运行阶段,日志级别设置的高。
由上图可知,SpringBoot默认的日志级别是Info。
SpringBoot输出的日志包括如下信息:
- 日期和时间:精确到毫秒
- 日志级别
- 进程ID
- 分隔符:三个减号(---)
- 线程名:方括号里面的内容(在控制台输出时可能会被截断)
- 日志名:通常是完整类名(为了便于阅读,包名经常简写)
- 日志信息
设置日志级别的几种方式:
- 通过debug=true或trace=true等属性(可通过配置文件、命令行参数、系统变量、OS环境变量等方式)改变整个SpringBoot核心的日志级别
- 通过logging.level.=属性(可通过配置文件、命令行参数、系统变量等方式)设置日志级别。其中代表日志名,通常是包名或全限定类名,而Level可以是各种日志级别。
需要注意的是,当启用trace或debug模式时,SpringBoot的核心日志(包括嵌入式容器、Hibernate和SpringBoot)被设为对应的级别,但是其他程序组件不会被设为对应级别。
例如:添加命令行参数: --trace 。 启动上面代码运行结果如下:
可见,程序组件本身的日志级别没有改变。
那么要设置程序组件的日志级别,要通过logging.level.=属性来设置- logging:
- level:
- # 将org.crazyit.app包及其子包下所有日志级别设为TRACE
- org.crazyit.app: trace
复制代码 运行结果如下
学会之后解决以下几个问题就很简单了。
- 让Mybatis输出SQL语句(logging.level.=debug)
- 输出Redis的详细执行过程(logging.level.io.lettuce.core=debug)
- 输出MongoDB的详细执行过程(logging.level.com.mongodb=debug)
SpringBoot允许通过spring.output.ansi.enabled属性设置是否用不同颜色来区分不同级别日志,该属性支持以下属性值:
- always:总是启用
- detect:自动检查。如果控制台支持ansi颜色特性,则启用。这是默认值。
- never:不启用
如果要改变控制台的日志格式,可通过logging.pattern.console属性进行设置。其默认值是:
%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint}
%clr(${LOG_LEVEL_PATTERN:-%5p})
%clr(${PID:- }){magenta}
%clr(---){faint}
%clr([%15.15t]){faint}
%clr(%-40.40logger{39}){cyan}
%clr(
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |