slf4j-logback-Appender进阶

来源:互联网 发布:linux下启动jenkins 编辑:程序博客网 时间:2024/05/17 06:17
logback 进阶 
基础篇请参考http://wangxinchun.iteye.com/blog/2094761 
1、AsyncAppender。 
为了提升性能,logback 支持异步的日志记录。 

关于异步:本质就是执行不等待,所谓执行就是提交任务。任务执行 1、有结果:一般认为执行完可以回调;2、没有结果,执行完就完事。log的记录就是典型的没有结果的情况,调用方不需要知道执行的最终结果。 

实现: logback 是通过 ch.qos.logback.classic.AsyncAppender 来实现异步的log日志记录的。其内部实现是通过保存一个 BlockingQueue<E> blockingQueue; 来缓存 (info,warn,error)的日志消息,然后由一个 Worker worker 线程 从 blockingQueue 中 blockingQueue.take();数据,并输出到   AppenderAttachableImpl<E> aai 中。

关于BlockingQueue的使用 是异步的重点,请参考: 
http://wangxinchun.iteye.com/blog/1882960 

相关源码: 
Java代码  收藏代码
  1. public class AsyncAppenderBase<E> extends UnsynchronizedAppenderBase<E> implements AppenderAttachable<E> {  
  2.   //内部要输出的appender  
  3.   AppenderAttachableImpl<E> aai = new AppenderAttachableImpl<E>();  
  4.   // log 消息队列  
  5.   BlockingQueue<E> blockingQueue;  
  6.   
  7.   /** 
  8.    * 默认的消息队列,一般可以稍大一点*/  
  9.   public static final int DEFAULT_QUEUE_SIZE = 256;  
  10.   int queueSize = DEFAULT_QUEUE_SIZE;  
  11.   int appenderCount = 0;  
  12.   
  13.   static final int UNDEFINED = -1;  
  14.   int discardingThreshold = UNDEFINED;  
  15.    //实际的log 输出线程任务  
  16.   Worker worker = new Worker();  
  17.   //其他略  
  18. }  

使用case: 
Java代码  收藏代码
  1.    <!-- 循环文件输出(基于时间戳的分文件,是实际项目中用途最广的一种情况) -->  
  2. <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
  3.    <file>rooling.log</file>  
  4.     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
  5.         <fileNamePattern>rooling-log.%d{yyyy-MM-dd-HH}.log.gz</fileNamePattern>  
  6.         <maxHistory>30</maxHistory>  
  7.     </rollingPolicy>  
  8.     <encoder>  
  9.         <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n </pattern>  
  10.     </encoder>  
  11. </appender>  
  12.   
  13.    <appender name="SYNC_ROLLING_FILE" class="ch.qos.logback.classic.AsyncAppender">  
  14.        <appender-ref ref="ROLLING_FILE"/>  
  15.        <queueSize>1024</queueSize>  
  16.     <discardingThreshold>0</discardingThreshold>  
  17.    </appender>  
  18.   
  19. <logger name="com.qunar.logback.LogbackTest" additivity="false"  
  20.     level="debug">  
  21.      <!-- <appender-ref ref="SYNC_ROLLING_FILE" />   -->  
  22.     <appender-ref ref="ROLLING_FILE" />   
  23. </logger>  


测试: 
Java代码  收藏代码
  1. @Test  
  2.     public void testLogback() throws InterruptedException {  
  3.         long l = System.currentTimeMillis();  
  4.         for(int i=0;i<30000;i++){  
  5.             logger.debug("hello {} ""world" +i);  
  6.             logger.info("hello {} ""world"+i);  
  7.             logger.warn("hello {} ""world"+i);  
  8.             logger.error("hello {} ""world"+i);  
  9.             if(i%1000 == 0){  
  10.                 Thread.currentThread().sleep(50);  
  11.             }  
  12.         }  
  13.         System.out.println(System.currentTimeMillis() - l);  
  14.         Thread.currentThread().sleep(1000);  
  15.     }  


结论: 
同步的耗时:3800 左右 
异步的耗时:4500 左右 
另外:考虑到实际的生产环境,大多不会把缓存填满,异步的性能优势会更明显。 

请注意:如果循环非常快,有可能队列很快就满了,当前线程要等待work线程把数据输出到appender,这样的测试是不能显示异步appender的优势的,所以i%1000==0 进行了短暂的等待。 

2、RollingFileAppender 
循环文件输出appender,特点:可以根据rollingPolicy 来指定文件名的规则,按照时间或自增id ,保证log输出到由(%d)当前时间指定的特定的文件内,同一个时间规则,有可以根据(%i)来根据文件的大小分多个文件。 

对于RollingFileAppender 一般必须要指定 rollingPolicy 和 triggeringPolicy,由于TimeBasedRollingPolicy 实现了TriggeringPolicy 和 RollingPolicy 所以如果rollingPolicy  配置为 TimeBasedRollingPolicy  ,可以不配置triggeringPolicy。 

TimeBasedRollingPolicy案例如下: 
Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <configuration scan="true" scanPeriod="30 seconds">  
  3.     <contextName>myAppName</contextName>  
  4.     <!-- 命令行输出 -->  
  5.     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
  6.         <encoder>  
  7.             <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}- %msg%n</pattern>  
  8.         </encoder>  
  9.     </appender>  
  10.   
  11.     <!-- 循环文件输出(基于时间戳的分文件,是实际项目中用途最广的一种情况) -->  
  12.     <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
  13.         <file>rooling.log</file>  
  14.         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
  15.             <fileNamePattern>rooling-log.%d{yyyy-MM-dd-HH}.%i.log.gz</fileNamePattern>  
  16.             <maxHistory>30</maxHistory>  
  17.              <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">  
  18.                 <maxFileSize>1MB</maxFileSize>  
  19.              </timeBasedFileNamingAndTriggeringPolicy>  
  20.         </rollingPolicy>  
  21.         <encoder>  
  22.             <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}- %msg%n</pattern>  
  23.         </encoder>  
  24.     </appender>  
  25.   
  26.     <logger name="com.qunar.logback.LogbackTest" additivity="true"  
  27.         level="debug">  
  28.         <appender-ref ref="ROLLING_FILE" />  
  29.     </logger>  
  30.   
  31.     <root level="INFO">  
  32.         <appender-ref ref="STDOUT" />  
  33.     </root>  
  34. </configuration>  


输出的效果如下: 


FixedWindowRollingPolicy 
固定格式,固定文件大小的rooling策略。 

案例如下: 
Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <configuration scan="true" scanPeriod="30 seconds">  
  3.     <contextName>myAppName</contextName>  
  4.     <!-- 命令行输出 -->  
  5.     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
  6.         <encoder>  
  7.             <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}- %msg%n</pattern>  
  8.         </encoder>  
  9.     </appender>  
  10.   
  11.     <!-- 循环文件输出(基于时间戳的分文件,是实际项目中用途最广的一种情况) -->  
  12.     <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
  13.         <file>test.log</file>  
  14.         <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">  
  15.           <fileNamePattern>tests.%i.log.zip</fileNamePattern>  
  16.           <minIndex>1</minIndex>  
  17.           <maxIndex>3</maxIndex>  
  18.         </rollingPolicy>  
  19.           
  20.          <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">  
  21.           <maxFileSize>1MB</maxFileSize>  
  22.         </triggeringPolicy>  
  23.           
  24.         <encoder>  
  25.             <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n </pattern>  
  26.         </encoder>  
  27.     </appender>  
  28.   
  29.     <logger name="com.qunar.logback.LogbackTest" additivity="false"  
  30.         level="debug">  
  31.         <appender-ref ref="ROLLING_FILE" />  
  32.     </logger>  
  33.   
  34.     <root level="INFO">  
  35.         <appender-ref ref="STDOUT" />  
  36.     </root>  
  37. </configuration>  

0 0
原创粉丝点击