log4j2异步及最佳实践

  1. 这里是列表文本log4j可以配置输出到不同的地方,比如console,file,sockete,mq等

  2. 每一种都输出都可以配置成异步的,包裹一下就可以了,具体看官网配置

  3. 所谓的异步,其实就是生产者和消费者模式,不再每次直接写文件,而是把把日志封装成log event,丢到一个queue里面,这个queue使用的是ArrayBlockingQueue,并且不提供配置项进行配置,queue的大小为128,也不提供配置。取出的时候使用queue.take()方法,如果queue里面没有数据,则等待

  4. 对于RollingFileAppender,默认bufferedIO 为true,底层对应的使用BufferedOutputStream,bufferSize 为8192bytes,这个也是BufferedOutputStream的默认配置。如果bufferedIO为false,则使用的是不带buffer的FileOutputStream

  5. RollingFileAppender中的immediateFlush这个值默认是true,表示每次写入后都会flush操作,这个可以确保日志可以及时的写入磁盘,但是效率较低。这个配置无论对于同步和异步都起作用。但是对于异步,应该把immediateFlush设为false,这样的话,Asynchronous loggers and appenders will automatically flush at the end of a batch of events ,意思即批量刷,从如下代码也可以看出来

public void append(final LogEvent event) {
       readLock.lock();
       try {
           final byte[] bytes = getLayout().toByteArray(event);
           if (bytes.length > 0) {
               manager.write(bytes);
               if (this.immediateFlush || event.isEndOfBatch()) {
                   manager.flush();
               }
           }
       } catch (final AppenderLoggingException ex) {
           error("Unable to write to stream " + manager.getName() + " for appender " + getName());
           throw ex;
       } finally {
           readLock.unlock();
       }
   }
  1. 应该优先使用RollingRandomAccessFileAppender 而不是RollingFileAppender,它是使用ByteBuffer + RandomAccessFile而不是BufferedOutputStream ,效率会提供20-200%,并且他总是buffered,因为使用了NIO中的ByteBuffer

  2. 有另外一种配置异步的方法,log4j2.xml还是按照同步的方式来配置,但是加上java启动参数-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector,这样的话所有的日志都是异步,但是这个和直接配置log4j2.xml异步的原理不一样,前者会额外启动一个线程,不使用queue,而后者会额外启动2个线程,并且使用queue,推荐使用后者

官方文档:log4j2

猜你喜欢

转载自my.oschina.net/dxqr/blog/1813410