使用log4j记录日志_使用log4j2免费分配日志记录
使用log4j記錄日志
介紹
最近,我正在為一個客戶端工作,試圖為大型精心制作的Java系統消除一些GC暫停。 經過分析后,我意識到大部分垃圾都是通過日志記錄產生的! 是否有一種簡單的方法來刪除所有分配? 原來有:)
我應該使用哪個框架進行GC免費日志記錄?
讓我們將注意力轉向使用哪個日志記錄框架的古老問題。
通常的候選人是
- log4j2
- 登回
- java.util.logging
- slf4j(簡單)
除非您做的是超級時髦的東西,否則您可能不會認為這會給您帶來很大的改變。
已經進行了許多比較性能的研究,如果您在超低延遲的競技場中玩,那當然很重要。 ( 請參閱對Java日志記錄框架進行基準測試 )
但是我擔心的是分配!
請參閱我之前有關分配的弊端的文章“性能優化的第一條規則”。
在典型的系統中,所有分配的30%-50%可以記錄在日志中! 因此,即使大多數人不介意在一個框架中進行日志記錄的時間比在另一個框架中花費幾毫秒的時間,他們幾乎肯定會在乎日志框架所產生的垃圾導致的長時間GC暫停。
而且所有這些日志記錄分配都可以通過簡單的配置刪除。 從2.6開始的Log4J2是免費分配的,因此沒有任何借口不利用它:)
讓我們看看它的作用
提出免分配索賠是一回事,但讓我們看看這在實踐中是否成立。
考慮下面的這個簡單的日志記錄代碼:請注意,我在代碼中使用了slf4j,因此只需更改配置即可在不同的日志記錄框架中運行。 這樣做是個好主意,因為盡管log4j2可能是目前最好的框架,但誰知道明天會帶來什么……
package test;import org.slf4j.Logger; import org.slf4j.LoggerFactory;import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream;public class GCLogger {private final static Logger LOGGER = LoggerFactory.getLogger(GCLogger.class);public static void main(String[] args) throws InterruptedException {List<String> list = IntStream.range(0,(int)1e6).mapToObj(i->"" + i).collect(Collectors.toList());//Log 1 million lines in a loop sleeping 1 second between each iteration of the loop//to allow time to run Flight Recorder.for (int i = 0; i < 1000; i++) {list.forEach(s->LOGGER.info("Logging [{}]", s));Thread.sleep(1000);}} }使用log4j2運行–無分配
如果我們使用以下Maven配置將程序配置為與log4j2一起運行:
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version> </dependency> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.9.1</version> </dependency> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.9.1</version> </dependency> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.9.1</version> </dependency>我們使用此log4j2配置
xml version="1.0" encoding="UTF-8" ?><Configuration status="INFO"><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{HH:mm:ss:SSS} [%t] %-5level %logger[36] %msg%n"></PatternLayout></Console><File name="MyFile" fileName="all.log" immeadiateFlush="false" append="false"><PatternLayout pattern="%d{dd MMM yyyy HH:mm:ss,SSS} [%t] %-5level %logger[36] %msg%n"></PatternLayout></File></Appenders><Loggers><Root level="debug"><AppenderRef ref="MyFile"></AppenderRef></Root></Loggers> </Configuration>然后我們得到0分配!
我們可以通過在程序上運行Flight Recorder來證明這一點(見下文):
唯一分配的內存歸因于Flight Recorder(通過配置FR的方式,這樣就不會發生這種情況)。
使用登錄運行
使用Logback嘗試完全相同。
使用此Maven配置
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version> </dependency>使用此注銷配置:
<configuration><appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>myApp.log</file><encoder><pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern></encoder></appender><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%msg%n</pattern></encoder></appender><root level="debug"><appender-ref ref="FILE" /></root> </configuration>當我們使用Flight Recorder運行時,我們會看到一個擁抱量分配!
但是有一點警告……。
您需要完全按照文檔中的說明使用log4j2配置,請參閱支持的布局 。 如果您甚至更改日期格式,則略微分配將再次猖ramp。
摘要
- 使用slf4j,以便您可以輕松更改日志記錄實現
- 使用log4j2避免分配
- 確保使用支持的格式來支持免費分配日志記錄
翻譯自: https://www.javacodegeeks.com/2017/10/allocation-free-logging-log4j2.html
使用log4j記錄日志
總結
以上是生活随笔為你收集整理的使用log4j记录日志_使用log4j2免费分配日志记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hashmap java_Java –
- 下一篇: 小米 Redmi Note 13 Pro