2013-10-01 96 views
4

我編寫了一個測試程序來驗證log4j比log4j的性能改進。但令我驚訝的是,我遇到了這個奇怪的問題。我正在使用他們的異步和文件appender將一些200k日誌消息寫入一個循環中。但是,每次只記錄約14萬條消息並在此之後停止。它只是打印我的最後一個日誌語句,表明它已經將所有內容寫入了緩衝區,程序終止。如果我只是運行與Log4j相同的程序,我可以看到日誌文件中的所有200k消息。發生這種情況是否存在任何基本的架構差異?無論如何要避免它?我們正在考慮從log4j切換到logback,現在這讓我重新思考。Logback丟失我的日誌消息到文件

這是我的logback configuraiton:

<configuration> 
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
    <encoder> 
     <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 
     </pattern> 
    </encoder> 
</appender> 

<appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
<file>logback.log</file> 
<encoder> 
    <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> 
</encoder> 
</appender> 

<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> 
    <appender-ref ref="FILE" /> 
</appender> 

<root level="info"> 
    <appender-ref ref="ASYNC" /> 
</root> 
</configuration> 

這是我的代碼------------------

 public static void main(String[] args) throws InterruptedException { 
     org.slf4j.Logger logbackLogger = LoggerFactory 
       .getLogger(LogbackTest.class); 

     List<Integer> runs = Arrays.asList(1000, 5000, 50000, 200000); 
     ArrayList<Long> logbackRuntimes = new ArrayList<>(4); 

     for (int run = 0; run < runs.size(); run++) { 
      logbackLogger.info("------------------------>Starting run: " 
        + (run + 1)); 
      // logback test 
      long stTime = System.nanoTime(); 
      int i = 0; 
      for (i = 1; i <= runs.get(run); i++) { 
       Thread.sleep(1); 
       logbackLogger 
       .info("This is a Logback test log, run: {},  iter: {}", 
           run, i); 
      } 
      logbackRuntimes.add(System.nanoTime() - stTime); 
      logbackLogger.info("logback run - " + (run + 1) + " " + i); 
     } 
     Thread.sleep(5000); 
     // print results 
     logbackLogger.info("Run times:"); 
     logbackLogger 
      .info("Run\tNoOfMessages\tLog4j Time(ms)\tLogback Time(ms)"); 
     for (int run = 0; run < runs.size(); run++) { 
      logbackLogger.info((run + 1) + "\t" + runs.get(run) + "\t" 
        + logbackRuntimes.get(run)/10e6d); 
     } 
    } 

回答

6

the documentation

默認情況下,當少於隊列容量的20%時,AsyncAppender會刪除級別爲TRACE,DEBUG和INFO的事件,只保留事件級別警告和錯誤。這種策略可以在隊列的容量低於20%時,以TRACE,DEBUG和INFO級別的事件爲代價來確保非阻塞處理記錄事件(因此具有出色的性能)。通過將discardingThreshold屬性設置爲0(零)可以防止事件丟失。