¿Cómo se vacia un archivo log4j FileAppender?

En log4j, cuando se utiliza FileAppender con BufferedIO = true y BufferSize = xxx properties (es decir, el almacenamiento en búfer está habilitado), quiero poder vaciar el registro durante el procedimiento de apagado normal. ¿Alguna idea sobre cómo hacer esto?

public static void flushAllLogs() { try { Set flushedFileAppenders = new HashSet(); 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); } } 

Logré responder mi propia pregunta 🙂

Al apagar el LogManager:

 LogManager.shutdown(); 

todos los registros almacenados en el búfer se enrojecen.

 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(); } } } } 

Tal vez podría anular WriterAppender#shouldFlush( LoggingEvent ) , por lo que devolvería true para una categoría de registro especial, como log4j.flush.now , y luego llamaría a:

 LoggerFactory.getLogger("log4j.flush.now").info("Flush") 

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/WriterAppender.html#shouldFlush%28org.apache.log4j.spi.LoggingEvent%29

Tratar:

 LogFactory.releaseAll(); 

He escrito un appender que soluciona esto, vea GitHub o use name.wramner.log4j: FlushAppender en Maven. Se puede configurar para nivelar los eventos con una gran severidad y puede hacer que los appenders no sean almacenados cuando recibe un mensaje específico, por ejemplo “Shutting down”. Verifique las pruebas unitarias para ver ejemplos de configuración. Es gratis, por supuesto.