随着通用日志元件轉入 Slf4j,logback 也變成了預設的日志實作,像 log4j 一樣,logback.xml 中也可以使用系統屬性或環境變量,如 ${catalina.home}。在 log4j.properties 中,如果變量在系統屬性和環境變量中找不到的話預設為 "" 空字元串,而到了 logback.xml 中如果某個變量找不到預設就是 "變量名_IS_UNDEFINED" 了,這樣就比較奇怪了。
那如何在沒有配置 catalina.home 系統屬性或環境變量時設定一個預設值呢,例如,沒有 catalina.home 時取值為 ".",這時值日志檔案的路徑就是
./logs/unmi-%d{yyyy-MM-dd}.log
了,也就是生成中目前目錄下的 logs 子目錄中,這樣算是很友好的方式。下面就來分析怎麼一步步找到答案的,沒耐心或是隻求結果的話,直接滾屏到下面就行。
我們的問題是,對于下面那樣的 logback.xml 配置:
xml version = "1.0" encoding = "UTF-8" ?>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n pattern >
encoder >
appender >
${catalina.home}/logs/unmi-%d{yyyy-MM-dd}.log fileNamePattern >
10 maxHistory >
rollingPolicy >
%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n pattern >
encoder >
appender >
root >
configuration >
因為測試時直接在 Eclipse 或控制台下執行,在未定義 catalina.home 的情況下,一運作就會在目前目錄下生成 catalina.home_IS_UNDEFINED 目錄,其中有 logs 子目錄,再才是 unmi-2014-05-19.log 這個日志檔案。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yYkRGNlJGZjVmZ3ETM5gTN1UTNiNDZ4gjZkNDOjdTNx8CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
搜尋了網上關于預設值的解決方案,有說在 logback.xml 中寫條件表達式,例如:
logs/unmi-%d{yyyy-MM-dd}.log fileNamePattern >
then >
${catalina.home}/logs/unmi-%d{yyyy-MM-dd}.log fileNamePattern >
else >
if >
上面的 if-then-else 是有問題的 The FileNamePattern option must be set before using TimeBasedRollingPolicy,需要把 if 的覆寫範圍擴大,不過試了也不怎麼爽。
final static String _IS_UNDEFINED = "_IS_UNDEFINED";
注:從這個類的 lookupKey(String key) 方法中可以知道 logback 從四個地方取變量值,分别是 propertyContainer0, propertyContrainer1, System, Evn,前兩不知道沒關系,後兩個我們明白先從 System 屬性,沒有再從環境變量中取。
上面我們會想到 Node 除了有 payload 還有一個 defaultPart 用了設定預設值部分。至于預設值怎麼設定,猜測試是 ${catalina.home:abc},沒用,不過别急,logback 的測試用例告訴了我們表達式的寫法。
${v2:-toto} //格式是 ${變量名:-預設值},光有冒号還不夠,再加條短線後面才是預設值
是以學習它後,前面的日志檔案名配置部分就寫成
${catalina.home:-.}/logs/unmi-%d{yyyy-MM-dd}.log fileNamePattern >
xml version = "1.0" encoding = "UTF-8" ?>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n pattern >
encoder >
appender >
${catalina.home:-.}/logs/unmi-%d{yyyy-MM-dd}.log fileNamePattern >
10 maxHistory >
rollingPolicy >
%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n pattern >
encoder >
appender >
root >
configuration >
多看看這 OptionHelperTest 測試用例,還能發現預設值也能用變量,如
${B:-${A}}