logback.xml配置踩坑记录

    logback官方文档
    [https://github.com/YLongo/logback-chinese-manual/blob/master/04%E7%AC%AC%E5%9B%9B%E7%AB%A0%EF%BC%9AAppenders.md](https://github.com/YLongo/logback-chinese-manual/blob/master/04%E7%AC%AC%E5%9B%9B%E7%AB%A0%EF%BC%9AAppenders.md)
	配合压力测试的过程中在springboot项目中直接配置了logback.xml进行日志的打印
	高吞吐测试下 500M的日志文件 很快被打满 紧接着 logback去进行压缩
	RollingFileAppender下选择触发压缩策略时,rollingPolicy 单使用 TimeBasedRollingPolicy 日志会进行异步压缩(起个线程去处理),但是加上FixedWindowRollingPolicy 后 只执行 FixedWindowRollingPolicy 的 压缩策略 .
	FixedWindowRollingPolicy 并不会进行异步压缩 所以会发生 I/O 阻塞的情况
	压力测试时的现象就是 tps 每隔几分钟 规律性的 波动(峰谷巨大) 文件小时阻塞时间短,tps没有掉到谷底,当日志文件设置为 几个GB大小时 ,压缩耗时会增加至 一分钟 以上,影响巨大。
	一并加上triggeringPolicy的大小触发策略,是我最开始的配置(三块)。
	解决问题的过程中 我知道还有一种策略 SizeAndTimeBasedRollingPolicy。
	但是我只是用 SizeAndTimeBasedRollingPolicy 替换了 TimeBasedRollingPolicy,因为有FixedWindowRollingPolicy 的存在所以SizeAndTimeBasedRollingPolicy 的异步压缩并没有起作用(后面才知道的),所以我是看着源码 晕晕乎乎瞎干。
	我把 TimeBasedRollingPolicy 中的异步压缩方法替换至 FixedWindowRollingPolicy ,打好自己的logback-core.jar包 并使用之,好像没出什么问题。
	后来偶然就试试,只留一个 SizeAndTimeBasedRollingPolicy,其他什么都不要,triggeringPolicy也不需要,这是个惊喜。
	为了控制凌乱的日志级别打印,我使用了 临界值过滤器 ThresholdFilter:ch.qos.logback.classic.filter.ThresholdFilter。
	结果不给力,对性能(tps)的影响在30%多,当然这是在压力测试的极限情况下,一般不是高qps应该也是可以使用的  。
	
	先后配置顺序是否存在影响,没有验证, 为什么FixedWindowRollingPolicy 不是异步压缩,还是未知。
	PS:我用的是1.2.3版本


<?xml version="1.0" encoding="UTF-8"?>
<!-- 属性描述 scan:设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
    debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->

<configuration scan="true" scanPeriod="60 seconds" debug="true" >
    <springProperty scope="context" name="logName" source="application.name" defaultValue="spring-boot"/>
    <springProperty scope="context" name="logPath" source="log.path" defaultValue="D:\"/>
    <springProperty scope="context" name="logLevel" source="log.level" defaultValue="DEBUG"/>
    <springProperty scope="context" name="logSize" source="log.size" defaultValue="512000KB"/>
    <timestamp key="bySecond" datePattern="yyyy-MM-dd" />
    <property name="logTextPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %X{username} %-5level %logger{80} [%L] - %msg%n"/>

    <!-- 按照每天生成日志文件RollingFileAppender滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。有以下子节点:-->
	<!-- RollingFileAppender是FileAppender的子类,指定日志输出到文件,不过他可以配置按照某种规则备份之前输出的日志的文件,然后重新生成一个文件输出新的日志 -->
	<!-- RollingFileAppender有两个主要的组成:
	1. rollingPolicy:
	当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类。
	
	ch.qos.logback.core.rolling.TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。有以下子节点:
	fileNamePattern:必要节点,包含文件名及“%d”转换符,“%d”可以包含一个java.text.SimpleDateFormat指定的时间格式,如:%d{yyyy-MM}。如果直接使用 %d,默认格式是 yyyy-MM-dd。RollingFileAppender的file字节点可有可无,通过设置file,可以为活动文件和归档文件指定不同位置,当前日志总是记录到file指定的文件(活动文件),活动文件的名字不会改变;
	***如果没设置file,活动文件的名字会根据fileNamePattern 的值,每隔一段时间改变一次。“/”或者“\”会被当做目录分隔符。***
	maxHistory:日志最大保存的日期。比如如果你设置的pattern是按天算的,那么设置maxHistory为30,那么会自动删除30天之前的日志。
	totalSizeCap:日志最大保存的大小。当超过该值,会自动删除老的日志文件。必须和maxHistory一起使用,而且maxHistory先生效,其次是判断是否达到totalSizeCap。
	cleanHistoryOnStart:默认false。如果设置为true,再项目启动的时候会自动删除老的日志文件。
	
	2. triggeringPolicy:
	告知 RollingFileAppender 什么时候激活滚动。
	ch.qos.logback.core.rolling.FixedWindowRollingPolicy 根据固定窗口算法重命名文件的滚动策略。有以下子节点:
	minIndex:窗口索引最小值
	maxIndex:窗口索引最大值,当用户指定的窗口过大时,会自动将窗口设置为12。
	fileNamePattern:必须包含“%i”例如,假设最小值和最大值分别为1和2,命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。还可以指定文件压缩选项,例如,mylog%i.log.gz。 -->

    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
    	 <!-- 输出log到文件中。通过file属性决定输出到哪个文件中,通过append属性决定当文件存在时是追加输出日志,还是删掉旧文件重新生成一个输出日志 -->
    	<file>${logPath}/${logName}.log</file>
    	<!-- <append>false</append> -->
        <!-- filter过滤会影响性能 -->
        <!--<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>-->
        
        <!-- 按照每天生成日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的位置  可相对、和绝对路径 按天回滚-->
            <FileNamePattern>${logPath}/${bySecond}/${logName}.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!-- 最大保存30天 -->
            <maxHistory>10</maxHistory>
            <!-- 日志总保存量为10GB -->
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
        <!--<encoder>
            encoder 用来格式化输出: 默认配置为PatternLayoutEncoder 
        %d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
    </encoder>-->
        <!--日志文件大小超限后,回滚,压缩日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.MyFixedWindowRollingPolicy">
		    <fileNamePattern>${logPath}/${bySecond}/${logName}.%i.log.zip</fileNamePattern>
	      <minIndex>1</minIndex>
	      <maxIndex>20</maxIndex> 
		</rollingPolicy>
        
		<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
			<MaxFileSize>${logSize}</MaxFileSize>
		</triggeringPolicy>
		<layout class="ch.qos.logback.classic.PatternLayout">
			<pattern>${logTextPattern}</pattern>
		</layout>
    </appender>

	<!--下层路径或具体类 配置的日志级别  低于 上层路径的日志级别时  决定者为 上层
	下层路径或具体类 配置的日志级别  高于 上层路径的日志级别时  决定者为 下层-->

	<!-- %m输出的信息, %p日志级别, %t线程名, %d日期, %c类的全名, %i索引 -->
    <!-- appender是configuration的子节点,是负责写日志的组件 -->
    <!-- ConsoleAppender把日志输出到控制台 -->
    <!--    <property name="CONSOLE_LOG_PATTERN" value="%date{yyyy-MM-dd HH:mm:ss} | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %msg%n"/> -->
	<!-- 子节点<appender>:负责写日志的组件,它有两个必要属性name和class。name指定appender名称,class指定appender的全限定名 -->
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<!-- 过滤调除了info以外的日志,只打印info的日志 -->
		    <!-- 级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据 onMath 和 onMismatch 接收或拒绝日志。
		         <level> : 设置过滤级别。
		       <onMatch> : 用于配置符合过滤条件的操作。
		       <onMismatch> : 用于配置不符合过滤条件的操作。 
		    	执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一。
            返回DENY,日志将立即被抛弃不再经过其他过滤器;
    		返回NEUTRAL,有序列表里的下个过滤器过接着处理日志;
    		返回ACCEPT,日志会被立即处理,不再经过剩余过滤器。-->
        <!--<filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>-->
        <!-- 临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。
            有以下子节点 :
              <level> : 设置过滤级别。
            例如:过滤掉所有低于info级别的日志。 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <!-- encoder 默认配置为PatternLayoutEncoder --> 
        <!-- 对日志进行格式化 -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
	    <!--<encoder>
                <pattern>${logTextPattern}</pattern>
            &lt;!&ndash;<pattern>%date{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) (%file:%line\)- %m%n</pattern> &ndash;&gt;
            &lt;!&ndash; 控制台也要使用utf-8,不要使用gbk &ndash;&gt;
            &lt;!&ndash; <charset>UTF-8</charset>&ndash;&gt;
        </encoder>-->
	</appender>

		<!-- 日志输出级别 TRACE < DEBUG < INFO < WARN < ERROR-->
		<!--现发现此处可以控制SQL的打印-->
    <root level="${logLevel}">
        <!--<appender-ref ref="STDOUT" />-->
        <appender-ref ref="FILE" />
    </root>

</configuration>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值