1.spring boot日志概述

spring boot使用Commons Logging作为内部的日志系统,并且给Java Util Logging,Log4J2以及Logback都提供了默认的配置。
如果使用了spring boot的Starters,那么默认会使用Logback用于记录日志。

2.spring boot日志默认配置

我们启动一个空的spring-boot项目看一下控制台的日志

控制台的默认配置

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(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}

其中%clr为配置不同的颜色输出,支持的颜色有以下几种:

  • blue
  • cyan
  • faint
  • green
  • magenta
  • red
  • yellow

输出顺序分析:

1、日期和时间--精确到毫秒,并按照时间进行简单的排序,格式为:

%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint}

2、日志级别--ERROR,WARN,INFO,DEBUG,TRACE

%clr(${LOG_LEVEL_PATTERN:-%5p})

3、进程ID号

%clr(${PID:- })

4、日志内容,用"---"分隔符分开

%clr(---){faint}

5、线程名字--括在方括号中

  

%clr([%15.15t]){faint}

6、日志的名字--通常对应的是类名

  

%clr(%-40.40logger{39}){cyan}

注意:Logback没有FATAL级别(映射到ERROR)

不同日志级别对应的颜色如下

3.spring boot日志配置

可以通过application.properties或者application.yml查看所有配置

每个配置后面都有说明,就不一一赘述了。

4.spring boot日志实现原理

点击配置属性,可以进入LoggingApplicationListener这个类,

/**
* An {@link ApplicationListener} that configures the {@link LoggingSystem}. If the
* environment contains a {@code logging.config} property it will be used to bootstrap the
* logging system, otherwise a default configuration is used. Regardless, logging levels
* will be customized if the environment contains {@code logging.level.*} entries and
* logging groups can be defined with {@code logging.group}.
* <p>
* Debug and trace logging for Spring, Tomcat, Jetty and Hibernate will be enabled when
* the environment contains {@code debug} or {@code trace} properties that aren't set to
* {@code "false"} (i.e. if you start your application using
* {@literal java -jar myapp.jar [--debug | --trace]}). If you prefer to ignore these
* properties you can set {@link #setParseArgs(boolean) parseArgs} to {@code false}.
* <p>
* By default, log output is only written to the console. If a log file is required the
* {@code logging.path} and {@code logging.file} properties can be used.
* <p>
* Some system properties may be set as side effects, and these can be useful if the
* logging configuration supports placeholders (i.e. log4j or logback):
* <ul>
* <li>{@code LOG_FILE} is set to the value of path of the log file that should be written
* (if any).</li>
* <li>{@code PID} is set to the value of the current process ID if it can be determined.
* </li>
* </ul>
*
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @author Madhura Bhave
* @since 2.0.0
* @see LoggingSystem#get(ClassLoader)
*/

它实现了GenericApplicationListener接口,它默认定义了日志组DEFAULT_GROUP_LOGGERS和日志级别LOG_LEVEL_LOGGERS

private static final Map<String, List<String>> DEFAULT_GROUP_LOGGERS;
static {
MultiValueMap<String, String> loggers = new LinkedMultiValueMap<>();
loggers.add("web", "org.springframework.core.codec");
loggers.add("web", "org.springframework.http");
loggers.add("web", "org.springframework.web");
loggers.add("web", "org.springframework.boot.actuate.endpoint.web");
loggers.add("web",
"org.springframework.boot.web.servlet.ServletContextInitializerBeans");
loggers.add("sql", "org.springframework.jdbc.core");
loggers.add("sql", "org.hibernate.SQL");
DEFAULT_GROUP_LOGGERS = Collections.unmodifiableMap(loggers);
} private static final Map<LogLevel, List<String>> LOG_LEVEL_LOGGERS;
static {
MultiValueMap<LogLevel, String> loggers = new LinkedMultiValueMap<>();
loggers.add(LogLevel.DEBUG, "sql");
loggers.add(LogLevel.DEBUG, "web");
loggers.add(LogLevel.DEBUG, "org.springframework.boot");
loggers.add(LogLevel.TRACE, "org.springframework");
loggers.add(LogLevel.TRACE, "org.apache.tomcat");
loggers.add(LogLevel.TRACE, "org.apache.catalina");
loggers.add(LogLevel.TRACE, "org.eclipse.jetty");
loggers.add(LogLevel.TRACE, "org.hibernate.tool.hbm2ddl");
LOG_LEVEL_LOGGERS = Collections.unmodifiableMap(loggers);
}

你也可以自定义logging.level和logging.group,它们都是map结构。LoggingApplicationListener重写了onApplicationEvent方法,实现日志的打印

    @Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationStartingEvent) {
onApplicationStartingEvent((ApplicationStartingEvent) event); //1
}
else if (event instanceof ApplicationEnvironmentPreparedEvent) {
onApplicationEnvironmentPreparedEvent(
(ApplicationEnvironmentPreparedEvent) event); //2
}
else if (event instanceof ApplicationPreparedEvent) {
onApplicationPreparedEvent((ApplicationPreparedEvent) event); //3
}
else if (event instanceof ContextClosedEvent && ((ContextClosedEvent) event)
.getApplicationContext().getParent() == null) {
onContextClosedEvent(); //4
}
else if (event instanceof ApplicationFailedEvent) {
onApplicationFailedEvent(); //5
}
}

第一步:根据classloader里加载的依赖决定使用哪个日志系统?

主要实现有JavaLoggingSystem,Log4J2LoggingSystem,LogbackLoggingSystem

    private void onApplicationStartingEvent(ApplicationStartingEvent event) {
this.loggingSystem = LoggingSystem
.get(event.getSpringApplication().getClassLoader());
this.loggingSystem.beforeInitialize();
}

第二步:通过classpath,enviroment等获取参数初始化日志系统

    /**
* Initialize the logging system according to preferences expressed through the
* {@link Environment} and the classpath.
* @param environment the environment
* @param classLoader the classloader
*/
protected void initialize(ConfigurableEnvironment environment,
ClassLoader classLoader) {
new LoggingSystemProperties(environment).apply();
LogFile logFile = LogFile.get(environment);
if (logFile != null) {
logFile.applyToSystemProperties();
}
initializeEarlyLoggingLevel(environment);
initializeSystem(environment, this.loggingSystem, logFile);
initializeFinalLoggingLevels(environment, this.loggingSystem);
registerShutdownHookIfNecessary(environment, this.loggingSystem);
}

第三步:注册springBootLoggingSystem

    private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
ConfigurableListableBeanFactory beanFactory = event.getApplicationContext()
.getBeanFactory();
if (!beanFactory.containsBean(LOGGING_SYSTEM_BEAN_NAME)) {
beanFactory.registerSingleton(LOGGING_SYSTEM_BEAN_NAME, this.loggingSystem);
}
}

第四步和第五步:日志系统清洗

    private void onContextClosedEvent() {
if (this.loggingSystem != null) {
this.loggingSystem.cleanUp();
}
} private void onApplicationFailedEvent() {
if (this.loggingSystem != null) {
this.loggingSystem.cleanUp();
}
}

5.自定义配置文件

日志系统 自定义配置文件

Logback

logback-spring.xmllogback-spring.groovylogback.xml, or logback.groovy

Log4j2

log4j2-spring.xml or log4j2.xml

JDK (Java Util Logging)

logging.properties

6.总结

  spring boot日志系统封装了logback,log4j2和java log,默认情况下使用java log,一旦使用各种starts,则默认使用Log4J2,也可以通过classpath来改变,pom.xml指定

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>

参考资料

【1】https://docs.spring.io/spring-boot/docs/2.1.2.RELEASE/reference/htmlsingle/#boot-features-logging-format

【2】https://www.jb51.net/article/133795.htm

让你的spring-boot应用日志随心所欲--spring boot日志深入分析的更多相关文章

  1. 学习Spring Boot:(四)应用日志

    前言 应用日志是一个系统非常重要的一部分,后来不管是开发还是线上,日志都起到至关重要的作用.这次使用的是 Logback 日志框架. 正文 Spring Boot在所有内部日志中使用Commons L ...

  2. spring boot aop打印http请求回复日志包含请求体

    一.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  3. Spring Boot 2.X(十四):日志功能 Logback

    Logback 简介 Logback 是由 SLF4J 作者开发的新一代日志框架,用于替代 log4j. 主要特点是效率更高,架构设计够通用,适用于不同的环境. Logback 分为三个模块:logb ...

  4. Spring Boot 笔记 (2) - 使用 log4j2 记日志

    日志框架的选用 Spring 使用的默认日志框架是 logback, 默认情况下会采取默认的 autoconfiguration; 即便想对日志的一些配置进行修改也比较方便, 详细可以参考: Spri ...

  5. spring boot:使用log4j2做异步日志打印(spring boot 2.3.1)

    一,为什么要使用log4j2?     log4j2是log4j的升级版,     升级后更有优势:     性能更强/吞吐量大/支持异步     功能扩展/支持插件/支持自定义级别等     这些优 ...

  6. 一起来学spring Cloud | 第一章:spring Cloud 与Spring Boot

    目前大家都在说微服务,其实微服务不是一个名字,是一个架构的概念,大家现在使用的基于RPC框架(dubbo.thrift等)架构其实也能算作一种微服务架构. 目前越来越多的公司开始使用微服务架构,所以在 ...

  7. Spring Boot 2 (二):Spring Boot 2 动态 Banner

    Spring Boot 2 (二):Spring Boot 2 动态 Banner Spring Boot 2.0 提供了很多新特性,其中就有一个小彩蛋:动态 Banner. 一.配置依赖 使用 Sp ...

  8. Spring Boot 应用系列 5 -- Spring Boot 2 整合logback

    上一篇我们梳理了Spring Boot 2 整合log4j2的配置过程,其中讲到了Spring Boot 2原装适配logback,并且在非异步环境下logback和log4j2的性能差别不大,所以对 ...

  9. Spring Boot 应用系列 4 -- Spring Boot 2 整合log4j2

    一.背景 1. log4j2传承于log4j和logback,它是目前性能最好的日志处理工具,有关它们的性能对比请看: 2. 除了性能好之外,log4j2有这么几个重要的新features: (1) ...

随机推荐

  1. http接口测试框架-python

    简单分解一下 接口测试框架设计: 主入口 -> 遍历接口/用例 -> 发送请求+接收响应 ->结果的对比 -> 生成报告 ->发送email 分成几大类:主入口的py文件 ...

  2. 解决jquery动态创建元素绑定事件失效问题

    存在问题 在我们使用jquery动态创建元素后往往会遇到一些问题,如: 给.button按钮绑定了点击时间,执行alert:(1); 点击事件代码如下: <script>$("# ...

  3. 训练集、测试集loss容易出现的问题总结

    train loss 不断下降,test loss不断下降:说明网络仍在学习; train loss 不断下降,test loss趋于不变:说明网络过拟合; train loss 趋于不变,test ...

  4. JS性能之滚动条之外的其他部分

    问题: 如果一个页面宽高比较大,也就是页面需要滚动条来查看其他页面内容,这时候,在滚动条之外的其他部分,是依然处于运行状态. 比如那部分有视频播放,则那些视频虽然在当前窗口看不到,但它们还是会处于播放 ...

  5. jquery--find与children方法的区别

      children方法: find方法: 通过以上的解释,可以总结如下: 1:children及find方法都用是用来获得element的子elements的,两者都不会返回 text node,就 ...

  6. POJ2442:Sequence

    浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:http://poj.org/problem?id=2442 我们先简化题意,假设只有两 ...

  7. 孤独地、凄惨地AK

    一个\(OIer\)要写多少\(for\) 才能被称为一个\(OIer\) 一位巨佬要爆过多少次零 才能在省选逆袭 手指要多少次掠过键盘 才能安心地休息 \(OI\)啊 我的朋友 在风中\(AK\) ...

  8. Poj_1008--Maya Calendar

    一.Description 上周末,M.A. Ya教授对古老的玛雅有了一个重大发现.从一个古老的节绳(玛雅人用于记事的工具)中,教授发现玛雅人使用了一个一年有365天的叫做Haab的历法.这个Haab ...

  9. 二 Flask快速入门

    1: 外部可访问的服务器: 如果你运行了这个服务器,你会发现它只能从你自己的计算机上访问,网络中其它任何的地方都不能访问.在调试模式下,用户可以在你的计算机上执行任意 Python 代码.因此,这个行 ...

  10. ES6学习之Proxy

    定义:“代理器”,用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程.可以对外界的访问进行过滤和改写. 语法: va ...