1.spring boot日誌概述html
spring boot使用Commons Logging做爲內部的日誌系統,而且給Java Util Logging,Log4J2以及Logback都提供了默認的配置。
若是使用了spring boot的Starters,那麼默認會使用Logback用於記錄日誌。java
2.spring boot日誌默認配置web
咱們啓動一個空的spring-boot項目看一下控制檯的日誌spring
控制檯的默認配置sql
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爲配置不一樣的顏色輸出,支持的顏色有如下幾種:express
blue
cyan
faint
green
magenta
red
yellow
輸出順序分析:apache
一、日期和時間--精確到毫秒,並按照時間進行簡單的排序,格式爲:bootstrap
%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint}tomcat
二、日誌級別--ERROR,WARN,INFO,DEBUG,TRACEapp
%clr(${LOG_LEVEL_PATTERN:-%5p})
三、進程ID號
%clr(${PID:- })
四、日誌內容,用"---"分隔符分開
%clr(---){faint}
五、線程名字--括在方括號中
%clr([%15.15t]){faint}
六、日誌的名字--一般對應的是類名
%clr(%-40.40logger{39}){cyan}
注意:Logback沒有FATAL級別(映射到ERROR)
不一樣日誌級別對應的顏色以下
3.spring boot日誌配置
能夠經過application.properties或者application.yml查看全部配置
每一個配置後面都有說明,就不一一贅述了。
4.spring boot日誌實現原理
點擊配置屬性,能夠進入LoggingApplicationListener這個類,
`/**
它實現了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>
參考資料