slf4j-logback-Appender进阶

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SLF4J 是一个简单的日志门面,它提供了一组日志 API,可以与许多流行的日志框架(例如 logback、log4j、java.util.logging)集成。而 logback 则是一个功能强大的日志框架,它是 log4j 框架的继承者,提供了更好的性能和更丰富的特性。 要使用 SLF4J + logback 实现日志输出和记录,需要按照以下步骤进行: 1. 引入依赖:在项目的 pom.xml 文件中加入以下依赖: ``` <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.30</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> ``` 2. 配置 logback.xml 文件:在项目的 src/main/resources 目录下创建 logback.xml 文件,并配置日志输出的格式、级别、输出目标等信息。以下是一个简单的 logback.xml 配置示例: ``` <configuration> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="console" /> </root> </configuration> ``` 该配置将日志输出到控制台中,并显示日志的时间、线程、级别、类名和消息内容。 3. 在代码中使用 SLF4J API:在需要记录日志的代码中,使用 SLF4J API 进行日志记录。以下是一个示例: ``` import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyClass { private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class); public void doSomething() { LOGGER.info("This is a log message."); } } ``` 在这个示例中,我们使用 LoggerFactory.getLogger() 方法获取了一个 Logger 对象,并使用该对象进行日志记录。在记录日志时,我们使用了 LOGGER.info() 方法,指定日志的级别为 INFO。 以上就是使用 SLF4J + logback 实现日志输出和记录的基本步骤。通过 SLF4J,我们可以方便地切换不同的日志框架,而 logback 则提供了强大的日志功能,例如异步日志记录、定时滚动日志文件等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值