什么是 layout ?
Layout 是Logback中的組件,負責將到來的event轉換成 String。Layout 接口中的 doLayout(E event)方法接受一個模板類 event 參數,並返回 String 字符串。
下面是 Layout 接口概要
public interface Layout<E extends ContextAware, LifeCycle {
String doLayout(E event);
String getFileHeader();
String getPresentationHeader();
String getFileFooter();
String getPresentationFooter();
String getContentType();
}
logback-classic 中僅僅處理 ILoggingEvent。
下面我們嘗試寫一個自己的layout類
package chapters.layouts;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.LayoutBase;
public class MySampleLayout2 extends LayoutBase<ILoggingEvent {
String prefix = null;
boolean printThreadName = true;
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public void setPrintThreadName(boolean printThreadName) {
this.printThreadName = printThreadName;
}
public String doLayout(ILoggingEvent event) {
StringBuffer sbuf = new StringBuffer(128);
if (prefix != null) {
sbuf.append(prefix + ": ");
}
sbuf.append(event.getTimeStamp() - event.getLoggerContextVO().getBirthTime());
sbuf.append(" ");
sbuf.append(event.getLevel());
if (printThreadName) {
sbuf.append(" [");
sbuf.append(event.getThreadName());
sbuf.append("] ");
} else {
sbuf.append(" ");
}
sbuf.append(event.getLoggerName());
sbuf.append(" - ");
sbuf.append(event.getFormattedMessage());
sbuf.append(LINE_SEP);
return sbuf.toString();
}
}
可以看到 MySampleLayout2 繼承自
LayoutBase
,LayoutBase 這個類實現了很多其他內置layout 通用的函數,例如檢測 layout 是否開啟或關閉,設置header,footer,以及content type 等。它使開發人員可以只關注自己的格式化實現。記住,LayoutBase是泛型的,因此在使用logbook-classic時需要制定泛型 LayoutBase<ILoggingEvent>,而在hogback-access中 event的類型就是 IAccessEvent
下面是引用自己的Layout類
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"
<layout class="chapters.layouts.MySampleLayout2"
<prefix>MyPrefix</prefix>
<printThreadName>false</printThreadName>
</layout>
</encoder>
</appender>
<root level="DEBUG"
<appender-ref ref="STDOUT" />
</root>
</configuration>
可以看出,我們layout類中的變量,可以通過<layout>標簽下<屬性名>的方式來使用set方法賦值。
PatternLayout是logback自帶的一個比較靈活的布局類。與其他layout一樣,PatternLayout接收一個logging event 然后返回一個String。然而這個String可以通過conversion pattern(轉換模板)來個性化。與之相比,我們上面自級寫的layout類的輸出日志的格式也就寫死在代碼上了。
pattern 的格式的樣子與c語言中的printf函數非常相似,由文本,以及稱為conversion specifier(格式符)的格式控制表達式組成。格式符由%開頭,並且跟隨可選的的format modifiers(格式編輯符),一個conversion word(轉換字) 以及用{}包裹可選參數。conversion word控制數據域,例如logger name , level , thread name 等等。format modifiers 控制數據域的快讀,padding ,左右浮動。
Encoder那篇博文也說過,在0.9.19版本引入 Encoder之后,FileAppender及其子類不在直接使用<Layout>,而是使用<encoder>包裹<layout>的方式。原因也說了,是因為layout只能將event轉換成string,並且不能控制日志輸出過,無法做先緩存再一次性寫出的操作。
下面我們看看,不是配置文件的情況下,手寫代碼使用PatternLayout
package chapters.layouts;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.ConsoleAppender;
public class PatternSample {
static public void main(String[] args) throws Exception {
Logger rootLogger = (Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
LoggerContext loggerContext = rootLogger.getLoggerContext();
// we are not interested in auto-configuration
loggerContext.reset();
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(loggerContext);
encoder.setPattern("%-5level [%thread]: %message%n");
encoder.start();
ConsoleAppender<ILoggingEvent appender = new ConsoleAppender<ILoggingEvent>();
appender.setContext(loggerContext);
appender.setEncoder(encoder);
appender.start();
rootLogger.addAppender(appender);
rootLogger.debug("Message 1");
rootLogger.warn("Message 2");
}
}
將會輸出如下日志
DEBUG [main]: Message 1
WARN [main]: Message 2
下面我們看看PatternLayout到底有哪些Conversion word 以及 格式化符
需要注意的時,有些符號是轉義符,因此需要使用 “\” 來轉換,例如
\( \) \%
Effect | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
c{
length}
lo{
length}
logger{
length}
|
logger 的名稱
可接收一個可選參數,設置logger name的長度。默認輸出全名,參數0代表只輸出Logger name最右邊點號的值,如只輸出類名,不輸出包名。
注意:點號最右邊的字符串不會被壓縮,如果length的值小於Logger name,其他字符串最小也只能被壓縮成1個字符,但不會缺失。
|
||||||||||||||||||||||||
C{
length}
class{
length}
|
日志請求調用所在的全限定類名(caller data中的一部分),之前說過獲取caller data消耗資源高。所以非必要,不建議。 | ||||||||||||||||||||||||
contextName
cn
|
logger context上下文名稱 | ||||||||||||||||||||||||
d{pattern} date{pattern} d{pattern, timezone}
date{
pattern,
timezone}
|
logging event的時間
可接收時間格式化參數(默認ISO 8601,格式參照
java.text.SimpleDateFormat .)
以及時區參數(默認Jvm時區,如果所設置的時區有錯,則使用GMT時區)
需要注意,在pattern中,如果要使用逗號, 需要用引號括起來。 例如%date{
"HH:mm:ss,SSS
"}
|
||||||||||||||||||||||||
F / file | 日志請求所在的java source file 文件名。不提倡,速度慢。參考caller data | ||||||||||||||||||||||||
caller{depth}
caller{depthStart..depthEnd}
caller{depth, evaluator-1, ... evaluator-n}
caller{depthStart..depthEnd, evaluator-1, ... evaluator-n}
|
日志請求的caller data
包含 caller 的全限定類名,文件名,以及行號。
參數evaluator指定鑒別器,可以實現特定日志請求才包含caller data
參數depth,指定caller data 的深度
例如,
%caller{2} 將輸出如下
0 [main] DEBUG - logging statement
Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
%caller{3} 如下
16 [main] DEBUG - logging statement
Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22) Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)
也可以指定一個范圍
%caller{1..2} 如下
0 [main] DEBUG - logging statement
Caller+0 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
而
%caller{3, CALLER_DISPLAY_EVAL},當鑒別器返回true時才會輸出caller data
|
||||||||||||||||||||||||
L / line | caller data 行號,速度慢,不推薦 | ||||||||||||||||||||||||
m / msg / message | logging event 的 message | ||||||||||||||||||||||||
M / method | caller data 的method ,速度慢,不推薦 | ||||||||||||||||||||||||
n | 輸出與系統平台相關的換行符。例如linux 的"\n", 或者 windows"\r\n" | ||||||||||||||||||||||||
p / le / level | 日志的level | ||||||||||||||||||||||||
r / relative | 日志產生時,應用已存活的時間 | ||||||||||||||||||||||||
t / thread | 產生logging event 的線程名 | ||||||||||||||||||||||||
X{key:-defaultVal}
mdc{
key:-defaultVal}
|
輸出指定MDC指定Key的值,沒有輸出默認值,如果不通過 :- 指定默認值,當key不存在,則輸出空字符串 | ||||||||||||||||||||||||
ex{depth} exception{depth} throwable{depth} ex{depth, evaluator-1, ..., evaluator-n} exception{depth, evaluator-1, ..., evaluator-n}
throwable{depth, evaluator-1, ..., evaluator-n}
|
輸出 exception的相關的stack trace 的值。默認是全部 stack trace
depth可以選擇以下幾種類型的值:
以下是一些例子:
evaluator鑒別器,意義參照caller data中的聲明。當evaluator返回false,則輸出,與caller conversion相反哦。切記
|
||||||||||||||||||||||||
xEx{depth} xException{depth} xThrowable{depth} xEx{depth, evaluator-1, ..., evaluator-n} xException{depth, evaluator-1, ..., evaluator-n}
xThrowable{depth, evaluator-1, ..., evaluator-n}
|
與%ex類似,但是包含了包名以及版本號,如果包,版本號不確定,則會附帶~波浪號。如果pattern不指定任何%ex或%xEx,則會默認添加%xEx。
但是需要注意,如果你使用Netbeans,則獲取包名版本號可能導致阻塞,所以需要禁止%ex來防止這種默認行為。
例子:
java.lang.NullPointerException
at com.xyz.Wombat(Wombat.java:57)
~[wombat-1.3.jar:1.3]
at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.5.0_06]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.5.0_06]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.5.0_06]
at java.lang.reflect.Method.invoke(Method.java:585) ~[na:1.5.0_06]
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59) [junit-4.4.jar:na] at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98) [junit-4.4.jar:na] ...etc
|
||||||||||||||||||||||||
nopex
nopexception
|
無視 exception 信息,同時禁止PatternLayout中默認的安全機制,就是在pattern中添加%eXe。 | ||||||||||||||||||||||||
marker |
日志的marker 標簽
如果marker 存在 子marker,則轉換器都會將它們按以下格式輸出
parentName [ child1, child2 ]
|
||||||||||||||||||||||||
property{key} |
輸出指定Key的property屬性值,如何定義屬性呢,之前也講過
define variables
如果key指定的property不在logger context中,則會在system properties中找,如果還沒有,就返回 Property_HAS_NO_KEY
|
||||||||||||||||||||||||
replace(p){r, t} |
以 t 值 替換 在 p 中出現的符合 r 模板的值。
例如 "%replace(%msg){'\s', '’}" 會刪除event message中所有的空格
注意,p 可以包含多個conversion word 。注意轉義符的問題。 例如:%replace(%logger %msg){'\.', '/'}"
|
||||||||||||||||||||||||
rEx{depth} rootException{depth} rEx{depth, evaluator-1, ..., evaluator-n}
rootException{depth, evaluator-1, ..., evaluator-n}
|
與%eXe類似,不同的是,將 root cause 放在了第一句,原本一般是在最后一句的。
例如:
java.lang.NullPointerException
at com.xyz.Wombat(Wombat.java:57) ~[wombat-1.3.jar:1.3] at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3] Wrapped by: org.springframework.BeanCreationException: Error creating bean with name 'wombat': at org.springframework.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248) [spring-2.0.jar:2.0] at org.springframework.AbstractBeanFactory.getBean(AbstractBeanFactory.java:170) [spring-2.0.jar:2.0] at org.apache.catalina.StandardContext.listenerStart(StandardContext.java:3934) [tomcat-6.0.26.jar:6.0.26] |
大多數情況下,pattern中的文本會包含空格以及一些其他的界定符,這樣就會與conversion words 混淆在一起難以理解。
例如在模板 "%level [%thread] - %message%n” 中就包含了 [ ] - space(空格)這些文本值。但是如果我們直接寫成這樣"%date%nHello”,那轉換器就會認為%nHello是個未知的conversion word,logbook就會將%nHello輸出為%PARSER_ERROR[nHello],不過如果你非得這樣,也可以在%n插入空參數花括號,例如"%date%n{}Hello"
說完了conversion word,我們再來看看 Format modifiers
我們可以通過Format modifier來改變數值域的最大,最小寬度,左,右對齊,顏色等等。
下面是一些說明最大,最小寬度,左右對齊的例子:
Format modifier | Left justify | Minimum width | Maximum width | Comment |
---|---|---|---|---|
%20logger | false | 20 | none | 指定最小寬度,如果logger name少於20個字符,則默認向右對齊 |
%-20logger | true | 20 | none | -號 代表向左對齊,同樣設置最小寬度為20 |
%.30logger | NA | none | 30 | .點號后面的值,代表最大寬度,超過最大長度,默認,截斷左邊的值 |
%20.30logger | false | 20 | 30 | 設置最大最小寬度 |
%-20.30logger | true | 20 | 30 | 設置最大最小寬度,並且左對齊,超過最大寬度,默認截斷左邊的值 |
%.-30logger | NA | none | 30 | 這是最大寬度,在.點號右邊加-減號,代表指定截斷從尾部(右邊)開始 |
下面是一些例子,注意其中的”[ ]"只是為了方便理解,並不是pattern中的值
Format modifier | Logger name | Result |
---|---|---|
[%20.20logger] | main.Name | [ main.Name] |
[%-20.20logger] | main.Name | [main.Name ] |
[%10.10logger] | main.foo.foo.bar.Name | [o.bar.Name] |
[%10.-10logger] | main.foo.foo.bar.Name | [main.foo.f] |
下面我們看幾個常用的例子:
1、只輸出 level 的一個字母,如T,D,W,I,E,可以使用
"%.-1level"
2、將信用卡號碼替換成xxxx,需要注意,如果option中包含特殊意義的符號,需要使用單引號或雙引號 括住
<pattern>%5level - replace(%msg){‘\d{14,16}’,'xxxx'}</pattern>
小括號的特殊含義
在logback中,小括號括起來的pattern子串將被認為是一組。因此你可以針對這個組來設置樣式。
例如下面的例子:
%-30(%d{HH:mm:ss:SSS} [%thread]) %-5level %logger{32} - %msg%n
輸出結果格式如下:

顏色設置
logback 1.0.5版本,PatternLayout開始支持
%black
黑色
|
%red
紅色
|
%green
綠色
|
%yellow
黃色
|
%blue
藍色
|
%magenta
洋紅色
|
%cyan
藍綠色
|
%white
白色
|
%gray
灰色
|
|||
%boldRed
鮮紅色
|
%boldGreen
鮮綠
|
%boldYellow
鮮黃
|
%boldBlue
鮮藍
|
%boldMagenta
鮮洋紅
|
%boldCyan
鮮藍綠色
|
%boldWhite
鮮白色
|
%highlight
高亮
|
高亮指的是:level級別:error鮮紅,warn紅色,info藍色,其他黑色
下面看個例子:
<configuration debug="true"
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"
<!-- On Windows machines setting withJansi to true enables ANSI
color code interpretation by the Jansi library. This requires
org.fusesource.jansi:jansi:1.8 on the class path. Note that
Unix-based operating systems such as Linux and Mac OS X
support ANSI color codes by default. -->
<withJansi>true</withJansi>
<encoder>
<pattern>[%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG"
<appender-ref ref="STDOUT" />
</root>
</configuration>
輸出格式如下:

鑒別器
上面提到過,如果需要動態的conversion specifier行為可以在option中指定evaluator,這是一個EventEvaluator對象。
例如,我們只希望某些需要caller data數據的日志才產生caller data信息,這樣就不會嚴重影響性能。
鑒別器的詳細說明會在filter章節中(下一篇博文)說明,也可參照官方文檔
dedicated section of the chapter on filters
需要注意,默認的evaluator引用Janino library的 JaninoEventEvaluator,以下用maven引入依賴包
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>2.7.8</version>
</dependency>
下面我們來看個鑒別期的例子
<configuration>
<evaluator name="DISP_CALLER_EVAL"
<expression>logger.contains("chapters.layouts") && \
message.contains("who calls thee")</expression>
</evaluator>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"
<encoder>
<pattern>
%-4relative [%thread] %-5level - %msg%n%caller{2, DISP_CALLER_EVAL}
</pattern>
</encoder>
</appender>
<root level="DEBUG"
<appender-ref ref="STDOUT" />
</root>
</configuration>
package chapters.layouts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;
public class CallerEvaluatorExample {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(CallerEvaluatorExample.class);
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
try {
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
configurator.doConfigure(args[0]);
} catch (JoranException je) {
// StatusPrinter will handle this
}
StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
for (int i = 0; i < 5; i++) {
if (i == 3) {
logger.debug("who calls thee?");
} else {
logger.debug("I know me " + i);
}
}
}
}
由以上logback配置和程序,將會產生如下輸出
0 [main] DEBUG - I know me 0
0 [main] DEBUG - I know me 1
0 [main] DEBUG - I know me 2
0 [main] DEBUG - who calls thee?
Caller+0 at chapters.layouts.CallerEvaluatorExample.main(CallerEvaluatorExample.java:28)
0 [main] DEBUG - I know me 1
0 [main] DEBUG - I know me 2
0 [main] DEBUG - who calls thee?
Caller+0 at chapters.layouts.CallerEvaluatorExample.main(CallerEvaluatorExample.java:28)
0 [main] DEBUG - I know me 4
特別注意,上面也提到過,caller conversion word 是當evaluator 返回真有效,而ex,eXe,rEx是當evaluator返回假時有效。
例如以下配置,當異常不為空,且異常時TestException的實例,不輸出異常信息。
<configuration>
<evaluator name="DISPLAY_EX_EVAL"
<expression>throwable != null && throwable instanceof \
chapters.layouts.TestException</expression>
</evaluator>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"
<encoder>
<pattern>%msg%n%ex{full, DISPLAY_EX_EVAL}</pattern>
</encoder>
</appender>
<root level="debug"
<appender-ref ref="STDOUT" />
</root>
</configuration>
我們也可以定義使用自己的conversion word
定義使用自己的conversion word有兩個步驟:
1:繼承
ClassicConverter
,ClassicConverter 類負責獲取ILooginEvent對象的信息,並且生成String。
public class MySampleConverter extends ClassicConverter {
long start = System.nanoTime();
@Override
public String convert(ILoggingEvent event) {
long nowInNanos = System.nanoTime();
return Long.toString(nowInNanos-start);
}
}
2:聲明我們的converter
<configuration>
<conversionRule conversionWord="nanos"
converterClass="chapters.layouts.MySampleConverter" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"
<encoder>
<pattern>%-6nanos [%thread] - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG"
<appender-ref ref="STDOUT" />
</root>
</configuration>
該配置輸出的日志格式如下:
4868695 [main] DEBUG - Everything's going well
5758748 [main] ERROR - maybe not quite...
5758748 [main] ERROR - maybe not quite...
HTMLLayout
HTMLLayout 會將日志信息以html table 的形式輸出。我們先看下他默認的css樣式:


需要注意的是:HTMLLayout的pattern中,conversion specifier不能用空格,或其他字符隔開。因為每一個specifier都會被分成一列。加入不必要的字符,會導致空白列,浪費屏幕空間。
<configuration debug="true"
<appender name="FILE" class="ch.qos.logback.core.FileAppender"
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"
<layout class="ch.qos.logback.classic.html.HTMLLayout"
<pattern>%relative%thread%mdc%level%logger%msg</pattern>
</layout>
</encoder>
<file>test.html</file>
</appender>
<root level="DEBUG"
<appender-ref ref="FILE" />
</root>
</configuration>
特別注意,HTMLLayout實例自帶一個IThrowableRenderer對象,該渲染器對象,可以讓異常的stack trace的信息以一種易讀的方式展現,如上面的例子,所以在HTMLLayout 的 pattern中一般都不用使用異常的conversion word。如果你一定要使用%ex來講異常信息顯示在某一列上,這會導致大多數的日志可能這一列為空,並且信息也不容易閱讀。所以我們並不推薦。不過如果你心意已決,那就去吧比卡丘。
如果要修改樣式呢,可以通過以下方式:引入樣式文件。
<layout class="ch.qos.logback.classic.html.HTMLLayout"
<pattern>%relative...%msg</pattern>
<cssBuilder class="ch.qos.logback.classic.html.UrlCssBuilder"
<!-- url where the css file is located -->
<url>http://...</url>
</cssBuilder>
</layout>
Log4j XMLLayout
logback-classic 中個XMLLayout 與 log4j 1.2.15版本中XMLLayout相同,接受兩個boolean參數。
locationInfo 代表是否包含caller data
properties 代表是否包含MDC信息,這兩個參數默認為false。
例子如下:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender"
<file>test.xml</file>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"
<layout class="ch.qos.logback.classic.log4j.XMLLayout"
<locationInfo>true</locationInfo>
</layout>
</encoder>
</appender>
<root level="DEBUG"
<appender-ref ref="FILE" />
</root>
</configuration>
Logback access
大多數logback-access 中的layout 其實是logback-access 中的副本,提供基本相同的功能。
PatternLayout在 logback-access中的配置與classic中的基本相同,不過它提供更多適合HTTP servlet request 和 HTTP servlet response的conversion specifiers。
下面列出了access模塊中,PatternLayout可用的conversion specifiers。
Conversion Word
|
Effect |
a / remoteIP
|
遠程主機IP地址 |
A / localIP | 本content |
b / B / bytesSent | response content的長度 |
h / clientHost | 遠程主機名 |
H / protocol | request請求的協議 |
l | 遠程log name。在Logback access模塊中,這個converter常返回 “-“。 |
reqParameter{paramName} |
ßå獲取指定request 中的parameter,例如:%reqParameter{input_data}
|
i{header} / header{header} |
獲取指定request中的header,例如:
%header{Referer}
|
m / requestMethod | Request 請求的方法 |
r / requestURL | URL requested. |
s / statusCode | Status code of the request. |
D / elapsedTime | 處理這個request的時間,時間單位:毫秒 |
T / elapsedSeconds | 處理這個request的時間,時間單位:秒 |
t / date |
日志的時間,例如:
%t{HH:mm:ss,SSS}
%t{dd MMM yyyy ;HH:mm:ss,SSS}
%t{dd/MMM/yyyy:HH:mm:ss Z}
|
u / user | Remote user. |
q / queryString | Request query string, prepended with a '?'. |
U / requestURI | Requested URI. |
S / sessionID | Session ID. |
v / server | Server name. |
I / threadName |
Name of the thread which processed the request.
|
localPort | Local port. |
reqAttribute{attributeName} |
Attribute of the request.
例如:%reqAttribute{SOME_ATTRIBUTE}
|
reqCookie{cookie} |
Request cookie.
%cookie{COOKIE_NAME}
|
responseHeader{header} |
Header of the response.
%header{Referer}
|
requestContent | This conversion word displays the content of the request, that is the request'sInputStream . It is used in conjunction with a TeeFilter , a javax.servlet.Filter that replaces the original HttpServletRequest by a TeeHttpServletRequest . The latter object allows access to the request's InputStream multiple times without any loss of data. |
fullRequest | This converter outputs the data associated with the request, including all headers and request contents. |
responseContent | This conversion word displays the content of the response, that is the response'sInputStream . It is used in conjunction with a TeeFilter , a javax.servlet.Filter that replaces the original HttpServletResponse by a TeeHttpServletResponse . The latter object allows access to the request's InputStream multiple times without any loss of data. |
fullResponse | This conversion word takes all the available data associated with the response, including all headers of the response and response contents. |
除了以上這些,還有一些內置格式的別名:
keyword | equivalent conversion pattern |
---|---|
common 或者 CLF | %h %l %u [%t] "%r" %s %b |
combined | %h %l %u [%t] "%r" %s %b "%i{Referer}" "%i{User-Agent}" |
HTMLLayout
logbook access 中的 HTMLLayout 默認包含以下數據
- Remote IP
- Date
- Request URL
- Status code
- Content Length
下面是它的一個示例圖

