spring boot 2.1.x log4j2 配置

本文通過項目中的日志配置問題,引出并總結(jié)一下spring boot 2.1.x 中 log4j2 的配置

現(xiàn)象

在服務器上調(diào)試項目的時候,發(fā)現(xiàn)日志文件生成的路徑有問題,總是找不到日志位置,后來測試發(fā)現(xiàn)每次都在當前目錄下生成 log/xxx.log
查看項目配置如下:

logging.level.com.xxx.yyy=INFO
logging.file=log/xxx.log

在resource目錄下柿赊,有log4j.properties(記住這個文件名稱)俩功,內(nèi)容如下

log4j官網(wǎng)圖片

解決(測試基于spring boot 2.1.5)

1幻枉、因為對此配置不熟悉,直接修改了配置文件中的appender.File值為絕對路徑诡蜓,后經(jīng)測試根本不生效

2熬甫、修改spring boot 配置文件中的logging.file為絕對路徑,發(fā)現(xiàn)配置生效
所以其實是log4j的配置文件根本就沒有被加載

3蔓罚、查看spring boot 官方文檔椿肩,可以看到如下說明



支持如上幾種log system以及各自的自動加載的配置文件名稱,唯獨沒有看到 .properties 后綴的支持豺谈,覺得不應該

4郑象、只能通過源碼來找答案了
AbstractLoggingSystem

@Override
public void initialize(LoggingInitializationContext initializationContext,
        String configLocation, LogFile logFile) {
    // 如果指定了log配置文件路徑(logging.config)
    if (StringUtils.hasLength(configLocation)) {
        // 指定了自定義配置的處理方法
        initializeWithSpecificConfig(initializationContext, configLocation, logFile);
        return;
    }
    // 未指定則加載默認配置
    initializeWithConventions(initializationContext, logFile);
}

看到這里的initialize方法和剛才的官方文檔說明,想到大概是properties需要顯示的通過logging.config來指定茬末,加上后測試厂榛,發(fā)現(xiàn)依然沒用盖矫,只能繼續(xù)往下看源碼

通過initializeWithSpecificConfig方法我們一路找下去,可以找到Log4J2LoggingSystem的loadConfiguration方法

protected void loadConfiguration(String location, LogFile logFile) {
    Assert.notNull(location, "Location must not be null");
    try {
        LoggerContext ctx = getLoggerContext();
        URL url = ResourceUtils.getURL(location);
        ConfigurationSource source = getConfigurationSource(url);
        // 通過對應的配置工廠加載配置
        ctx.start(ConfigurationFactory.getInstance().getConfiguration(ctx, source));
    }
    catch (Exception ex) {
        throw new IllegalStateException(
                "Could not initialize Log4J2 logging from " + location, ex);
    }
}

看到這里又產(chǎn)生了疑惑击奶,如下圖辈双,除了官方文檔提到的那些格式,還有PropertiesConfigurationFactory柜砾,說明properties一定是可以被解析的湃望,debug發(fā)現(xiàn)的確進入到這里,也解析了配置文件痰驱,但是結(jié)果依然是沒有生效

配置工廠

為了測試是否是環(huán)境問題证芭,將配置文件修改為官方推薦的log4j2.xml,發(fā)現(xiàn)此配置生效担映,說明問題還是出在properties文件中

不得不說檩帐,解決問題果然還是得靠官網(wǎng),通過查閱log4j2官網(wǎng)發(fā)現(xiàn)另萤,項目這里的配置犯了很低級的錯誤湃密,我們依賴的是log4j2,而properties文件里還是log4j 1.x的語法四敞,從log4j2官方copy如下配置

status = error
dest = err
name = PropertiesConfig
 
property.filename = target/rolling/rollingtest.log
 
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
 
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n
appender.console.filter.threshold.type = ThresholdFilter
appender.console.filter.threshold.level = error
 
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${filename}
appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 2
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=100MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 5
 
logger.rolling.name = com.example.my.app
logger.rolling.level = debug
logger.rolling.additivity = false
logger.rolling.appenderRef.rolling.ref = RollingFile
 
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = STDOUT

果不其然泛源,配置生效了
可是現(xiàn)在還有一個疑問就是,為什么spring boot官網(wǎng)沒有說明properties配置文件的默認命名格式忿危,還是說必須得用logging.config指定

繼續(xù)看源碼达箍,還有一條分支沒有看,不顯示指定配置文件的情況

private void initializeWithConventions(
        LoggingInitializationContext initializationContext, LogFile logFile) {
    String config = getSelfInitializationConfig();
    if (config != null && logFile == null) {
        // self initialization has occurred, reinitialize in case of property changes
        reinitialize(initializationContext);
        return;
    }
    if (config == null) {
        config = getSpringInitializationConfig();
    }
    if (config != null) {
        loadConfiguration(initializationContext, config, logFile);
        return;
    }
    loadDefaults(initializationContext, logFile);
}

先通過getSelfInitializationConfig方法找到log4j2對應的初始化配置方法

private String[] getCurrentlySupportedConfigLocations() {
    List<String> supportedConfigLocations = new ArrayList<>();
    supportedConfigLocations.add("log4j2.properties");
    if (isClassAvailable("com.fasterxml.jackson.dataformat.yaml.YAMLParser")) {
        Collections.addAll(supportedConfigLocations, "log4j2.yaml", "log4j2.yml");
    }
    if (isClassAvailable("com.fasterxml.jackson.databind.ObjectMapper")) {
        Collections.addAll(supportedConfigLocations, "log4j2.json", "log4j2.jsn");
    }
    supportedConfigLocations.add("log4j2.xml");
    return StringUtils.toStringArray(supportedConfigLocations);
}

看到這里上面的疑惑也就解決了铺厨,因為項目的配置文件名稱不符合初始化配置缎玫,應當改為log4j2.properties

如果classpath中沒有上述命名格式的配置文件,則獲取-spring.命名標識的配置文件

protected String[] getSpringConfigLocations() {
    String[] locations = getStandardConfigLocations();
    for (int i = 0; i < locations.length; i++) {
        String extension = StringUtils.getFilenameExtension(locations[i]);
        locations[i] = locations[i].substring(0,
                locations[i].length() - extension.length() - 1) + "-spring."
                + extension;
    }
    return locations;
}

如果也沒有找到解滓,就加載默認配置

@Override
protected void loadDefaults(LoggingInitializationContext initializationContext,
        LogFile logFile) {
    if (logFile != null) {
        loadConfiguration(getPackagedConfigFile("log4j2-file.xml"), logFile);
    }
    else {
        loadConfiguration(getPackagedConfigFile("log4j2.xml"), logFile);
    }
}
spring boot log4j2 默認配置文件
總結(jié)

1赃磨、去掉logback的依賴,引入spring-boot-starter-log4j2洼裤,官方文檔有這里就不再贅述
2邻辉、新建log4j2.properties(當然可以是支持的其他后綴文件),如果想要spring boot 自動識別配置文件腮鞍,記得文件名要是log4j2

所以值骇,解決問題最有效的方式,還是得通過官網(wǎng)和源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末移国,一起剝皮案震驚了整個濱河市吱瘩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌迹缀,老刑警劉巖使碾,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皱卓,死亡現(xiàn)場離奇詭異,居然都是意外死亡部逮,警方通過查閱死者的電腦和手機娜汁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兄朋,“玉大人掐禁,你說我怎么就攤上這事÷停” “怎么了傅事?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長峡扩。 經(jīng)常有香客問我蹭越,道長,這世上最難降的妖魔是什么教届? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任响鹃,我火速辦了婚禮,結(jié)果婚禮上案训,老公的妹妹穿的比我還像新娘买置。我一直安慰自己,他們只是感情好强霎,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布忿项。 她就那樣靜靜地躺著,像睡著了一般城舞。 火紅的嫁衣襯著肌膚如雪轩触。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天家夺,我揣著相機與錄音脱柱,去河邊找鬼。 笑死秦踪,一個胖子當著我的面吹牛褐捻,可吹牛的內(nèi)容都是我干的掸茅。 我是一名探鬼主播椅邓,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昧狮!你這毒婦竟也來了景馁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤逗鸣,失蹤者是張志新(化名)和其女友劉穎合住,沒想到半個月后绰精,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡透葛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年笨使,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片僚害。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡硫椰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出萨蚕,到底是詐尸還是另有隱情靶草,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布岳遥,位于F島的核電站奕翔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏浩蓉。R本人自食惡果不足惜派继,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捻艳。 院中可真熱鬧互艾,春花似錦、人聲如沸讯泣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽好渠。三九已至昨稼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拳锚,已是汗流浹背假栓。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留霍掺,地道東北人匾荆。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像杆烁,于是被迫代替她去往敵國和親牙丽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容