log4j 压缩日志_Spring Boot 日志各种使用姿势,是时候捋清楚了!
來自公眾號:江南一點雨
1. Java 日志概覽
1.1 總體概覽
1.2 日志級別
1.3 綜合對比
1.4 最佳實踐
2. Spring Boot 日志實現
2.1 Spring Boot 日志配置
2.2 Logback 配置
2.3 Log4j 配置
3.小結
通過一篇文章來和大家捋一捋 Java 中的日志問題,順便我們把 Spring Boot 中的日志問題也說清楚。
1. Java 日志概覽
說到 Java 日志,很多初學者可能都比較懵,因為這里涉及到太多東西了:Apache Commons Logging、Slf4j、Log4j、Log4j2、Logback、Java Util Logging?等等,這些框架各自有什么作用?他們之間有什么區別?
1.1 總體概覽
下面這張圖很好的展示了 Java 中的日志體系:
可以看到,Java 中的日志框架主要分為兩大類:日志門面和日志實現。
日志門面
日志門面定義了一組日志的接口規范,它并不提供底層具體的實現邏輯。Apache Commons Logging?和?Slf4j?就屬于這一類。
日志實現
日志實現則是日志具體的實現,包括日志級別控制、日志打印格式、日志輸出形式(輸出到數據庫、輸出到文件、輸出到控制臺等)。Log4j、Log4j2、Logback?以及?Java Util Logging?則屬于這一類。
將日志門面和日志實現分離其實是一種典型的門面模式,這種方式可以讓具體業務在不同的日志實現框架之間自由切換,而不需要改動任何代碼,開發者只需要掌握日志門面的 API 即可。
日志門面是不能單獨使用的,它必須和一種具體的日志實現框架相結合使用。
那么日志框架是否可以單獨使用呢?
技術上來說當然沒問題,但是我們一般不會這樣做,因為這樣做可維護性很差,而且后期擴展不易。例如 A 開發了一個工具包使用 Log4j 打印日志,B 引用了這個工具包,但是 B 喜歡使用 Logback 打印日志,此時就會出現一個業務使用兩個甚至多個日志框架,開發者也需要維護多個日志的配置文件。因此我們都是用日志門面打印日志。
1.2 日志級別
使用日志級別的好處在于,調整級別,就可以屏蔽掉很多調試相關的日志輸出。不同的日志實現定義的日志級別不太一樣,不過也都大同小異。
Java Util Logging
Java Util Logging?定義了 7 個日志級別,從嚴重到普通依次是:
- SEVERE
- WARNING
- INFO
- CONFIG
- FINE
- FINER
- FINEST
因為默認級別是 INFO,因此 INFO 級別以下的日志,不會被打印出來。
Log4j
Log4j?定義了 8 個日志級別(除去 OFF 和 ALL,可以說分為 6 個級別),從嚴重到普通依次是:
- OFF:最高等級的,用于關閉所有日志記錄。
- FATAL:重大錯誤,這種級別可以直接停止程序了。
- ERROR:打印錯誤和異常信息,如果不想輸出太多的日志,可以使用這個級別。
- WARN:警告提示。
- INFO:用于生產環境中輸出程序運行的一些重要信息,不能濫用。
- DEBUG:用于開發過程中打印一些運行信息。
- TRACE
- ALL 最低等級的,用于打開所有日志記錄。
Logback
Logback?日志級別比較簡單,從嚴重到普通依次是:
- ERROR
- WARN
- INFO
- DEBUG
- TRACE
1.3 綜合對比
Java Util Logging?系統在?JVM?啟動時讀取配置文件并完成初始化,一旦應用程序開始運行,就無法修改配置。另外,這種日志實現配置也不太方便,只能在?JVM?啟動時傳遞參數,像下面這樣:
-Djava.util.logging.config.file=。由于這些局限性,導致?Java Util Logging?并未廣泛使用。
Log4j?雖然配置繁瑣,但是一旦配置完成,使用起來就非常方便,只需要將相關的配置文件放到?classpath?下即可。在很多情況下,Log4j?的配置文件我們可以在不同的項目中反復使用。
Log4j?可以和?Apache Commons Logging?搭配使用,Apache Commons Logging?會自動搜索并使用?Log4j,如果沒有找到?Log4j,再使用?Java Util Logging。
比?Log4j?+?Apache Commons Logging?組合更得人心的是?Slf4j?+?Logback?組合。
Logback?是?Slf4j?的原生實現框架,它也出自?Log4j?作者(Ceki Gülcü)之手,但是相比?Log4j,它擁有更多的優點、特性以及更強的性能。
1.4 最佳實踐
- 如果不想添加任何依賴,使用?
Java Util Logging?或框架容器已經提供的日志接口。 - 如果比較在意性能,推薦:
Slf4j?+?Logback。 - 如果項目中已經使用了?
Log4j?且沒有發現性能問題,推薦組合為:Slf4j?+?Log4j2。
2. Spring Boot 日志實現
Spring Boot 使用?Apache Commons Logging?作為內部的日志框架門面,它只是一個日志接口,在實際應用中需要為該接口來指定相應的日志實現。
Spring Boot 默認的日志實現是?Logback。這個很好查看:隨便啟動一個 Spring Boot 項目,從控制臺找一行日志,例如下面這樣:
考慮到最后的 prod 是一個可以變化的字符,我們在項目中全局搜索:The following profiles are active,結果如下:
在日志輸出的那一行 debug。然后再次啟動項目,如下圖:
此時我們就可以看到真正的日志實現是?Logback。
其他的諸如?Java Util Logging、Log4j?等框架,Spring Boot 也有很好的支持。
在 Spring Boot 項目中,只要添加了如下 web 依賴,日志依賴就自動添加進來了:
<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-webartifactId>
dependency>
2.1 Spring Boot 日志配置
Spring Boot 的日志系統會自動根據 classpath 下的內容選擇合適的日志配置,在這個過程中首選 Logback。
如果開發者需要修改日志級別,只需要在 application.properties 文件中通過?logging.level 前綴+包名?的形式進行配置即可,例如下面這樣:
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
如果你想將日志輸出到文件,可以通過如下配置指定日志文件名:
logging.file.name=javaboy.log
logging.file.name 可以只指定日志文件名,也可以指定日志文件全路徑,例如下面這樣:
logging.file.name=/Users/sang/Documents/javaboy/javaboy.log
如果你只是想重新定義輸出日志文件的路徑,也可以使用?logging.file.path?屬性,如下:
logging.file.path=/Users/sang/Documents/javaboy
如果想對輸出到文件中的日志進行精細化管理,還有如下一些屬性可以配置:
- logging.logback.rollingpolicy.file-name-pattern:日志歸檔的文件名,日志文件達到一定大小之后,自動進行壓縮歸檔。
- logging.logback.rollingpolicy.clean-history-on-start:是否在應用啟動時進行歸檔管理。
- logging.logback.rollingpolicy.max-file-size:日志文件大小上限,達到該上限后,會自動壓縮。
- logging.logback.rollingpolicy.total-size-cap:日志文件被刪除之前,可以容納的最大大小。
- logging.logback.rollingpolicy.max-history:日志文件保存的天數。
日志文件歸檔這塊,小伙伴們感興趣可以自己試下,可以首先將 max-file-size 屬性調小,這樣方便看到效果:
logging.logback.rollingpolicy.max-file-size=1MB
然后添加如下接口:
@RestController
public?class?HelloController?{
????private?static?final?Logger?logger?=?getLogger(HelloController.class);
????@GetMapping("/hello")
????public?void?hello()?{
????????for?(int?i?=?0;?i?100000;?i++)?{
????????????logger.info("hello?javaboy");
????????}
????}
}
訪問該接口,可以看到最終生成的日志文件被自動壓縮了:
application.properties 中還可以配置日志分組。
日志分組能夠把相關的 logger 放到一個組統一管理。
例如我們可以定義一個 tomcat 組:
logging.group.tomcat=org.apache.catalina,org.apache.coyote, org.apache.tomcat
然后統一管理 tomcat 組中的所有 logger:
logging.level.tomcat=TRACE
Spring Boot 中還預定義了兩個日志分組 web 和 sql,如下:
不過在 application.properties 中只能實現對日志一些非常簡單的配置,如果想實現更加細粒度的日志配置,那就需要使用日志實現的原生配置,例如?Logback?的?classpath:logback.xml,Log4j?的?classpath:log4j.xml?等。如果這些日志配置文件存在于 classpath 下,那么默認情況下,Spring Boot 就會自動加載這些配置文件。
2.2 Logback 配置
2.2.1 基本配置
默認的?Logback?配置文件名有兩種:
logback.xml:這種配置文件會直接被日志框架加載。logback-spring.xml:這種配置文件不會被日志框架直接加載,而是由 Spring Boot 去解析日志配置,可以使用 Spring Boot 的高級 Profile 功能。
Spring Boot 中為?Logback?提供了四個默認的配置文件,位置在?org/springframework/boot/logging/logback/,分別是:
- defaults.xml:提供了公共的日志配置,日志輸出規則等。
- console-appender.xml:使用 CONSOLE_LOG_PATTERN 添加一個ConsoleAppender。
- file-appender.xml:添加一個 RollingFileAppender。
- base.xml:為了兼容舊版 Spring Boot 而提供的。
如果需要自定義?logback.xml?文件,可以在自定義時使用這些默認的配置文件,也可以不使用。一個典型的?logback.xml?文件如下(resources/logback.xml):
<?xml ?version="1.0"?encoding="UTF-8"?>
<configuration>
????<include?resource="org/springframework/boot/logging/logback/defaults.xml"/>
????<include?resource="org/springframework/boot/logging/logback/console-appender.xml"?/>
????<root?level="INFO">
????????<appender-ref?ref="CONSOLE"?/>
????root>
????<logger?name="org.springframework.web"?level="DEBUG"/>
configuration>
可以通過 include 引入 Spring Boot 已經提供的配置文件,也可以自定義。
2.2.2 輸出到文件
如果想禁止控制臺的日志輸出,轉而將日志內容輸出到一個文件,我們可以自定義一個?logback-spring.xml?文件,并引入前面所說的?file-appender.xml?文件。
像下面這樣(resources/logback-spring.xml):
<?xml ?version="1.0"?encoding="UTF-8"?>
<configuration>
????<include?resource="org/springframework/boot/logging/logback/defaults.xml"?/>
????<property?name="LOG_FILE"?value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
????<include?resource="org/springframework/boot/logging/logback/file-appender.xml"?/>
????<root?level="INFO">
????????<appender-ref?ref="FILE"?/>
????root>
configuration>
2.3 Log4j 配置
如果 classpath 下存在?Log4j2?的依賴,Spring Boot 會自動進行配置。
默認情況下 classpath 下當然不存在?Log4j2?的依賴,如果想使用?Log4j2,可以排除已有的?Logback,然后再引入?Log4j2,如下:
<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-webartifactId>
????<exclusions>
????????<exclusion>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-loggingartifactId>
????????exclusion>
????exclusions>
dependency>
<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-log4j2artifactId>
dependency>
Log4j2?的配置就比較容易了,在 reources 目錄下新建 log4j2.xml 文件,內容如下:
<?xml ?version="1.0"?encoding="UTF-8"?>
<configuration?status="warn">
????<properties>
????????<Property?name="app_name">loggingProperty>
????????<Property?name="log_path">logs/${app_name}Property>
????properties>
????<appenders>
????????<console?name="Console"?target="SYSTEM_OUT">
????????????<PatternLayout?pattern="[%d][%t][%p][%l]?%m%n"?/>
????????console>
????????<RollingFile?name="RollingFileInfo"?fileName="${log_path}/info.log"filePattern="${log_path}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz">
????????????<Filters>
????????????????<ThresholdFilter?level="INFO"?/>
????????????????<ThresholdFilter?level="WARN"?onMatch="DENY"onMismatch="NEUTRAL"?/>
????????????Filters>
????????????<PatternLayout?pattern="[%d][%t][%p][%c:%L]?%m%n"?/>
????????????<Policies>
????????????????<TimeBasedTriggeringPolicy?interval="1"?modulate="true"?/>
????????????????<SizeBasedTriggeringPolicy?size="2?MB"?/>
????????????Policies>
????????????<DefaultRolloverStrategy?compressionLevel="0"?max="10"/>
????????RollingFile>
????????<RollingFile?name="RollingFileWarn"?fileName="${log_path}/warn.log"filePattern="${log_path}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz">
????????????<Filters>
????????????????<ThresholdFilter?level="WARN"?/>
????????????????<ThresholdFilter?level="ERROR"?onMatch="DENY"onMismatch="NEUTRAL"?/>
????????????Filters>
????????????<PatternLayout?pattern="[%d][%t][%p][%c:%L]?%m%n"?/>
????????????<Policies>
????????????????<TimeBasedTriggeringPolicy?interval="1"?modulate="true"?/>
????????????????<SizeBasedTriggeringPolicy?size="2?MB"?/>
????????????Policies>
????????????<DefaultRolloverStrategy?compressionLevel="0"?max="10"/>
????????RollingFile>
????????<RollingFile?name="RollingFileError"?fileName="${log_path}/error.log"filePattern="${log_path}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz">
????????????<ThresholdFilter?level="ERROR"?/>
????????????<PatternLayout?pattern="[%d][%t][%p][%c:%L]?%m%n"?/>
????????????<Policies>
????????????????<TimeBasedTriggeringPolicy?interval="1"?modulate="true"?/>
????????????????<SizeBasedTriggeringPolicy?size="2?MB"?/>
????????????Policies>
????????????<DefaultRolloverStrategy?compressionLevel="0"?max="10"/>
????????RollingFile>
????appenders>
????<loggers>
????????<root?level="info">
????????????<appender-ref?ref="Console"?/>
????????????<appender-ref?ref="RollingFileInfo"?/>
????????????<appender-ref?ref="RollingFileWarn"?/>
????????????<appender-ref?ref="RollingFileError"?/>
????????root>
????loggers>
configuration>
首先在 properties 節點中指定了應用名稱以及日志文件位置。
然后通過幾個不同的 RollingFile 對不同級別的日志分別處理,不同級別的日志將輸出到不同的文件,并按照各自的命名方式進行壓縮。
這段配置比較程式化,小伙伴們可以保存下來做成 IntelliJ IDEA 模版以便日常使用。
推薦:程序員求職面試分享程序員找工作經驗
程序員筆試、面試題
總結
以上是生活随笔為你收集整理的log4j 压缩日志_Spring Boot 日志各种使用姿势,是时候捋清楚了!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个关于龙的微信网名
- 下一篇: jmeter异步请求测试怎么测试_JMe