您好,登錄后才能下訂單哦!
這篇文章主要講解了“高性能日志工具Log4j2的優點有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“高性能日志工具Log4j2的優點有哪些”吧!
1)在多線程場景下,Log4j 2 的吞吐量比 Logback 高出了 10 倍,延遲降低了幾個數量級。這話聽起來像吹牛,反正是 Log4j 2 官方自己吹的。
Log4j 2 的異步 Logger 使用的是無鎖數據結構,而 Logback 和 Log4j 的異步 Logger 使用的是 ArrayBlockingQueue。對于阻塞隊列,多線程應用程序在嘗試使日志事件入隊時通常會遇到鎖爭用。
下圖說明了多線程方案中無鎖數據結構對吞吐量的影響。 Log4j 2 隨著線程數量的擴展而更好地擴展:具有更多線程的應用程序可以記錄更多的日志。其他日志記錄庫由于存在鎖競爭的關系,在記錄更多線程時,總吞吐量保持恒定或下降。這意味著使用其他日志記錄庫,每個單獨的線程將能夠減少日志記錄。
性能方面是 Log4j 2 的最大亮點,至于其他方面的一些優勢,比如說下面這些,可以忽略不計,文字有多短就代表它有多不重要。
2)Log4j 2 可以減少垃圾收集器的壓力。
3)支持 Lambda 表達式。
4)支持自動重載配置。
廢話不多說,直接實操開干。理論知識有用,但不如上手實操一把,這也是我多年養成的一個“不那么良好”的編程習慣:在實操中發現問題,解決問題,尋找理論基礎。
第一步,在 pom.xml 文件中添加 Log4j 2 的依賴:
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.5</version> </dependency>
(這個 artifactId 還是 log4j,沒有體現出來 2,而在 version 中體現,多少叫人誤以為是 log4j)
第二步,來個最簡單的測試用例:
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class Demo { private static final Logger logger = LogManager.getLogger(Demo.class); public static void main(String[] args) { logger.debug("log4j2"); } }
運行 Demo 類,可以在控制臺看到以下信息:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
Log4j 2 竟然沒有在控制臺打印“ log4j2”,還抱怨我們沒有為它指定配置文件。在這一點上,我就覺得它沒有 Logback 好,畢竟人家會輸出。
這對于新手來說,很不友好,因為新手在遇到這種情況的時候,往往不知所措。日志里面雖然體現了 ERROR,但代碼并沒有編譯出錯或者運行出錯,憑什么你不輸出?
那作為編程老鳥來說,我得告訴你,這時候最好探究一下為什么。怎么做呢?
我們可以復制一下日志信息中的關鍵字,比如說:“No log4j2 configuration file found”,然后在 Intellij IDEA 中搜一下,如果你下載了源碼和文檔的話,不除意外,你會在 ConfigurationFactory 類中搜到這段話。
可以在方法中打個斷點,然后 debug 一下,你就會看到下圖中的內容。
通過源碼,你可以看得到,Log4j 2 會去尋找 4 種類型的配置文件,后綴分別是 properties、yaml、json 和 xml。前綴是 log4j2-test 或者 log4j2。
得到這個提示后,就可以進行第三步了。
**第三步,**在 resource 目錄下增加 log4j2-test.xml 文件(方便和 Logback 做對比),內容如下所示:
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="DEBUG"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
Log4j 2 的配置文件格式和 Logback 有點相似,基本的結構為 < Configuration>
元素,包含 0 或多個 < Appenders>
元素,其后跟 0 或多個 < Loggers>
元素,里面再跟最多只能存在一個的 < Root>
元素。
1)配置 appender,也就是配置日志的輸出目的地。
有 Console,典型的控制臺配置信息上面你也看到了,我來簡單解釋一下里面 pattern 的格式:
%d{HH:mm:ss.SSS}
表示輸出到毫秒的時間
%t
輸出當前線程名稱
%-5level
輸出日志級別,-5 表示左對齊并且固定輸出 5 個字符,如果不足在右邊補空格
%logger
輸出 logger 名稱,最多 36 個字符
%msg
日志文本
%n
換行
順帶補充一下其他常用的占位符:
%F
輸出所在的類文件名,如 Demo.java
%L
輸出行號
%M
輸出所在方法名
%l
輸出語句所在的行數, 包括類名、方法名、文件名、行數
%p
輸出日志級別
%c
輸出包名,如果后面跟有 {length.}
參數,比如說 %c{1.}
,它將輸出報名的第一個字符,如 com.itwanger
的實際報名將只輸出 c.i
再次運行 Demo 類,就可以在控制臺看到打印的日志信息了:
10:14:04.657 [main] DEBUG com.itwanger.Demo - log4j2
2)配置 Loggers,指定 Root 的日志級別,并且指定具體啟用哪一個 Appenders。
3)自動重載配置。
Logback 支持自動重載配置,Log4j 2 也支持,那想要啟用這個功能也非常簡單,只需要在 Configuration 元素上添加 monitorInterval
屬性即可。
<Configuration monitorInterval="30"> ... </Configuration>
注意值要設置成非零,上例中的意思是至少 30 秒后檢查配置文件中的更改。最小間隔為 5 秒。
除了 Console,還有 Async,可以配合文件的方式來異步寫入,典型的配置信息如下所示:
<Configuration> <Appenders> <File name="DebugFile" fileName="debug.log"> <PatternLayout> <Pattern>%d %p %c [%t] %m%n</Pattern> </PatternLayout> </File> <Async name="Async"> <AppenderRef ref="DebugFile"/> </Async> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="Async"/> </Root> </Loggers> </Configuration>
對比 Logback 的配置文件來看,Log4j 2 真的復雜了一些,不太好用,就這么直白地說吧!但自己約的,含著淚也得打完啊。把這個 Async 加入到 Appenders:
<Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> <File name="DebugFile" fileName="debug.log"> <PatternLayout> <Pattern>%d %p %c [%t] %m%n</Pattern> </PatternLayout> </File> <Async name="Async"> <AppenderRef ref="DebugFile"/> </Async> </Appenders> <Loggers> <Root level="DEBUG"> <AppenderRef ref="Console"/> <AppenderRef ref="Async"/> </Root> </Loggers> </Configuration>
再次運行 Demo 類,可以在項目根路徑下看到一個 debug.log 文件,內容如下所示:
2020-10-30 09:35:49,705 DEBUG com.itwanger.Demo [main] log4j2
當然了,Log4j 和 Logback 我們都配置了 RollingFile,Log4j 2 也少不了。RollingFile 會根據 Triggering(觸發)策略和 Rollover(過渡)策略來進行日志文件滾動。如果沒有配置 Rollover,則使用 DefaultRolloverStrategy 來作為 RollingFile 的默認配置。
觸發策略包含有,基于 cron 表達式(源于希臘語,時間的意思,用來配置定期執行任務的時間格式)的 CronTriggeringPolicy;基于文件大小的 SizeBasedTriggeringPolicy;基于時間的 TimeBasedTriggeringPolicy。
過渡策略包含有,默認的過渡策略 DefaultRolloverStrategy,直接寫入的 DirectWriteRolloverStrategy。一般情況下,采用默認的過渡策略即可,它已經足夠強大。
來看第一個基于 SizeBasedTriggeringPolicy 和 TimeBasedTriggeringPolicy 策略,以及缺省 DefaultRolloverStrategy 策略的配置示例:
<Configuration> <Appenders> <RollingFile name="RollingFile" fileName="rolling.log" filePattern="rolling-%d{yyyy-MM-dd}-%i.log"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="1 KB"/> </Policies> </RollingFile> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
為了驗證文件的滾動策略,我們調整一下 Demo 類,讓它多打印點日志:
for (int i = 1;i < 20; i++) { logger.debug("微信搜索「{}」,回復關鍵字「{}」,有驚喜哦","沉默王二", "java"); }
再次運行 Demo 類,可以看到根目錄下多了 3 個日志文件:
結合日志文件名,再來看 RollingFile 的配置,就很容易理解了。
1)fileName 用來指定文件名。
2)filePattern 用來指定文件名的模式,它取決于過渡策略。
由于配置文件中沒有顯式指定過渡策略,因此 RollingFile 會啟用默認的 DefaultRolloverStrategy。
先來看一下 DefaultRolloverStrategy 的屬性:
再來看 filePattern 的值 rolling-%d{yyyy-MM-dd}-%i.log
,其中 %d{yyyy-MM-dd}
很好理解,就是年月日;其中 %i
是什么意思呢?
第一個日志文件名為 rolling.log(最近的日志放在這個里面),第二個文件名除去日期為 rolling-1.log,第二個文件名除去日期為 rolling-2.log,根據這些信息,你能猜到其中的規律嗎?
其實和 DefaultRolloverStrategy 中的 max 屬性有關,目前使用的默認值,也就是 7,那就當 rolling-8.log 要生成的時候,刪除 rolling-1.log。可以調整 Demo 中的日志輸出量來進行驗證。
3)SizeBasedTriggeringPolicy,基于日志文件大小的時間策略,大小以字節為單位,后綴可以是 KB,MB 或 GB,例如 20 MB。
再來看一個日志文件壓縮的示例,來看配置:
<RollingFile name="RollingFileGZ" fileName="gz/rolling.log" filePattern="gz/%d{yyyy-MM-dd-HH}-%i.rolling.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="1 KB"/> </Policies> </RollingFile>
fileName 的屬性值中包含了一個目錄 gz,也就是說日志文件都將放在這個目錄下。
filePattern 的屬性值中增加了一個 gz 的后綴,這就表明日志文件要進行壓縮了,還可以是 zip 格式。
運行 Demo 后,可以在 gz 目錄下看到以下文件:
感謝各位的閱讀,以上就是“高性能日志工具Log4j2的優點有哪些”的內容了,經過本文的學習后,相信大家對高性能日志工具Log4j2的優點有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。