logback使用中,会因为日志量过大,导致请求响应时间太长。本文介绍几种常见提升logback性能的办法
异步Appender
异步是降低日志对请求耗时影响的最有效方法,首推使用!
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="logDir" value="${catalina.base}/logs" />
<property name="commonPattern" value="[%thread][%level][%class{0}:%line]: %msg%n" />
<appender name="ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/all.log</file>
<encoder>
<pattern>${commonPattern}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${logDir}/all.%d{yyyy-MM-dd}.log.zip</FileNamePattern>
<maxHistory>15</maxHistory>
</rollingPolicy>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<includeCallerData>true</includeCallerData>
<discardingThreshold>-1</discardingThreshold>
<queueSize>1024</queueSize>
<appender-ref ref="ALL" />
</appender>
<root level="DEBUG">
<appender-ref ref="ASYNC" />
</root>
</configuration>
-
queueSize
默认值256,不过该值首次建议设置大一些,后续根据自己业务的特点去调优,降低日志丢失的概率。 -
discardingThreshold
:默认情况下,当blockingQueue的容量高于阈值时(80%),会丢弃ERROR以下级别的日志,如果不希望丢弃日志(既每次都是全量保存),那可以设置为0,但是如果队列满的时候,会丢弃所有插入队列的日志信息,所以建议设置为-1(默认值)。 如正常日志可以丢弃,那可以极大的提升性能,并保存关键的ERROR日志。 -
AsyncAppender
中只能配置一个appender-ref
,配置多个就会无效
不同环境不同配置
开发环境一般都把日志输出到ConsoleAppender
,但是其他环境是不需要的,可以使用动态配置。
<root level="DEBUG">
<appender-ref ref="ASYNC"/>
<if condition='property("os.name").toUpperCase().contains("WINDOWS") || property("os.name").toUpperCase().contains("MAC")'>
<then>
<appender-ref ref="STDOUT"/>
</then>
</if>
</root>
pom.xml
中需要添加依赖
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.0.11</version>
</dependency>
过滤异常栈
异常栈可以非常有效地帮助定位问题,但是也会因为异常栈太长,包含了太多几乎无价值的信息,比如反射、动态代理、Spring、tomcat等调用信息。过滤掉这部分信息,既减少了日志量,也减少大对象的数量,降低Full GC的次数。常用配置如下:
代码语言:javascript复制<property name="commonPattern" value="[%thread][%level][%class{0}:%line]: %msg%n%rEx{full,
java.lang.reflect.Method,
sun.reflect,
org.apache.catalina,
org.springframework.aop,
org.springframework.security,
org.springframework.transaction,
org.springframework.web,
org.springframework.beans,
org.springframework.cglib,
net.sf.cglib,
org.apache.tomcat.util,
org.apache.coyote,
ByCGLIB,
BySpringCGLIB,
com.google.common.cache.LocalCache$
}"/>
常见问题
- 日志中的
%class%line
中没有显示正确的值,而是两个问号? 解决办法:一般出现在AsyncAppender中,需要添加属性<includeCallerData>true</includeCallerData>
参考
- logback 异步日志配置
- Filtering the Stack Trace From Hell
- 日志优化