让你的spring-boot应用日志随心所欲--spring boot日志深入分析
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 |
|
Log4j2 |
|
JDK (Java Util Logging) |
|
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>
参考资料
【2】https://www.jb51.net/article/133795.htm
让你的spring-boot应用日志随心所欲--spring boot日志深入分析的更多相关文章
- 学习Spring Boot:(四)应用日志
前言 应用日志是一个系统非常重要的一部分,后来不管是开发还是线上,日志都起到至关重要的作用.这次使用的是 Logback 日志框架. 正文 Spring Boot在所有内部日志中使用Commons L ...
- spring boot aop打印http请求回复日志包含请求体
一.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- Spring Boot 2.X(十四):日志功能 Logback
Logback 简介 Logback 是由 SLF4J 作者开发的新一代日志框架,用于替代 log4j. 主要特点是效率更高,架构设计够通用,适用于不同的环境. Logback 分为三个模块:logb ...
- Spring Boot 笔记 (2) - 使用 log4j2 记日志
日志框架的选用 Spring 使用的默认日志框架是 logback, 默认情况下会采取默认的 autoconfiguration; 即便想对日志的一些配置进行修改也比较方便, 详细可以参考: Spri ...
- spring boot:使用log4j2做异步日志打印(spring boot 2.3.1)
一,为什么要使用log4j2? log4j2是log4j的升级版, 升级后更有优势: 性能更强/吞吐量大/支持异步 功能扩展/支持插件/支持自定义级别等 这些优 ...
- 一起来学spring Cloud | 第一章:spring Cloud 与Spring Boot
目前大家都在说微服务,其实微服务不是一个名字,是一个架构的概念,大家现在使用的基于RPC框架(dubbo.thrift等)架构其实也能算作一种微服务架构. 目前越来越多的公司开始使用微服务架构,所以在 ...
- Spring Boot 2 (二):Spring Boot 2 动态 Banner
Spring Boot 2 (二):Spring Boot 2 动态 Banner Spring Boot 2.0 提供了很多新特性,其中就有一个小彩蛋:动态 Banner. 一.配置依赖 使用 Sp ...
- Spring Boot 应用系列 5 -- Spring Boot 2 整合logback
上一篇我们梳理了Spring Boot 2 整合log4j2的配置过程,其中讲到了Spring Boot 2原装适配logback,并且在非异步环境下logback和log4j2的性能差别不大,所以对 ...
- Spring Boot 应用系列 4 -- Spring Boot 2 整合log4j2
一.背景 1. log4j2传承于log4j和logback,它是目前性能最好的日志处理工具,有关它们的性能对比请看: 2. 除了性能好之外,log4j2有这么几个重要的新features: (1) ...
随机推荐
- PHP把时间转换成几分钟前、几小时前、几天前的几个函数、类分享
这篇文章主要介绍了php计算时间几分钟前.几小时前.几天前的几个函数.类分享,需要的朋友可以参考下一.函数实现实例1: <?php header("Content-type: text ...
- 唐诗掠影:基于词移距离(Word Mover's Distance)的唐诗诗句匹配实践
词移距离(Word Mover's Distance)是在词向量的基础上发展而来的用来衡量文档相似性的度量. 词移距离的具体介绍参考http://blog.csdn.net/qrlhl/artic ...
- Linux-解决putty无法直接使用root用户远程登录linux主机的问题
问题描述: 有时,在使用putty连接远程linux主机时会发现,无法直接使用root登录, 但是可以使用其他用户登录,然后切换至root用户. 解决办法: 1.修改配置文件 vi /etc/ssh/ ...
- unity破解步骤
1.选择unity的安装目录 C:\Programe Files (x86)\Unity\Editor 2.点击patch 3.使用random生成序列号 4.使用Cre Lic生成授权文件
- ACM学习历程—UVALive 7147 World Cup(分类讨论 && 贪心)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- NOIP2018爆炸记
又是一年\(NOIP\),可能是梦结束的地方? 之所以咕了这么久是得先确定自己不会退役,因为分太低了. 和去年一样在学校门前照了相,然后上车走了.高三回来考的只剩下\(p2oileen\)学姐了.新一 ...
- mongodb 学习资料
1 入门 http://www.cnblogs.com/huangxincheng/archive/2012/02/18/2356595.html http://www.cnblogs.com/hoo ...
- 洛谷【P1177】【模板】归并排序
题目传送门:https://www.luogu.org/problemnew/show/P1177 归并排序: 1.先将\(a\)数组的区间\([l,mid],[mid+1,r]\)排成有序的. 2. ...
- 快速排序的JavaScript实现
思想 分治的思想,将原始数组分为较小的数组(但没有像归并排序一样将它们分隔开). 主元选择: 从数组中任意选择一项作为主元,通常为数组的第一项,即arr[i]:或数组的中间项, arr[Math.fl ...
- Poj 1401 Factorial(计算N!尾数0的个数——质因数分解)
一.Description The most important part of a GSM network is so called Base Transceiver Station (BTS). ...