Java循环日志

现在大多情况下都使用日志组件,比如log4j、log4j2,这些组件的好处是比较通用,同时鉴于软件开发中的拿来主义,尽量用现成的代码减小工作任务,同时公用的框架能避免自己花大量时间去测试,因为大家都在测试;另一方面,使用日志组件比较简单,只要配置配置就好了。但是有的情况下,第三方组件不能满足日志需求,需要实现循环日志,或者想探究循环日志实现原理是什么,怎么去做呢

本文基于Jdk8,记录实现循环日志的基本原理和测试代码。主要分为三步:

  1. 对java.util.logging.Logger进行包装;
    Logger自从JDK1.4添加,是JDK自带的Logger,对Logger进行包装主要可以从Logger命名、使用工厂模式进行构建等非功能性需求。

  2. 配置FileHandler
    配置FileHandler主要配置循环日志目录以及文件命名,输出的日志格式,循环日志数目,每个循环日志文件的大小。关于循环日志输出的主要代码在FileHandler类中,以下方法是FileHandler中方法,主要用于日志文件重命名和新文件创建(PS,编辑器真不好用,是我不会用吗)。

    private synchronized void rotate() {
    Level oldLevel = getLevel();
    setLevel(Level.OFF);

     super.close();
     for (int i = count-2; i >= 0; i--) {
         File f1 = files[i];
         File f2 = files[i+1];
         if (f1.exists()) {
             if (f2.exists()) {
                 f2.delete();
             }
             f1.renameTo(f2);
         }
     }
     try {
         open(files[0], false);
     } catch (IOException ix) {
         // We don't want to throw an exception here, but we
         // report the exception to any registered ErrorManager.
         reportError(null, ix, ErrorManager.OPEN_FAILURE);
    
     }
     setLevel(oldLevel);
    

    }

  3. 配置MemoryHandler并绑定到Logger
    MemoryHandler主要用于绑定FileHandler,指定缓存大小以及日志级别等,实现异步日志。

示例:

public class MyLogger {

    private Logger logger;

    protected MyLogger(String name) {
        
        logger = Logger.getLogger(name);
    }
    
    public Boolean configureLogger(String filePattern, int count, int bufferSize, int limit, Formatter format) {
        
        try {
            FileHandler fileHandler = new FileHandler(filePattern, limit, count);
            fileHandler.setFormatter(format);
            MemoryHandler memHandler = new MemoryHandler(fileHandler, bufferSize, Level.INFO);
            logger.addHandler(memHandler);
        }
        catch (SecurityException | IOException e) {
            
            e.printStackTrace();
            return false;
        }
        return true;
    }
    
    public void info(String msg) {

       logger.info(msg);
    }

    public static class SimpleLogFormatter extends Formatter {

        @Override
        public String format(LogRecord record) {

            return record.getMessage();

        }
    }
}

测试类:

public class TestLogger {

    public static void main(String[] args) {

        MyLogger myLogger = new MyLogger("test");
        myLogger.configureLogger("/TEST/test.log", 3, 10, 10240, new MyLogger.SimpleLogFormatter());
        
        for(int index=0; index<10000; index++) {
            myLogger.info("test log" + index);
        }
    }

}

测试结果:

  1. 生成test.log.0,test.log.1, test.log.2文件
  2. 日志文件大小为10K(实际显示为11k)
  3. 日志循环输出

猜你喜欢

转载自blog.csdn.net/qq_36101933/article/details/83349744
今日推荐