log4j에서 BufferedIO = true 및 BufferSize = xxx 속성을 사용하는 FileAppender를 사용할 때 (즉, 버퍼링이 사용 가능할 때) 정상적인 종료 절차 중에 로그를 플러시 할 수 있기를 원합니다. 이 작업을 수행하는 방법에 대한 아이디어가 있습니까?어떻게 버퍼링 된 log4j FileAppender를 플러시합니까?
답변
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);
}
}
봅니다 :
LogManager.shutdown();
버퍼링 된 모든 로그를 플러시 :
LogFactory.releaseAll();
이 전화는 불행히도 효과가 없었습니다. – Amos
:-)
LogManager에 종료
내 자신의 질문을 대답 할 수 있었다.답변으로 선택하십시오 - 분명히 가장 좋은 옵션입니다. 다른 사람에게서 녹색 진드기를 제거하는 것에 대해 불쾌감을 느끼지 마십시오. –
이것이 가장 좋은 답변처럼 보입니다.하지만 어떻게이 "LogManager"개체에 액세스합니까? (log4php 초보자) –
이 log4j.flush.now
같은 특정 로깅 범주에 대한 true
을 반환 그래서 어쩌면 당신은, WriterAppender#shouldFlush(LoggingEvent)
을 무시할 수 있고, 당신은 전화 :
LoggerFactory.getLogger("log4j.flush.now").info("Flush")
내가 펜더를 작성했습니다 그 이 문제를 해결하려면 GitHub을 참조하거나 name.wramner.log4j : Maven의 FlushAppender를 사용하십시오. 심각도가 높은 이벤트를 플러시하도록 구성 할 수 있으며 특정 메시지 (예 : "시스템 종료 중")를 수신하면 appender가 버퍼링되지 않도록 만들 수 있습니다. 단위 테스트에서 구성 예제를 확인하십시오. 물론 무료입니다.
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();
}
}
}
}
이 코드는 질문에 대답 할 수 있지만, 어떻게 그리고/또는 왜 문제를 해결하는지에 대한 추가 컨텍스트를 제공하면 대답의 장기적인 가치가 향상됩니다. –
이 코드는 모든 flushable appenders ("flush"메서드가 선언 된 AbstractOutputStreamAppender를 확장하는 모든 appender)를 플러시하려고합니다. 내 프로젝트에서 Log4J2 v2.8.2와 함께 사용. –
Log4J는 정상 종료 중에 appender를 자동으로 플러시하지 않습니까? 나는 그렇게 할 것을 적어도 기대할 것이다. –
코드를 이해함에 따라 BufferedIO를 결정할 때 플러시가 발생하지 않습니다. 당신은 성능을 얻지 만 가격을 지불합니다 : 마지막 로그 엔트리를 잃어 버릴 것입니다 ... –
(DB에 대해서,하지만 정말로 중요하지는 않지만) 자신의 appender를 썼을 때 자동으로 플러시되는 동안 버퍼 된 출력을했습니다. – ripper234