记录一个点:
很多时候,生产环境的log4j appender会设置bufferIO。但是系统意外挂了就会丢失部分日志。通过下面的语句flush log4j的日志:
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); } }
PS:可能要增加一个java代码的钩子, 在系统关闭的时候触发。
//增加关闭钩子 Runtime.getRuntime().addShutdownHook(new Thread(){ public void run(){ //STH TODO } }); //移除关闭钩子 Runtime.getRuntime().removeShutdownHook(hook);
其实是“参考” stackoverflow的:
http://stackoverflow.com/questions/3060240/how-do-you-flush-a-buffered-log4j-fileappender