1、同步异步分析
同步记录日志方式如下:
多个业务线程打印日志时候要等把内容写入磁盘后才会返回,所以打日志的rt就是写入磁盘的耗时。
而异步记录日志方式如下:
多个业务线程打印日志时候是把打印任务放入内存队列后就直接返回了,而具体打印日志是有日志系统的一个日志线程去队列里面获取然后执行,可见这种打印rt就是写入内存队列的耗时。
2、异步配置方式
springboot使用logback记录日志,在resources下创建logback-spring.xml文件来配置
整体配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<contextName>stc-pub日志配置</contextName>
<property name="LOG_PATH" value="logs" />
<!--设置系统日志目录-->
<property name="APPDIR" value="newframe" />
<!-- 日志记录器,日期滚动记录 -->
<appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${APPDIR}/log_error.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
命名日志文件,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器,日期滚动记录 -->
<appender name="FILEWARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${APPDIR}/log_warn.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
命名日志文件,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器,日期滚动记录 -->
<appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${APPDIR}/log_info.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
命名日志文件,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="ASYNC-FILEINFO" class="ch.qos.logback.classic.AsyncAppender">
<!-- 当队列的剩余容量小于这个阈值并且当前日志level为 TRACE, DEBUG or INFO ,则丢弃这些日志。 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>1024</queueSize>
<!-- 新增这行为了打印栈堆信息 -->
<includeCallerData>true</includeCallerData>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="FILEINFO"/>
</appender>
<appender name="ASYNC-FILEWARN" class="ch.qos.logback.classic.AsyncAppender">
<!-- 当队列的剩余容量小于这个阈值并且当前日志level为 TRACE, DEBUG or INFO ,则丢弃这些日志。 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>1024</queueSize>
<!-- 新增这行为了打印栈堆信息 -->
<includeCallerData>true</includeCallerData>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="FILEWARN"/>
</appender>
<appender name="ASYNC-FILEERROR" class="ch.qos.logback.classic.AsyncAppender">
<!-- 当队列的剩余容量小于这个阈值并且当前日志level为 TRACE, DEBUG or INFO ,则丢弃这些日志。 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>1024</queueSize>
<!-- 新增这行为了打印栈堆信息 -->
<includeCallerData>true</includeCallerData>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="FILEERROR"/>
</appender>
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--encoder 默认配置为PatternLayoutEncoder-->
<encoder>
<pattern>${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</pattern>
<charset>utf-8</charset>
</encoder>
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
</appender>
<logger name="org.springframework" level="INFO" />
<!-- <logger name="java.sql" level="DEBUG" />
<logger name="org.apache.ibatis" level="DEBUG" />
<logger name="com.sxd.swapping.dao.mybatis" level="DEBUG" />-->
<logger name="org.apache.ibatis" level="DEBUG" />
<logger name="com.iscas.biz" level="DEBUG" />
<logger name="sun.rmi.transport.tcp" level="INFO" />
<logger name="org.apache.http" level="INFO" />
<logger name="com.sun.mail.smtp" level="INFO" />
<logger name="javax.management" level="INFO" />
<logger name="sun.rmi" level="INFO" />
<logger name="de.codecentric" level="INFO" />
<logger name="druid.sql.Connection" level="INFO" />
<logger name="druid.sql.Statement" level="INFO" />
<logger name="druid.sql.ResultSet" level="INFO" />
<logger name="org.hibernate.validator" level="INFO" />
<logger name="org.mybatis.spring.mapper" level="INFO" />
<logger name="org.xnio.nio" level="INFO" />
<logger name="springfox.documentation" level="INFO" />
<logger name="springfox.bean" level="INFO" />
<logger name="com.baomidou.mybatisplus.core" level="INFO" />
<logger name="io.undertow" level="INFO" />
<logger name="io.micrometer.core" level="INFO" />
<logger name="com.baomidou.mybatisplus.extension.spring" level="INFO" />
<logger name="Validator" level="INFO" />
<logger name="io.lettuce" level="INFO" />
<logger name="io.netty" level="INFO" />
<logger name="org.springframework.boot.actuate.redis.RedisReactiveHealthIndicator" level="ERROR" />
<logger name="org.neo4j.driver" level="INFO" />
<logger name="org.apache.zookeeper" level="INFO" />
<logger name="org.apache.curator.framework.recipes.cache" level="INFO" />
<logger name="oshi.util.platform.windows" level="INFO" />
<logger name="org.quartz.core" level="INFO" />
<logger name="org.quartz.simpl" level="INFO" />
<logger name="net.javacrumbs.shedlock.core.DefaultLockingTaskExecutor" level="INFO" />
<logger name="com.atomikos.jdbc.AbstractDataSourceBean" level="WARN" />
<logger name="com.atomikos.jdbc.AtomikosConnectionProxy" level="ERROR" />
<logger name="org.springframework.boot.actuate.mail" level="ERROR" />
<logger name="root" level="DEBUG" />
<!-- 生产环境下,将此级别配置为适合的级别,以免日志文件太多或影响程序性能 -->
<root level="DEBUG">
<appender-ref ref="ASYNC-FILEERROR" />
<appender-ref ref="ASYNC-FILEWARN" />
<appender-ref ref="ASYNC-FILEINFO" />
<!-- 生产环境将请stdout去掉 -->
<!--<appender-ref ref="STDOUT" />-->
</root>
</configuration>
以上的每项配置都有注释,可以通过注释了解配置的意义。
其中ASYNC-FILEERROR、ASYNC-FILEWARN、ASYNC-FILEINFO三个appender是重点,每个appender中需要配置<includeCallerData>true</includeCallerData>,使之打印堆栈信息,不然%-3L不会打印行号。