1. 程式人生 > >SpringBoot的日誌管理

SpringBoot的日誌管理

star cnblogs 基礎上 version size -- schema hot eth

SpringBoot的日誌管理

SpringBoot關於日誌的官方文檔

1、簡述
技術分享圖片
SpringBoot官方文檔關於日誌的整體說明


本博客基於SpringBoot_1.3.6
大家請先簡單看下這篇英文的官方文檔,文中有說 SpringBoot 內部日誌系統使用的是 Commons Logging 並且 SpringBoot 給 JDKLogging , Log4j2(Log4j也是支持的) , Logback 都提供了默認配置,並且如果使用了 Starters ,那麽默認使用 Logback 。
那麽什麽是這個這個 Starters 呢?大家請看我的pom文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lunqi</groupId>
<artifactId>springbootstart</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>boot</name>
<description>SpringBootDemo</description>
<parent>
<groupId>org.springframework.boot</groupId>
<!--
Spring Boot應用啟動器Starter-parent:
官方推薦
其中集成了:
1、使用java6編譯級別
2、使用utf-8編碼
3、實現了通用的測試框架 (JUnit, Hamcrest, Mockito).
4、智能資源過濾
5、智能的插件配置(exec plugin, surefire, Git commit ID, shade).
-->
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.6.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<!--
Spring Boot應用啟動器Starter-web:
支持全棧式Web開發,包括Tomcat和spring-webmvc
-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

簡單的說,只要你的 pom 文件中使用了 spring-boot-starter 就代表著你使用了 SpringBoot 的 Starters 。相信各位玩 SpringBoot 的朋友肯定是看到了自己的 pom 文件中有這個了,因為,Starters(啟動器)是 SpringBoot 最核心的部件之一,沒有了啟動器, SpringBoot 就幾乎廢掉了。

2、使用

SpringBoot 招人喜歡的一大特點就是配置方便,配置日誌的相關參數也只需要寫在 application.properties 中就可以了,當然,這僅僅是基本的配置,如果需要高級的配置,還是需要添加依賴所選擇日誌系統的配置文件。

技術分享圖片
SpringBoot官方文檔關於配置Log級別的說明

官方文檔中有提到, SpringBoot 的 Logging 配置的級別有7個:
TRACE , DEBUG , INFO , WARN , ERROR , FATAL , OFF

配置格式:
logging.level.*=LEVEL

舉例:

#root日誌以WARN級別輸出
logging.level.root=WARN
#springframework.web日誌以DEBUG級別輸出
logging.level.org.springframework.web=DEBUG
#hibernate日誌以ERROR級別輸出
logging.level.org.hibernate=ERROR

在進行了這樣的配置後,就可以在控制臺打印Log信息了!

但是很有人又會問了,在生產環境中,日誌往往要以文件形式存放到本地,那麽 SpringBoot 的默認配置文件能夠實現嗎?答案是可以的,我們繼續看官方文檔:

技術分享圖片

文檔中對 SpringBoot 日誌的文件輸出有明確的說明,上面說到:
在默認情況下,SpringBoot 是僅僅在控制臺打印log信息的,如果我們需要將log信息記錄到文件,那麽就需要在 application.properties 中配置 logging.file 或者 logging.path (註意啊,是或者,不是並且!)
而且官方文檔有明確說明,配置 logging.file 的話是可以定位到自定義的文件的,使用 logging.path 的話,日誌文件將使用 spring.log 來命名。
而且日誌文件會在10Mb大小的時候被截斷,產生新的日誌文件,默認級別為:ERROR、WARN、INFO

這時候又會有很多同學問了,那如果我要自定義輸出格式怎麽辦呢?其實在 application.properties 也是可以辦到的。繼續看官方文檔:

技術分享圖片
SpringBoot官方文檔關於日誌配置的說明


但是要註意:這兩個配置項是只對默認的日誌系統Logback起作用的

舉例(application.properties):

logging.level.root=WARNlogging.level.org.springframework.web=DEBUGlogging.file=/log/log/my.loglogging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%nlogging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n

結果(Console部分):

2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘systemEnvironment‘: no URL paths identified2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry‘: no URL paths identified2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘messageSource‘: no URL paths identified2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘servletContext‘: no URL paths identified2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘contextParameters‘: no URL paths identified2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘contextAttributes‘: no URL paths identified2016/09/22-17:36:06 [main] INFO  org.springframework.web.servlet.handler.SimpleUrlHandlerMapping- Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2016/09/22-17:36:06 [main] INFO  org.springframework.web.servlet.handler.SimpleUrlHandlerMapping- Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver- Looking for exception mappings: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@15ef3ab: startup date [Thu Sep 22 17:36:04 GMT+08:00 2016]; root of context hierarchy2016/09/22-17:36:06 [main] INFO  org.springframework.web.servlet.handler.SimpleUrlHandlerMapping- Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.resource.ResourceUrlProvider- Looking for resource handler mappings2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.resource.ResourceUrlProvider- Found resource handler mapping: URL pattern="/**/favicon.ico", locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@b1df4d]2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.resource.ResourceUrlProvider- Found resource handler mapping: URL pattern="/webjars/**", locations=[class path resource [META-INF/resources/webjars/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@164e13b]2016/09/22-17:36:06 [main] DEBUG org.springframework.web.servlet.resource.ResourceUrlProvider- Found resource handler mapping: URL pattern="/**", locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@1fefcb1]2016/09/22-17:36:06 [main] DEBUG org.springframework.web.context.support.StandardServletEnvironment- Adding [server.ports] PropertySource with highest search precedence

結果(File部分):

2016/09/22-17:36 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry‘: no URL paths identified2016/09/22-17:36 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘messageSource‘: no URL paths identified2016/09/22-17:36 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘servletContext‘: no URL paths identified2016/09/22-17:36 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘contextParameters‘: no URL paths identified2016/09/22-17:36 [main] DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name ‘contextAttributes‘: no URL paths identified2016/09/22-17:36 [main] INFO  org.springframework.web.servlet.handler.SimpleUrlHandlerMapping- Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2016/09/22-17:36 [main] INFO  org.springframework.web.servlet.handler.SimpleUrlHandlerMapping- Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2016/09/22-17:36 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver- Looking for exception mappings: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@15ef3ab: startup date [Thu Sep 22 17:36:04 GMT+08:00 2016]; root of context hierarchy2016/09/22-17:36 [main] INFO  org.springframework.web.servlet.handler.SimpleUrlHandlerMapping- Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2016/09/22-17:36 [main] DEBUG org.springframework.web.servlet.resource.ResourceUrlProvider- Looking for resource handler mappings

好了,這時候大家已經對 application.properties 中配置Log有了了解,但是這時候又會發現一個問題, application.properties 中的配置有的時候不能滿足我們的要求,或者我們要使用其他的集成進SpringBoot的日誌系統,該怎麽辦呢?官方文檔又給了我們答案:

技術分享圖片
SpringBoot官方文檔關於使用指定日誌配置的說明


我們能從中知道:
1.通過將適當的庫添加到classpath,可以激活各種日誌系統。然後在 classpath 的根目錄 (root) 或通過 Spring Environment( application.properties)的 logging.config 屬性指定的位置提供一個合適的配置文件來達到進一步的定制(註意由於日誌是在ApplicationContext被創建之前初始化的,所以不可能在Spring的@Configuration文件中,通過@PropertySources控制日誌。系統屬性和平常的Spring Boot外部配置文件能正常工作)。
2.如果我們使用指定日誌系統的配置文件, application.properties 中相關的日誌配置是可以不要的。
3.支持的三種日誌系統( Logback , Log4j2 ( Log4j 也是支持的), JDKLogging )所識別的配置文件名。

好了,接下來我們就要學習如何在 SpringBoot 中玩這些指定的日誌系統了。

3、擴展
#3.1使用Logback的指定配置文件實現更高級的日誌配置:

如果我們的確要使用 Logback 的指定配置文件的話,那麽說明 application.properties 中的配置功能已經不滿足我們需求了,所以 application.properties 中關於日誌記錄的可以不要了,因為我們啟用了 Logback 自己的配置文件,啟用的方式很簡單,在 classpath 的 resources 下新建 logback.xml 文件。這樣就可以了。
具體配置和說明這裏有個簡單的介紹:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制臺打印日誌的相關配置 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日誌格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%level] - %m%n</pattern>
</encoder>
<!-- 日誌級別過濾器 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 過濾的級別 -->
<level>WARN</level>
<!-- 匹配時的操作:接收(記錄) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配時的操作:拒絕(不記錄) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>

<!-- 文件保存日誌的相關配置 -->
<appender name="ERROR-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 保存日誌文件的路徑 -->
<file>/logs/error.log</file>
<!-- 日誌格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>
</encoder>
<!-- 日誌級別過濾器 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 過濾的級別 -->
<level>ERROR</level>
<!-- 匹配時的操作:接收(記錄) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配時的操作:拒絕(不記錄) -->
<onMismatch>DENY</onMismatch>
</filter>
<!-- 循環政策:基於時間創建日誌文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日誌文件名格式 -->
<fileNamePattern>error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 最大保存時間:30天-->
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!-- 基於dubug處理日誌:具體控制臺或者文件對日誌級別的處理還要看所在appender配置的filter,如果沒有配置filter,則使用root配置 -->
<root level="debug">
<appender-ref ref="STDOUT" />
<appender-ref ref="ERROR-OUT" />
</root>
</configuration>
#3.2使用Log4j的指定配置文件實現更高級的日誌配置:

1.更改pom文件:
在創建 SpringBoot 工程時,我們引入了 spring-boot-starter,其中包含了 spring-boot-starter-logging ,該依賴內容就是 SpringBoot 默認的日誌框架 Logback ,所以我們在引入 log4j 之前,需要先排除該包的依賴,再引入 log4j 的依賴。

<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>

之後我們可以使用 application.properties,其中的配置項之前有說,同樣也是適用 Log4J 的。
如果需要更高級的配置選擇,必須要添加 Log4j 的配置文件了。我們在 classpath 的 resources下新建 log4j.properties 文件,這裏簡單示例一下:

# 日誌級別,日誌追加程序列表...log4j.rootLogger=DEBUG,ServerDailyRollingFile,stdout#文件保存日誌log4j.appender.ServerDailyRollingFile=org.apache.log4j.DailyRollingFileAppender#文件保存日誌日期格式log4j.appender.ServerDailyRollingFile.DatePattern=‘.‘yyyy-MM-dd_HH#文件保存日誌文件路徑log4j.appender.ServerDailyRollingFile.File=/mnt/lunqi/demo/log4j.log#文件保存日誌布局程序log4j.appender.ServerDailyRollingFile.layout=org.apache.log4j.PatternLayout#文件保存日誌布局格式log4j.appender.ServerDailyRollingFile.layout.ConversionPattern=%d - %m%n#文件保存日誌需要向後追加(false是測試的時候日誌文件就清空,true的話就是在之前基礎上往後寫)log4j.appender.ServerDailyRollingFile.Append=false#控制臺日誌log4j.appender.stdout=org.apache.log4j.ConsoleAppender#控制臺日誌布局程序log4j.appender.stdout.layout=org.apache.log4j.PatternLayout#控制臺日誌布局格式log4j.appender.stdout.layout.ConversionPattern=%d yyyy-MM-dd HH:mm:ss %p [%c] %m%n
#3.3使用Log4j2的指定配置文件實現更高級的日誌配置:

1.更改pom文件:
跟引入Log4j一樣,我們也需要排除 spring-boot-starter-logging ,再引入Log4j2的依賴:

<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-log4j2</artifactId>
</dependency>

2.跟Log4j一樣,我們可以使用 application.properties ,如果需要更高級的配置選擇,必須要添加 Log4j2 的配置文件了。我們在 classpath 的 resources下新建 log4j2.xml 文件:

<?xml version="1.0" encoding="UTF-8"?><configuration> 
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" /> </Console>
<File name="log" fileName="log/test.log" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
</File>
<RollingFile name="RollingFile" fileName="logs/spring.log" filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log">
<PatternLayout pattern="%d{yyyy-MM-dd ‘at‘ HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n" />
<SizeBasedTriggeringPolicy size="50MB" />
</RollingFile>
</appenders>

<loggers>
<root level="trace">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</root>
</loggers>
</configuration>

這裏所有的配置信息和配置項在說Logback和Log4j的時候都有說過,所以Log4j2的配置文件肯定是能看懂的。

SpringBoot的日誌管理