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
使用说明:
queueSize 缓存记录的size 非常重要,默认是256,对于并发量较高的系统,队列深度需要根据业务场景进行相应的测试,做出相应的更改,以达到较好的性能。
discardingThreshold:默认情况下,当BlockingQueue还有20%容量,他将丢弃TRACE、DEBUG和INFO级别的event,只保留WARN和ERROR级别的event。为了保持所有的events,设置该值为0。
相关源码:
public class AsyncAppenderBase<E> extends UnsynchronizedAppenderBase<E> implements AppenderAttachable<E> {
//内部要输出的appender
AppenderAttachableImpl<E> aai = new AppenderAttachableImpl<E>();
// log 消息队列
BlockingQueue<E> blockingQueue;
/**
* 默认的消息队列,一般可以稍大一点*/
public static final int DEFAULT_QUEUE_SIZE = 256;
int queueSize = DEFAULT_QUEUE_SIZE;
int appenderCount = 0;
static final int UNDEFINED = -1;
int discardingThreshold = UNDEFINED;
//实际的log 输出线程任务
Worker worker = new Worker();
//其他略
}
使用case案例:
<!-- 循环文件输出(基于时间戳的分文件,是实际项目中用途最广的一种情况) -->
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>rooling.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>rooling-log.%d{yyyy-MM-dd-HH}.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n </pattern>
</encoder>
</appender>
<appender name="SYNC_ROLLING_FILE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="ROLLING_FILE"/>
<queueSize>1024</queueSize>
<discardingThreshold>0</discardingThreshold>
</appender>
<logger name="com.qunar.logback.LogbackTest" additivity="false"
level="debug">
<!-- <appender-ref ref="SYNC_ROLLING_FILE" /> -->
<appender-ref ref="ROLLING_FILE" />
</logger>
测试:
@Test
public void testLogback() throws InterruptedException {
long l = System.currentTimeMillis();
for(int i=0;i<30000;i++){
logger.debug("hello {} ", "world" +i);
logger.info("hello {} ", "world"+i);
logger.warn("hello {} ", "world"+i);
logger.error("hello {} ", "world"+i);
if(i%1000 == 0){
Thread.currentThread().sleep(50);
}
}
System.out.println(System.currentTimeMillis() - l);
Thread.currentThread().sleep(1000);
}
结论:
同步的耗时: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案例如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<contextName>myAppName</contextName>
<!-- 命令行输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}- %msg%n</pattern>
</encoder>
</appender>
<!-- 循环文件输出(基于时间戳的分文件,是实际项目中用途最广的一种情况) -->
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>rooling.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>rooling-log.%d{yyyy-MM-dd-HH}.%i.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}- %msg%n</pattern>
</encoder>
</appender>
<logger name="com.qunar.logback.LogbackTest" additivity="true"
level="debug">
<appender-ref ref="ROLLING_FILE" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
输出的效果如下:
FixedWindowRollingPolicy
固定格式,固定文件大小的rooling策略。
案例如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<contextName>myAppName</contextName>
<!-- 命令行输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}- %msg%n</pattern>
</encoder>
</appender>
<!-- 循环文件输出(基于时间戳的分文件,是实际项目中用途最广的一种情况) -->
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>tests.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>1MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n </pattern>
</encoder>
</appender>
<logger name="com.qunar.logback.LogbackTest" additivity="false"
level="debug">
<appender-ref ref="ROLLING_FILE" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
输出结果:
- 大小: 229.1 KB
- 大小: 68.3 KB
分享到:
相关推荐
SLF4J(Simple Logging Facade for Java)是Java日志记录的一个接口层,它为各种日志框架,如Log4j、Logback等提供一个简单的抽象层,使得最终用户能够在部署时插入所需的日志实现。`slf4j-api-1.7.7.jar`是SLF4J ...
SLF4J提供了一个抽象层,允许开发者在运行时选择合适的日志实现,比如Log4j、Logback等。这个"slf4j-log4j12.jar"文件就是SLF4J与Log4j 1.2桥接器的实现,它使得SLF4J调用能够被Log4j 1.2的日志系统捕获并处理。 1....
SLF4J作为接口层,允许代码独立于具体日志框架,slf4j-log4j12作为桥接器将SLF4J调用转换为Log4j操作,而Log4j则负责实际的日志记录和管理。这种设计模式使得日志管理更加标准化,同时提高了项目的可维护性和可移植...
首先,SLF4J是一个日志门面,它为各种日志框架(如Logback、Log4j等)提供一个简单的抽象层,使得最终用户能够在部署时插入所需的日志实现。SLF4J的API设计简洁,方便了开发者编写代码,而无需关心底层的日志实现。`...
本文将深入探讨“日志4j(Log4j)、SLF4J(Simple Logging Facade for Java)和logback 1.3.0”这三者之间的关系以及它们在Java应用中的作用。 首先,Log4j是Apache软件基金会开发的一个流行的日志记录框架,它允许...
"Log4j-slf4j-impl.zip"这个压缩包中包含的是Log4j对SLF4J接口的实现,即"log4j-slf4j-impl-2.11.2.jar"。SLF4J提供了一组API,允许开发者编写与具体日志库无关的日志代码。而Log4j-SLF4J-Impl则是SLF4J的一个绑定,...
slf4j-logback4jpos jPos 的 lf4j-logback appender 实现。 本实现工作的灵感来自 Victor 对核心模块的初步工作,这是参考实现。 这种变体处理 jPos 本机 Loggeable 对象,以某种方式取消它们通过 logback 的格式化...
SLF4J的主要目的是为各种日志框架(如log4j、java.util.logging、Logback等)提供一个简单、一致的接口,使得开发人员能够在不修改代码的情况下切换日志框架。"slf4j-log4j12-1.5.8.jar.zip"这个压缩包包含了SLF4J与...
SLF4J提供了一个统一的日志API,允许开发者选择任意的日志实现,比如Logback或Log4j。 `jcl-over-slf4j-1.6.0.jar`是SLF4J提供的一个桥接包,它的主要作用是将JCL的日志调用透明地重定向到SLF4J。这样做的好处是,...
SLF4J(Simple Logging Facade for Java)是Java中的一种日志抽象层,它提供了一个API,允许开发者选择自己偏好的日志框架,如Log4j、Java Util Logging、Logback等。SLF4J的主要目的是为了简化日志处理,使得在不同...
本文将深入探讨“调试日志之slf4j+logback”的主题,这两个组件是Java开发中的常见日志解决方案。 SLF4J(Simple Logging Facade for Java)是一个日志门面,它为各种日志框架提供了统一的接口,如Log4j、Logback等...
SLF4J提供了一个抽象层,允许开发者在运行时动态地选择合适的日志框架,如Logback、Log4j等。Log4j则是一个广泛使用的日志实现,提供了丰富的功能和高性能的日志记录。 SLF4J-log4j12-1.5.2.jar是SLF4J针对Log4j ...
SLF4J(Simple Logging Facade for Java)和Logback是Java世界中广泛使用的日志框架,它们在Spring MVC项目中扮演着至关重要的角色。SLF4J是一个接口层,为各种日志实现提供了一个统一的API,允许开发者在不修改代码...
SLF4J(Simple Logging Facade for Java)与Logback是Java日志处理中的两个重要组件,它们在软件开发中广泛用于实现灵活、高效的日志记录。SLF4J作为一个日志门面,提供了一种统一的日志API,使得开发者能够在不绑定...
SLF4J允许您选择任何支持的底层日志库,如Logback、Log4j、Java Util Logging等。在实际项目中,SLF4J与Logback的组合被广泛使用,因为Logback被认为是性能优秀且功能丰富的日志实现。 首先,我们需要理解SLF4J的...
本篇文章将重点讲解Spring如何与SLF4J(Simple Logging Facade for Java)和Logback进行集成,实现高效且灵活的日志记录。 SLF4J是一个日志API,它的主要目标是为各种日志框架提供一个简单的抽象层,如Log4j、...
SLF4J(Simple Logging Facade for Java)是一个为各种日志框架提供一个简单统一的API,例如Log4j、Java Util Logging、Logback等。它的目标是允许最终用户在部署时插入所需的日志框架。SLF4J-Log4j12-1.5.2是SLF4J...
SLF4J(Simple Logging Facade for Java)和Logback是Java日志处理中的两个重要组件,它们在软件开发中广泛用于记录应用程序的运行时信息。SLF4J作为一个日志门面,提供了一种标准的接口,允许开发者在运行时插入...
SLF4J(Simple Logging Facade for Java)和Logback是Java日志处理的两个重要组件,它们在软件开发中广泛用于记录应用程序的运行时信息。SLF4J是一个日志门面,它提供了一个统一的接口,允许开发人员在运行时插入所...
### SLF4J + Logback 快速上手教程 #### 一、SLF4J 简介 **SLF4J**(Simple Logging Facade for Java)是一种简单且高效的日志门面库,旨在为Java平台上的各种日志框架提供统一的API,从而简化日志记录的过程。通过...