注意:該功能需要高版本才能支持,如1.0.11。
AsyncAppender,異步記錄日志。
工作原理:
工作原理:
當Logging Event進入AsyncAppender后,AsyncAppender會調用appender方法,append方法中在將event填入Buffer(這里選用的數據結構為BlockingQueue)中前,會先判斷當前buffer的容量以及丟棄日志特性是否開啟,當消費能力不如生產能力時,AsyncAppender會超出Buffer容量的Logging Event的級別,進行丟棄,作為消費速度一旦跟不上生產速度,中轉buffer的溢出處理的一種方案。AsyncAppender有個線程類Worker,它是一個簡單的線程類,是AsyncAppender的后臺線程,所要做的工作是:從buffer中取出event交給對應的appender進行后面的日志推送。
從上面的描述中可以看出,AsyncAppender并不處理日志,只是將日志緩沖到一個BlockingQueue里面去,并在內部創建一個工作線程從隊列頭部獲取日志,之后將獲取的日志循環記錄到附加的其他appender上去,從而達到不阻塞主線程的效果。因此AsynAppender僅僅充當事件轉發器,必須引用另一個appender來做事。
在使用AsyncAppender的時候,有些選項還是要注意的。由于使用了BlockingQueue來緩存日志,因此就會出現隊列滿的情況。正如上面原理中所說的,在這種情況下,AsyncAppender會做出一些處理:默認情況下,如果隊列80%已滿,AsyncAppender將丟棄TRACE、DEBUG和INFO級別的event,從這點就可以看出,該策略有一個驚人的對event丟失的代價性能的影響。另外其他的一些選項信息,也會對性能產生影響,下面列出常用的幾個屬性配置信息:
屬性名 | 類型 | 描述 |
queueSize | int | BlockingQueue的最大容量,默認情況下,大小為256。 |
discardingThreshold | int | 默認情況下,當BlockingQueue還有20%容量,他將丟棄TRACE、DEBUG和INFO級別的event,只保留WARN和ERROR級別的event。為了保持所有的events,設置該值為0。 |
includeCallerData | boolean | 提取調用者數據的代價是相當昂貴的。為了提升性能,默認情況下,當event被加入到queue時,event關聯的調用者數據不會被提取。默認情況下,只有"cheap"的數據,如線程名。 |
?
?
默認情況下,event queue配置最大容量為256個events。如果隊列被填滿,應用程序線程被阻止記錄新的events,直到工作線程有機會來轉發一個或多個events。因此隊列深度需要根據業務場景進行相應的測試,做出相應的更改,以達到較好的性能。
下面給出一個使用的配置示例:
<appender name="FILE" class= "ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按天來回滾,如果需要按小時來回滾,則設置為{yyyy-MM-dd_HH} --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>/opt/log/test.%d{yyyy-MM-dd}.log</fileNamePattern><!-- 如果按天來回滾,則最大保存時間為1天,1天之前的都將被清理掉 --><maxHistory>30</maxHistory><!-- 日志輸出格式 --><layout class="ch.qos.logback.classic.PatternLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n</Pattern></layout> </appender><!-- 異步輸出 --><appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender"><!-- 不丟失日志.默認的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日志 --><discardingThreshold >0</discardingThreshold><!-- 更改默認的隊列的深度,該值會影響性能.默認值為256 --><queueSize>512</queueSize><!-- 添加附加的appender,最多只能添加一個 --><appender-ref ref ="FILE"/></appender><root level ="trace"><appender-ref ref ="ASYNC"/></root>
?