2010-06-17 3 views
16

log4j에서 BufferedIO = true 및 BufferSize = xxx 속성을 사용하는 FileAppender를 사용할 때 (즉, 버퍼링이 사용 가능할 때) 정상적인 종료 절차 중에 로그를 플러시 할 수 있기를 원합니다. 이 작업을 수행하는 방법에 대한 아이디어가 있습니까?어떻게 버퍼링 된 log4j FileAppender를 플러시합니까?

+0

Log4J는 정상 종료 중에 appender를 자동으로 플러시하지 않습니까? 나는 그렇게 할 것을 적어도 기대할 것이다. –

+1

코드를 이해함에 따라 BufferedIO를 결정할 때 플러시가 발생하지 않습니다. 당신은 성능을 얻지 만 가격을 지불합니다 : 마지막 로그 엔트리를 잃어 버릴 것입니다 ... –

+0

(DB에 대해서,하지만 정말로 중요하지는 않지만) 자신의 appender를 썼을 때 자동으로 플러시되는 동안 버퍼 된 출력을했습니다. – ripper234

답변

6
public static void flushAllLogs() 
{ 
    try 
    { 
     Set<FileAppender> flushedFileAppenders = new HashSet<FileAppender>(); 
     Enumeration currentLoggers = LogManager.getLoggerRepository().getCurrentLoggers(); 
     while(currentLoggers.hasMoreElements()) 
     { 
      Object nextLogger = currentLoggers.nextElement(); 
      if(nextLogger instanceof Logger) 
      { 
       Logger currentLogger = (Logger) nextLogger; 
       Enumeration allAppenders = currentLogger.getAllAppenders(); 
       while(allAppenders.hasMoreElements()) 
       { 
        Object nextElement = allAppenders.nextElement(); 
        if(nextElement instanceof FileAppender) 
        { 
         FileAppender fileAppender = (FileAppender) nextElement; 
         if(!flushedFileAppenders.contains(fileAppender) && !fileAppender.getImmediateFlush()) 
         { 
          flushedFileAppenders.add(fileAppender); 
          //log.info("Appender "+fileAppender.getName()+" is not doing immediateFlush "); 
          fileAppender.setImmediateFlush(true); 
          currentLogger.info("FLUSH"); 
          fileAppender.setImmediateFlush(false); 
         } 
         else 
         { 
          //log.info("fileAppender"+fileAppender.getName()+" is doing immediateFlush"); 
         } 
        } 
       } 
      } 
     } 
    } 
    catch(RuntimeException e) 
    { 
     log.error("Failed flushing logs",e); 
    } 
} 
+0

작업을 완료 한 것 같습니다. 감사! – Amos

+0

이렇게하면 모든 로거가 플러시되지 않습니다. 모두 플러시하려면 각 로거에서 getParent()를 반복적으로 호출하고 이러한 로거를 플러시해야합니다. – h22

0

봅니다 :

LogManager.shutdown(); 

버퍼링 된 모든 로그를 플러시 :

LogFactory.releaseAll(); 
+1

이 전화는 불행히도 효과가 없었습니다. – Amos

35

:-)

LogManager에 종료

내 자신의 질문을 대답 할 수 있었다.

+6

답변으로 선택하십시오 - 분명히 가장 좋은 옵션입니다. 다른 사람에게서 녹색 진드기를 제거하는 것에 대해 불쾌감을 느끼지 마십시오. –

+0

이것이 가장 좋은 답변처럼 보입니다.하지만 어떻게이 "LogManager"개체에 액세스합니까? (log4php 초보자) –

0

내가 펜더를 작성했습니다 그 이 문제를 해결하려면 GitHub을 참조하거나 name.wramner.log4j : Maven의 FlushAppender를 사용하십시오. 심각도가 높은 이벤트를 플러시하도록 구성 할 수 있으며 특정 메시지 (예 : "시스템 종료 중")를 수신하면 appender가 버퍼링되지 않도록 만들 수 있습니다. 단위 테스트에서 구성 예제를 확인하십시오. 물론 무료입니다.

3
public static void flushAll() { 
    final LoggerContext logCtx = ((LoggerContext) LogManager.getContext()); 
    for(final org.apache.logging.log4j.core.Logger logger : logCtx.getLoggers()) { 
     for(final Appender appender : logger.getAppenders().values()) { 
      if(appender instanceof AbstractOutputStreamAppender) { 
       ((AbstractOutputStreamAppender) appender).getManager().flush(); 
      } 
     } 
    } 
} 
+0

이 코드는 질문에 대답 할 수 있지만, 어떻게 그리고/또는 왜 문제를 해결하는지에 대한 추가 컨텍스트를 제공하면 대답의 장기적인 가치가 향상됩니다. –

+0

이 코드는 모든 flushable appenders ("flush"메서드가 선언 된 AbstractOutputStreamAppender를 확장하는 모든 appender)를 플러시하려고합니다. 내 프로젝트에서 Log4J2 v2.8.2와 함께 사용. –