В log4j при использовании свойств FileAppender с BufferedIO = true и BufferSize = xxx (т.е. буферизация включена), я хочу, чтобы можно было очистить журнал во время обычной процедуры выключения. Любые идеи о том, как это сделать?
Как вы очищаете буферный файл log4j FileAppender?
Ответ 1
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);
}
}
Ответ 2
Удалось ответить на мой вопрос: -)
При выключении LogManager:
LogManager.shutdown();
все буферизованные журналы очищаются.
Ответ 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();
}
}
}
}
Ответ 4
Может быть, вы можете переопределить WriterAppender#shouldFlush( LoggingEvent )
, чтобы он возвращал true
для специальной категории ведения журнала, например log4j.flush.now
, а затем вы вызываете:
LoggerFactory.getLogger("log4j.flush.now").info("Flush")
Ответ 5
Try:
LogFactory.releaseAll();
Ответ 6
Я написал приложение, которое исправляет это, см. GitHub или используйте имя .wramner.log4j: FlushAppender в Maven. Он может быть сконфигурирован для кратковременного включения событий с высокой степенью серьезности и может сделать приложение небуферизованным, когда оно получает конкретное сообщение, например "Выключение". Проверьте тесты модулей для примеров конфигурации. Это бесплатно, конечно.