logback框架使用誤區 如何將所有包的ERROR級別日誌集中列印到一個日誌檔案中
早就想寫這個事情了,起因是自己想寫一個東西,其中使用logback日誌框架記錄日誌
打算 將所有包的ERROR及以上級別日誌打到一個檔案中,各個包下的日誌打到對應包的檔案中。
起初寫的xml配置類似於這樣:
<!-- 其中一個appender,其他appender與其相同 ,只有name、file和fileNamePattern不同-->
<appender name="ALL-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>all-error.log</file >
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${log_dir}/all-error.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory >
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
</pattern>
</encoder>
</appender>
<logger name="com.some.package1" level ="INFO" additivty="true">
<appender-ref ref="appender-1"/>
</logger>
<logger name="com.some.package2" level="INFO" additivty="true">
<appender-ref ref="appender-2"/>
</logger>
<logger name="com.some" level="ERROR" additivty="true">
<appender-ref ref="ALL-ERROR"/>
</logger>
然而執行後卻發現,這樣配置後的,並沒有達到預期目標。
反而,所有INFO及以上的資訊,不僅在appender appender-1
和appender-2
對應的日誌檔案中有,在appender為ALL-ERROR對應的日誌檔案中也都有,這是為何?
追蹤了一下斷點,發現如下程式碼片段:
/**
* Invoke all the appenders of this logger.
*
* @param event
* The event to log
*/
public void callAppenders(ILoggingEvent event) {
int writes = 0;
for (Logger l = this; l != null; l = l.parent) {
writes += l.appendLoopOnAppenders(event);
if (!l.additive) {
break;
}
}
// No appenders in hierarchy
if (writes == 0) {
loggerContext.noAppenderDefinedWarning(this);
}
}
這段程式碼來自logback的 ch.qos.logback.classic.Logger
檔案,是最終決定日誌內容輸出在哪裡的程式碼。
從這段程式碼我們可以發現:
1. logback會找到第一個符合日誌級別要求的logger,然後將日誌內容輸入到這個logger下配置的appender中。舉例來說:如果有一個com.some.package1
內的類的INFO級別日誌,那麼首先會找到logger com.some.package1
,然後找到logger下配置的appender appender-1
;最後根據appender-1
的配置,將日誌內容輸出到appender-1配置的檔案中。
2. 之後,logback根據additivty
檢查logger是否允許繼承,如果配置為true(預設為true),則查詢上一級logger(實際是按照以包名為name查詢上一層包的logger),找到logger後,不再判斷logger配置是否符合日誌級別要求,直接找到對應的appender,將日誌內容輸出。
這就帶來了一個問題,位於低層次包的logger,在接收到日誌後,不僅會把它輸出到自身的appender中,還會將其傳遞給位於高層次包logger的appender中,無論高層次包logger配置的日誌級別是什麼。正因為如此,所以我打算將所有包的ERROR級別 日誌輸出到一個檔案的目的沒有實現,反而所有INFO及以上級別的日誌都輸出了。
按照這個思路,如果logger com.some.package1
和com.some.package2
日記級別為ERROR,而logger com.some
日誌級別為INFO的話,是否所有INFO及以上級別的日誌都可以記入logger com.some
對應的appender下,而ERROR及以上級別的日誌會記入logger com.some.package1
和com.some.package2
呢?測試證明,是這樣。
知道了為什麼上面的配置達不到目的,接下來要考慮的是,藉助什麼方式實現這個需求呢?
logback提供了實現需求的方式:藉助Filter來做:
既然logger無法判斷日誌級別,那我們可以在對應的appender裡判斷日誌級別。
logback的過濾器使用起來可以達到對每一條日誌的DENY、ACCEPT和NEUTRAL。
根據文章開始提出的需求,我們需要的是一個繫結appender的,過濾日誌等級的filter,那麼ch.qos.logback.classic.filter.ThresholdFilter
正好是我們需要的。通過加入如下配置,appender ALL-ERROR
將只能接受ERROR及以上的日誌:
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
完整的xml配置如下,僅改變了filter的部分,就實現了需求:
<!-- 其中一個appender,其他appender與其相同 ,只有name、file和fileNamePattern不同,並且沒有filter的標籤-->
<appender name="ALL-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>all-error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${log_dir}/all-error.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
</pattern>
</encoder>
</appender>
<logger name="com.some.package1" level="INFO" additivty="true">
<appender-ref ref="appender-1"/>
</logger>
<logger name="com.some.package2" level="INFO" additivty="true">
<appender-ref ref="appender-2"/>
</logger>
<logger name="com.some" level="ERROR" additivty="true">
<appender-ref ref="ALL-ERROR"/>
</logger>
相關推薦
Windows/Ubuntu下,將所有檔名字列舉出來並儲存到txt檔案中
Windows 使用如下的DOS命令來實現: dir /s /b > lists.txt 可以將當前路徑下的所有檔案的“檔案路徑+檔名”儲存在lists.txt中。 其中,/s表示的是“列
logback框架使用誤區 如何將所有包的ERROR級別日誌集中列印到一個日誌檔案中
早就想寫這個事情了,起因是自己想寫一個東西,其中使用logback日誌框架記錄日誌 打算 將所有包的ERROR及以上級別日誌打到一個檔案中,各個包下的日誌打到對應包的檔案中。 起初寫的xml配置類似於這樣: <!-- 其中一個appender,
Java 尋找一個目下的所有“.Java”檔案,並將他們的絕對路徑存到一個文字檔案中
import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOExce
linux下將一個目錄下的所有檔案拷貝到另一個大檔案中,並把大檔案拆分成原來的小檔案,大小,內容,名字不變
經過四五天的編寫與除錯,初步完成了檔案操作工具的內容,以下是程式碼說明: 首先,我測試用的檔案在/home/xudong/mywork下,我的最終生成檔案是在這個路徑下,/home/xudong/work/resultfile.txt,分開後生成的小檔案在/home/xud
springBoot 框架打成jar包,讀取不到webapp下的靜態檔案
問題:使用springboot寫一個微服務,將pdf以模板形式匯出,pdf模板放在webapp下,在eclipse中執行沒有問題;以maven打成jar包,匯出pdf時,提示找不到該模板; 開啟jar包
Python將所有輸出資訊同時輸出到控制檯和制定檔案
import sys class Logger(object): def __init__(self, fileN="Default.log"): self.terminal = sys.stdout self.log = open(
SHELL腳本:將新增的行添加到另一個文件中
shell#!/bin/bashcd /usr/local/logstash/nginxlog[ -f num.txt ] || count=0[ -f num.txt ] && count=cat num.txtncount=wc -l /var/log/nginx/access-app.l
node將陣列寫到一個js檔案中
const fs = require('fs'); let arr = [ 1, 2, 3, 'abc' ] fs.writeFile("url.js",'let articleUrlList = ' + JSON.stringify(arr), er
怎麼快速提取一個excel檔案中的所有工作表名
1.首先,我分享第一個方法,這個方法可是非常簡單的哦。開啟一個含有多個工作表的excel工作薄,然後新建一個工作表,此處命名為“彙總表”,如下圖所示。 2.找到“檢視程式碼”並開啟,查詢方法如下圖所示,有以下兩個方法:1.滑鼠右鍵點選“彙總表”,在下拉選單
C小程式—將一個磁碟檔案中的資訊複製到另一個磁碟檔案中。
#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){FILE *fp1, *fp2; //定義指向FILE型別檔案的指標變數char ch, fil
ios 將NSLog日誌重定向輸出到檔案中儲存(3)
#pragma mark - app 日誌檔案記錄,用於測試; - (void)redirectNSLogToDocumentFolder { //如果已經連線Xcode除錯則不輸出到檔案 /* if(isatty(STDOUT_FILENO)) {
log4j詳解 將指定日誌輸出到不同的檔案中
import org.apache.log4j.Logger; <span style="font-family: Arial, Helvetica, sans-serif;">public class HelloWorld {</span> <span style="whit
如何用java讀取csv檔案指定行列的資料,並將csv中資料元素隨機置零後儲存到另一個csv檔案中
這個流程可以大致分為兩步驟:1.讀取csv檔案中的資料2.生成隨機數,將csv的資料隨機置零,將新生成的檔案儲存到新的csv中一、首先我們進行第一步:讀取csv中的檔案:讀取函式格式為public static double readin(int row,int col)
假設一個文字檔案中儲存著100個整數,請將這100個整數按從小到大的順序寫到另一個檔案中
假設一個文字檔案中儲存著100個整數,請將這100個整數按從小到大的順序寫到另個文字檔案中去,並且在新檔案中每十個整數佔一行,原始檔名和目標檔名通過命令列引數獲取。程式如下: #include <stdio.h> void main(int argc, char
Matlab 將多個子函式寫到一個m檔案中
一般來講,在matlab中定義多個函式,需要存成多個m檔案,每一個檔案是一個函式 但是當我們的函式過於簡單,沒有必要存成多個檔案時,我們可以將多個子函式存在一個主函式下,這樣就可以存在一個m檔案中了。 例子 新建m檔案'makefuns.m' function fun
SpringBoot將所有依賴(包括本地jar包)打包到專案
Maven 新增本地依賴包 在專案根目錄新增lib資料夾,存放不在maven倉庫中存在的jar包 如下兩個推送包,(名字可以自定義) //華為推送服務端jar包 HwPush_SDK_Server_0_3_12.jar //小米推送服務端jar包 MiPush_SDK_Server_2_2_
springboot程式logback日誌基本配置,多個包不同日誌級別輸入到檔案中
日誌是程式中必不可少的內容。依據日誌我們可以有效診斷程式bug,統計使用者訪問和各主要功能的使用頻率時間段等資訊。因此我們會需要不同package使用不同的日誌級別,以及不同業務的日誌輸出到不同的檔案。下面本文簡要概述如何使用logback將不同包的不同級別日誌輸出到info1.txt中
java使用slf4j+log4j進行日誌記錄並將ERROR級別資訊入庫
1.maven 座標 <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>lo
logback日誌的使用,每天生成一個日誌檔案,以及error和其他級別日誌的分離
springboot會自動幫我們讀取logback的配置檔案,我們實現只需要新增即可在application中配置日誌檔案的位置logging: config: classpath:conf/logback-dev.xml配置檔案的內容如下:<?xml versio
Maven將所有依賴打成一個jar包
需求 將專案依賴的jar包打成一個jar包 程式碼 <build> <finalName>${project.artifactId}</finalName> <defaultGoal>package</d