窥探-spring boot日志使用及其源码分析
Spring Boot使用Commons Logging进行所有内部日志记录,但是使底层日志实现保持打开状态。 提供了Java Util Logging,Log4J2和Logback的默认配置。 在每种情况下,记录器都被预先配置为使用控制台输出以及可选文件输出。默认情况下,如果使用“Starts”,则使用Logback进行记录。 还包括适当的Logback路由,以确保使用Java Util Logging,Commons Logging,Log4J或SLF4J的从属库都能正常工作
日志排版
我们来看看spring的启动日志,看看日志是怎么排版的?
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.1.RELEASE)
2020-08-14 16:23:39.328 INFO 8124 --- [ main] org.tony.soringboot.logging.Application : Starting Application on tony with PID 8124 (D:\sources\spring-boot-cloud-study-gradle\spring-boot-study-gradle-log-default\bin\main started by xuanyi in D:\sources\spring-boot-cloud-study-gradle)
2020-08-14 16:23:39.334 INFO 8124 --- [ main] org.tony.soringboot.logging.Application : No active profile set, falling back to default profiles: default
2020-08-14 16:23:42.723 INFO 8124 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)
2020-08-14 16:23:42.744 INFO 8124 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-14 16:23:42.745 INFO 8124 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.36]
2020-08-14 16:23:43.121 INFO 8124 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-14 16:23:43.123 INFO 8124 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3670 ms
2020-08-14 16:23:43.520 INFO 8124 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-14 16:23:44.290 INFO 8124 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2020-08-14 16:23:44.600 INFO 8124 --- [ main] org.tony.soringboot.logging.Application : Started Application in 6.305 seconds (JVM running for 7.56)
最上面的为spring的启动banner
//[日志时间][日志级别][进程id][---分隔符][执行线程][日志作用的相关类][日志信息message]
2020-08-14 16:23:44.600 INFO 8124 --- [ main] org.tony.soringboot.logging.Application : Started Application in 6.305 seconds (JVM running for 7.56)
Logback没有FATAL级别,FATAL被映射到了ERROR级别
控制台输出
控制台输出是默认的日志配置,默认显示的级别为ERROR,WARN,INFO的日志级别。我们也可以使用–debug标记输出debug的日志,也可以在application.yml添加debug的标记
–debug:
java -jar spring-boot-study-gradle-log-default.jar --debug
appllication.yml:
启动项目,将显示debug的日志:
文件输出
spring boot默认是将日志进行控制台输出,没有将日志输出到文件,这样就不能进行日志追踪了。如果想将文件日志写入到指定的文件中,可以修改application.yml文件。添加logging.file和logging.path属性。
日志文件达到10 MB时会旋转,并且与控制台输出一样,默认情况下会记录ERROR级别,WARN级别和INFO级别的消息。 可以使用logging.file.max-size属性更改大小限制。 除非已设置logging.file.max-history属性,否则以前旋转的文件将无限期存档
日志记录系统在应用程序生命周期的早期进行了初始化。 因此,在通过@PropertySource批注加载的属性文件中找不到日志记录属性。日志记录属性与实际的日志记录基础结构无关。 结果,特定的配置密钥(例如用于logback的logback.configurationFile)不受spring boot 管理
日志级别
在springboot环境中,日志系统能有相关的日志级别,我们可以修改application.yml进行相关包的配置日志界别。配置root logger可以使用logging.level.root
客户自定义日志
通过在类路径中包含适当的库,可以激活各种日志记录系统并且可以通过在类路径的根目录或以下Spring Environment属性logging.config指定的位置中提供合适的配置文件来进一步自定义
可以通过使用org.springframework.boot.logging.LoggingSystem系统属性来强制Spring Boot使用特定的日志记录系统。 该值应该是LoggingSystem实现的完全限定的类名。还可以禁用Spring Boot的日志配置完全通过使用none值.
由于日志记录是在创建ApplicationContext之前初始化的,因此无法从Spring @Configuration文件中的@PropertySources控制日志记录。更改日志记录系统或完全禁用它的唯一方法是通过系统属性
日志系统 | 自定义 |
---|---|
Logback | logback-spring.xml, logbackspring.groovy, logback.xml, or logback.groovy |
Log4j2 | log4j2-spring.xml or log4j2.xml |
JDK (Java Util Logging) | logging.properties |
如果可能,建议在日志配置中使用-spring变体(例如,logback-spring.xml而不是logback.xml)。 如果使用标准配置位置,Spring将无法完全控制日志初始化。
从“可执行jar”运行时,Java Util Logging存在一些已知的类加载问题,这些问题会引起问题。 如果可以的话,建议从“可执行jar”运行时避免使用它。
相关系统属性:
属性 | 系统属性 | 描述 |
---|---|---|
logging.exception-conversion-word | LOG_EXCEPTION_CONVERSION_WORD | 日志记录异常时使用的转换词 |
logging.file | LOG_FILE | 如果定义,则在默认日志配置中使用 |
logging.file.max-size | LOG_FILE_MAX_SIZE | 最大日志文件大小(如果启用LOG_FILE)。(只支持默认的Logback设置。 ) |
logging.file.max-history | LOG_FILE_MAX_HISTORY | 保存的归档日志文件的最大数量(如果启用LOG_FILE)。(只支持默认的Logback设置。) |
logging.path | LOG_PATH | 如果定义,则在默认日志配置中使用 |
logging.pattern.console | CONSOLE_LOG_PATTERN | 要在控制台(stdout)上使用的日志模式)。(只支持默认的Logback设置。) |
logging.pattern.dateformat | LOG_DATEFORMAT_PATTERN | 日志日期格式的附加模式。(只支持默认的Logback设置。) |
logging.pattern.file | FILE_LOG_PATTERN | 要在文件中使用的日志模式(如果启用了LOG_FILE)。(只支持默认的Logback设置。) |
logging.pattern.level | LOG_LEVEL_PATTERN | 呈现日志级别时要使用的格式(默认%5p)。(只支持默认的Logback设置。) |
PID | PID | 当前进程ID(如果可能,在尚未定义为OS环境变量时发现) |
如果要在日志记录属性中使用占位符,则应该使用SpringBoot的语法,而不是底层框架的语法。 值得注意的是,如果使用Logback,则应该使用:作为分隔符在 属性名称与其默认值之间,而不使用:-
可以通过只重写LOG_LEVEL_PATTERN(或用Logback logging.pattern.level)将MDC和其他临时内容添加到日志行中)。 例如,如果使用logging.pattern.level=user:%X{user} %5p 然后,默认日志格式包含“user”的MDC条目
Logback 扩展
Spring Boot包括Logback的许多扩展,可以帮助高级配置。可以在logback-spring.xml配置文件中使用这些扩展名。
Profile指定配置
通过< springProfile >标签,可以根据活动的Spring profile文件有选择地包括或排除配置部分。在< configuration >元素内的任何位置都支持profile文件部分。使用name属性指定哪个配置文件接受配置。可以使用逗号分隔的列表指定多个配置文件。
<springProfile name="test">
<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>
<springProfile name="dev, pro">
<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>
<springProfile name="!pro">
<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>
环境属性
< springProperty >标签使可以从Spring Environment中公开属性,以在Logback中使用。 如果要从Logback配置中访问application.properties文件中的值,则这样做很有用。该标签的工作方式类似于Logback的标准< property >标签。 但是,您没有指定直接值,而是指定了属性的来源(来自环境)。 如果需要将属性存储在本地范围以外的其他位置,则可以使用scope属性。如果需要回退值(如果未在环境中设置该属性),则可以使用defaultValue属性。
<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>${fluentHost}</remoteHost>
...
</appender>
日志加载分析
在spring boot的进行配置的时候,日志会在application运行之前就进行加载,我们还是从run方法进去一步一步进行查看。
我们通过启动日志看看日志的加载:
进入标红的相关方法看看:
调用日志启动信息,子类可以重载该方法进行添加而外的日志配置
StartupInfoLogger该类将打印启动的日志,进行相关的字符串追加进行打印
这个类使用了LogFactory.getLog进行加载logger,LogFactory是一个抽象类,这个类在该spring boot中的版本中子类是过期的状态
在该版本版本中使用LogAdapter.createLog进行使用和加载log的相关类。
LogAdapter:进行logger的适配器