在log4j中,当使用带有BufferedIO=true和BufferSize=xxx属性的FileAppender(即启用缓冲)时,我想在正常关闭过程中刷新日志。有什么建议吗?
关闭LogManager时:
LogManager.shutdown();
所有缓存的日志都会被刷新。
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);
}
}
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();
}
}
}
}
对我来说唯一有效的解决方案是等待一段时间:
private void flushAppender(Appender appender) {
// this flush seems to be useless
((AbstractOutputStreamAppender<?>) appender).getManager().flush();
try {
Thread.sleep(500); // wait for log4j to flush logs
} catch (InterruptedException ignore) {
}
}
WriterAppender#shouldFlush(LoggingEvent)
方法,使其对于特定的日志类别(例如log4j.flush.now
)返回true
,然后调用以下代码:LoggerFactory.getLogger("log4j.flush.now").info("Flush")
尝试:
LogFactory.releaseAll();