1.進階說明
通過配置Layout打印格式化的日志,
Log4j2支持很多的Layouts:
CSV GELF HTML JSON Pattern Serialized Syslog XML YAML
本文僅介紹Pattern Layouts的詳細使用。
本文基於Log4j2基本使用入門。
請先參考上面的基本使用入門。
2.Pattern Layouts
Pattern Layouts是一個靈活的布局,
是最常用的日志格式配置。
該類的目標是格式化一個日志事件並返回結果,
結果的格式取決於轉換模式。
轉換模式與c語言中printf函數的轉換模式密切相關。
轉換模式由稱為轉換說明符的文字文本和格式控制表達式組成。
注意,任何文字文本,包括特殊字符,都可能包含在轉換模式中。
特殊字符包括\t、\n、\r、\f,使用\輸出一個反斜杠。
每個轉換說明符以百分號(%)開頭,
后面是可選的格式修飾符和必填的轉換字符。
格式修飾符控制字段寬度、填充、左對齊和右對齊等內容。
轉換字符指定數據的類型,例如日期、線程名、日志級別、日志名稱等等。
3.一個簡單的例子
log4j2.xml中的PatternLayout配置:
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
對應輸出的日志信息:
11:33:08.440 [main] FATAL org.apache.logging.log4j.Log4j2Test - fatal level log
詳細對應關系:
數據類型 | 轉換字符 | 輸出日志 |
---|---|---|
日期 | %d{HH:mm:ss.SSS} | 11:33:08.440 |
線程名 | %t | main |
日志級別 | %-5level | FATAL |
日志名稱 | %logger{36} | org.apache.logging.log4j.Log4j2Test |
日志信息 | %msg | fatal level log |
換行 | %n | 日志結束換行 |
另外配置中的空白字符和[]-等字符都是按照原樣輸出的。
4.PatternLayout參數
屬性 | 說明 |
---|---|
charset | 指定日志字符集 |
pattern | 指定日志輸出格式 |
alwaysWriteExceptions | 默認為true,輸出異常 |
header | 可選項,包含在每個日志文件的頂部 |
footer | 可選項,包含在每個日志文件的尾部 |
上面沒有把全部參數列出來,
下面僅介紹pattern參數的詳細配置。
5.pattern屬性
pattern可以配置各種類型的轉換字符,
轉換字符又稱為占位符,
在打印日志的時候會被替換為實際的值。
轉換字符 | 說明 |
---|---|
c{precision} logger{precision} |
輸出發布日志事件的日志程序的名稱。 |
C{precision} class{precision} |
輸出發出日志記錄請求的調用者的完全限定類名,可能會影響性能,謹慎使用。 |
d{pattern} date{pattern} |
輸出日志事件的日期。日期轉換說明符后面可以跟一組大括號,其中包含每個SimpleDateFormat的日期和時間模式字符串。 |
enc{pattern}{[HTML|XML|JSON|CRLF]} encode{pattern} {[HTML|XML|JSON|CRLF]} |
對適合用特定標記語言輸出的特殊字符進行編碼和轉義。默認情況下,如果只指定了一個選項,它將對HTML進行編碼。第二個選項用於指定應該使用哪種編碼格式。此轉換器特別適用於對用戶提供的數據進行編碼,這樣輸出數據就不會寫得不正確或不安全。 |
ex exception throwable |
輸出綁定到日志事件的可拋出跟蹤,默認情況下,這將輸出完整的跟蹤,就像調用Throwable. printstacktrace()時通常會看到的那樣。 |
F file |
輸出發出日志記錄請求的文件名。生成文件信息(位置信息)是一項昂貴的操作,可能會影響性能,請謹慎使用。 |
highlight{pattern}{style} | 根據當前事件的日志級別將ANSI顏色添加到所包含模式的結果中。(見Jansi配置。) |
l location |
輸出生成日志事件的調用者的位置信息。位置信息取決於JVM實現,但通常由調用方法的完全限定名、調用者源文件名和括號之間的行號組成。生成位置信息是一項昂貴的操作,可能會影響性能,請謹慎使用。 |
L line |
上面location功能的簡略版,僅僅輸出發出日志請求的行號。同樣生成行號信息可能會影響性能,請謹慎使用。 |
m{nolookups}{ansi} msg{nolookups}{ansi} message{nolookups}{ansi} |
輸出應用程序提供的與日志事件關聯的消息。 |
M method |
輸出發出日志請求的方法名。生成調用者的方法名(位置信息)是一項昂貴的操作,可能會影響性能,請謹慎使用。 |
maxLen maxLength |
輸出評估模式的結果並截斷結果。如果長度大於20,則輸出將包含一個拖尾省略號。如果提供的長度無效,則使用默認值100。示例語法:%maxLen{%p: %c{1} - %m%notEmpty{=>%ex{short}}}{160}將被限制為160個字符,后面加一個省略號。另一個例子:%maxLen{%m}{20}將被限制為20個字符,並且沒有拖尾省略號。 |
n | 輸出平台相關的行分隔符字符。與使用不可移植的行分隔符字符串(如“\n”或“\r\n”)相比,這個轉換字符提供了幾乎相同的性能。因此,它是指定行分隔符的首選方法。 |
N nano |
在創建日志事件時輸出System.nanoTime()的結果。 |
pid{[defaultValue]} processId{[defaultValue]} |
如果底層平台支持,則輸出進程ID。如果平台不支持進程id,可以指定一個可選的默認值來顯示。 |
p level |
輸出日志事件的級別。 |
r relative |
輸出從JVM啟動到日志事件創建的毫秒數。 |
replace{pattern}{regex}{substitution} | 將正則表達式'regex'的出現替換為對模式求值后字符串中的'替換'。例如,“%replace{%msg}{\s}{}”將刪除事件消息中包含的所有空格。模式可以任意復雜,特別是可以包含多個轉換關鍵字。例如,“%替換{%logger %msg}{\。}{/}將用正斜杠替換日志記錄器或事件消息中的所有點。 |
sn sequenceNumber |
包含將在每個事件中遞增的序列號。計數器是一個靜態變量,因此它只在共享相同轉換器類對象的應用程序中是唯一的。 |
T tid threadId |
輸出生成日志事件的線程ID。 |
t tn thread threadName |
輸出生成日志事件的線程名稱。 |
tp threadPriority |
輸出生成日志事件的線程的優先級。 |
fqcn | 輸出記錄器的完全限定類名。 |
endOfBatch | 輸出日志事件的EndOfBatch狀態,為“true”或“false”。 |
u{"RANDOM" | "TIME"} uuid |
包括一個隨機的或基於時間的UUID。基於時間的UUID是一個1型UUID,可以產生高達每毫秒10000獨特的id,將使用每個主機的MAC地址,並試圖確保唯一性跨多個jvm和/或類加載器在同一個主機上0到16384之間的一個隨機數將與每個UUID生成類的實例相關聯,包括在每一個基於時間的UUID生成。因為基於時間的uuid包含MAC地址和時間戳,所以應該小心使用它們,因為它們可能會導致安全漏洞。 |
% | 序列%%輸出一個百分比符號。 |
6.logger屬性詳解
c{precision}
logger{precision}
logger轉換說明符后面可以跟着precision精度說明符,
后者由一個十進制整數組成,也可以是一個以十進制整數開頭的模式。
當精度說明符是一個整數值時,它減少了記錄器名稱的大小。
如果數字為正,則布局將打印最右邊的記錄器名稱組件的相應數量。
如果為負,則布局將刪除最左側記錄器名稱組件的相應數量。
如果精度包含任何非整數字符,則布局將根據模式縮寫名稱。
如果精度整數小於1,布局仍然完整打印最右邊的標記。
默認情況下,布局將完整打印日志程序名稱。
Conversion Pattern | Logger Name | Result |
---|---|---|
%c{1} | org.apache.commons.Foo | Foo |
%c{2} | org.apache.commons.Foo | commons.Foo |
%c{10} | org.apache.commons.Foo | org.apache.commons.Foo |
%c{-1} | org.apache.commons.Foo | apache.commons.Foo |
%c{-2} | org.apache.commons.Foo | commons.Foo |
%c{-10} | org.apache.commons.Foo | org.apache.commons.Foo |
%c{1.} | org.apache.commons.Foo | o.a.c.Foo |
%c{1.1..} | org.apache.commons.test.Foo | o.a...Foo |
%c{.} | org.apache.commons.test.Foo | ....Foo |
7.class屬性詳解
C{precision}
class{precision}
輸出發出日志記錄請求的調用者的完全限定類名。
此轉換說明符可選后跟精度說明符,
它遵循與logger轉換器相同的規則。
生成調用者的類名(位置信息)是一項昂貴的操作,
可能會影響性能,請謹慎使用。
所以一般將類名作為日志名稱,
使用如下的代碼記錄日志:
private static Logger LOG = LogManager.getLogger(Log4j2Test.class);
配置log4j2.xml時使用logger{precision}打印日志程序名稱,
就能打印出生成日志的調用者的全限定類名,
通過這種方法是不損害性能的。
8.date屬性詳解
d{pattern}
date{pattern}
輸出日志事件的日期。
日期轉換說明符后面可以跟一組大括號,
其中包含每個SimpleDateFormat的日期和時間模式字符串。
Pattern | Example |
---|---|
%d{DEFAULT} | 2012-11-02 14:34:02,123 |
%d{DEFAULT_MICROS} | 2012-11-02 14:34:02,123456 |
%d{DEFAULT_NANOS} | 2012-11-02 14:34:02,123456789 |
%d{ISO8601} | 2012-11-02T14:34:02,781 |
%d{ISO8601_BASIC} | 20121102T143402,781 |
%d{ISO8601_OFFSET_DATE_TIME_HH} | 2012-11-02'T'14:34:02,781-07 |
%d{ISO8601_OFFSET_DATE_TIME_HHMM} | 2012-11-02'T'14:34:02,781-0700 |
%d{ISO8601_OFFSET_DATE_TIME_HHCMM} | 2012-11-02'T'14:34:02,781-07:00 |
%d{ABSOLUTE} | 14:34:02,781 |
%d{ABSOLUTE_MICROS} | 14:34:02,123456 |
%d{ABSOLUTE_NANOS} | 14:34:02,123456789 |
%d{DATE} | 02 Nov 2012 14:34:02,781 |
%d{COMPACT} | 20121102143402781 |
%d{UNIX} | 1351866842 |
%d{UNIX_MILLIS} | 1351866842781 |
還可以定義自定義日期格式:
Pattern | Example |
---|---|
%d{HH:mm:ss,SSS} | 14:34:02,123 |
%d{HH:mm:ss,nnnn} to %d{HH:mm:ss,nnnnnnnnn} | 14:34:02,1234 to 14:34:02,123456789 |
%d{dd MMM yyyy HH:mm:ss,SSS} | 02 Nov 2012 14:34:02,123 |
%d{dd MMM yyyy HH:mm:ss,nnnn} to %d{dd MMM yyyy HH:mm:ss,nnnnnnnnn} | 02 Nov 2012 14:34:02,1234 to 02 Nov 2012 14:34:02,123456789 |
%d{HH:mm:ss}{GMT+0} | 18:34:02 |
%d{UNIX}輸出UNIX時間(以秒為單位),
%d{UNIX_MILLIS}以毫秒為單位輸出UNIX時間。
UNIX時間是當前時間與1970年UTC年1月1日午夜之間的時間差,
UNIX以秒為單位,UNIX_MILLIS以毫秒為單位。
雖然時間單位是毫秒,但粒度取決於操作系統(Windows)。
這是輸出事件時間的一種有效方法,
因為只進行從long到String的轉換,不涉及日期格式。
當在Java 9上運行時,
Log4j 2.11增加了對時間戳timestamps的支持,
使得它比毫秒milliseconds更精確。
9.L和l屬性的區別
配置log4j2.xml:
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%l] - %msg%n" />
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%L] - %msg%n" />
打印出對應的日志:
2019-10-12 15:28:25.877 [main] ERROR [org.apache.logging.log4j.Log4j2Test.logAll(Log4j2Test.java:18)] - error level log
2019-10-12 15:30:34.535 [main] ERROR [18] - error level log
10.特殊符號
有些特殊符號不能直接打印,
需要使用實體名稱或者編號,
才能原樣打印特殊字符。
特殊符號 | 實體名稱 | 編號 |
---|---|---|
& | & | & |
< | < | < |
> | > | > |
" | " | " |
' | ' | ' |
11.格式修飾符
默認情況下,相關信息按原樣輸出。
然而,在格式修飾符的幫助下,可以改變最小字段寬度、最大字段寬度和對齊。
可選的格式修飾符放在百分號和轉換字符之間。
這是一個十進制常量,表示要輸出的最小字符數。
可以是正數,也可以是負數(帶減號(-)字符),
整數表示右對齊,負數表示左對齊。
如果數據項輸出字符數不夠,則在左邊或右邊填充空格,直到達到最小寬度為止。
若要使用0作為填充字符,請在最小字段寬度前加上0。
如果數據項大於最小字段寬度,則擴展字段以容納數據,數據項的值不會被截斷。
可以使用最大字段寬度修飾符限制最大寬度,
該修飾符由一個句點后跟一個十進制常數指定。
如果數據項比最大字段長,則從數據項的開頭而不是末尾刪除額外的字符。
例如,數據項最大字段寬度為8,數據項長度為10個字符,
然后刪除數據項的前2個字符,保留的是后8個字符。
可以在句點后面追加一個減號改為從末尾開始截斷。
那么上面的數據項的最后2個字符將被刪除。
下面是類別轉換說明符的各種格式修飾符示例。
格式修飾符 | 對齊方式 | 最小寬度 | 最大寬度 | 說明 |
---|---|---|---|---|
%20c | 右對齊 | 20 | 無 | 不足20個字符則在數值前面用空格補足,超過20個字符則保留原信息。 |
%-20c | 左對齊 | 20 | 無 | 同上。 |
%.30c | NA | 無 | 30 | 如果信息超過30個字符,則只保留最后30個字符。 |
%20.30c | 右對齊 | 20 | 30 | 不足20個字符則在信息前面用空格補足,超過30個字符則只保留最后30個字符。 |
%-20.30c | 左對齊 | 20 | 30 | 同上。 |
%-20.-30c | 左對齊 | 20 | 30 | 不足20個字符則在信息前面用空格補足,超過30個字符則只保留前面30個字符。 |