让你的spring-boot应用日志随心所欲--spring boot日志深入分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了让你的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.40logger39)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.40logger39)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.xml, logback-spring.groovy, logback.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>
参考资料
【2】https://www.jb51.net/article/133795.htm
以上是关于让你的spring-boot应用日志随心所欲--spring boot日志深入分析的主要内容,如果未能解决你的问题,请参考以下文章
spring-boot实战01:Hello World项目搭建