<configuration scan="true" scanPeriod="60 seconds" debug="true">
<property name="log_dir" value="/data/logs/wxcalendar/reminder" />
<property name="maxHistory" value="30"/>
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%file:%line] - %msg %xEx%npattern>
encoder>
appender>
<appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERRORlevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
<prudent>trueprudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log_dir}/error-%d{yyyy-MM-dd}.log.zipfileNamePattern>
<maxHistory>${maxHistory}maxHistory>
<maxFileSize>64 MBmaxFileSize>
rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%npattern>
<charset>GBKcharset>
encoder>
appender>
<logger name="com.tom" level="INFO" additivity="false">
<appender-ref ref="errorAppender">appender-ref>
logger>
<root level="INFO">
<appender-ref ref="Console"/>
<appender-ref ref="errorAppender" />
root>
configuration>
上面的配置是log-back的一些配置,在springBoot中,还额外增加了 springProfile、 springProperty 标签,springProfile 标签用于区分各个环境下配置文件,在application.properties 中配置了spring.profiles.active=xxx 后,该标签会加载指定的日志配置文件。
如:logback-spring.xml
<configuration debug="true" scan="true" scanPeriod="60 seconds">
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
encoder>
appender>
<springProfile name="dev">
<logger name="com.ks.aop" level="INFO" additivity="false">
<appender-ref ref="aopAppender"/>
logger>
springProfile>
configuration>
其中 name
等于dev、prod、prep分别是开发、生产、测试环境下的日志输出。
springProperty 标签用于读取 spring 环境中 property 配置的属性值,springProperty 有name属性,与 logback 中标签 property 作用类似,可以在配置文件的下文中通过 ${name} 读取值。logback 中配置定义有顺序,取值或者引用必须先声明后引用。
官文例子:
<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host" defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>${fluentHost}remoteHost>
....
appender>
高级特性之异步输出
之前的日志配置方式是基于同步的,每次日志输出到文件都会进行一次磁盘IO。采用异步写日志的方式而不让每次写日志发生磁盘IO,阻塞线程从而造成不必要的性能损耗,在写日志频繁且高并发场景下,异步写性能提升还是很显著的。
异步输出日志的方式很简单,添加一个基于异步写日志的appender,并指向原先配置的appender即可:
<appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0discardingThreshold>
<queueSize>256queueSize>
<appender-ref ref="INFO-LOG"/>
appender>
<appender name="ASYNC-ERROR" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0discardingThreshold>
<queueSize>256queueSize>
<appender-ref ref="ERROR-LOG"/>
appender>
最好在使用 appender 的地方,引入上面的异步 appender 即可。
大致原理:
分析 logback 的源码(ch.qos.logback.classic.AsyncAppender#append
)中可以看到,我们代码中的 info、error 等日志方法,最终只是通过 AsyncAppender#append
添加到了一个阻塞队列中,另有一个专门的写线程(worker thread) 来消费队列中的日志内容,写入磁盘中,把我们业务代码中写日志的过程异步化来提高了代码的性能。
参考文章:
http://www.cnblogs.com/lixuwu/p/5811273.html
http://tengj.top/2017/04/05/springboot7/
https://juejin.im/post/5b2e29d0e51d45589e7bd4fa
https://mp.weixin.qq.com/s/1wONU6YNbslmXuJkhaTJuA