来源:logback.qos.ch/manual/layo... 作者:Ceki Gülcü、Sébastien Pennec、Carl Harris 版权所有 © 2000-2022 QOS.ch Sarl
转换词选项
转换说明符后面可以跟随选项。它们总是在大括号之间声明。我们已经看到了一些选项提供的可能性,例如与 MDC 转换说明符结合使用,如:%mdc{someKey}
。
一个转换说明符可能有多个选项。例如,一个使用评估器的转换说明符(即将介绍)可以将评估器名称添加到选项列表中,如下所示:
perl
<pattern>%-4relative [%thread] %-5level - %msg%n \
%caller{2, DISP_CALLER_EVAL, OTHER_EVAL_NAME, THIRD_EVAL_NAME}</pattern>
如果选项包含特殊字符,如大括号、空格或逗号,可以用单引号或双引号将其括起来。例如,考虑下一个模式。
perl
<pattern>%-5level - %replace(%msg){'\d{14,16}', 'XXXX'}%n</pattern>
我们将选项 \d{16}
和 XXXX
传递给 replace
转换词。它将用 XXXX
替换消息中包含的任何 14、15 或 16 位数字序列,从而有效地混淆信用卡号码。注意,\d
是常规表达式中表示单个数字的简写。"{14,16\}"
被解释为 "{14, 16}"
,即重复前面的项至少 14 次但最多 16 次。
使用括号进行分组
在 logback 中,模式字符串中的括号被视为分组标记。因此,可以对子模式进行分组并对该子模式应用格式化指令。
例如,模式
perl
%-30(%d{HH:mm:ss.SSS} [%thread]) %-5level %logger{32} - %msg%n
将对由子模式 "%d{HH:mm:ss.SSS} [%thread]"
生成的输出进行分组,如果少于 30 个字符则右对齐。
假设没有分组时的输出是
accesslog
13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Classload hashcode is 13995234
13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Initializing for ServletContext
13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Trying platform Mbean server
13:09:30 [pool-1-thread-1] INFO ch.qos.logback.demo.LoggingTask - Howdydy-diddly-ho - 0
13:09:38 [btpool0-7] INFO c.q.l.demo.lottery.LotteryAction - Number: 50 was tried.
13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Beginning to factor.
13:09:40 [btpool0-7] DEBUG c.q.l.d.prime.NumberCruncherImpl - Trying 2 as a factor.
13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Found factor 2
使用 "%-30()"
分组后,输出将变为
accesslog
13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Classload hashcode is 13995234
13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Initializing for ServletContext
13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Trying platform Mbean server
13:09:30 [pool-1-thread-1] INFO ch.qos.logback.demo.LoggingTask - Howdydy-diddly-ho - 0
13:09:38 [btpool0-7] INFO c.q.l.demo.lottery.LotteryAction - Number: 50 was tried.
13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Beginning to factor.
13:09:40 [btpool0-7] DEBUG c.q.l.d.prime.NumberCruncherImpl - Trying 2 as a factor.
13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Found factor 2
后一种形式更容易阅读。
如果需要将括号字符视为字面量,则需要在每个括号之前加上反斜杠进行转义,如 \(%d{HH:mm:ss.SSS} [%thread]\)
。
【颜色设置】
按照上面所解释的方式,使用括号进行分组可以对子模式进行着色。从版本 1.0.5 开始,PatternLayout
可以识别 "%black"
、"%red"
、"%green"
、"%yellow"
、"%blue"
、"%magenta"
、"%cyan"
、"%white"
、"%gray"
、"%boldRed"
、"%boldGreen"
、"%boldYellow"
、"%boldBlue"
、"%boldMagenta"
、"%boldCyan"
、"%boldWhite"
和 "%highlight"
作为转换词。这些转换词旨在包含子模式。任何被染色词括起来的子模式都将以指定的颜色输出。
下面是一个演示如何进行着色的配置文件例子。请注意,"%logger{15}"
被 %cyan
转换说明符所包含。这将输出缩写为 15 个字符的记录器名称,并以青色显示。%highlight
转换说明符会以粗体红色打印其子模式,其中 ERROR 级别的事件以红色、WARN 级别的事件以 BLUE 色、INFO 级别的事件以默认颜色打印。
演示:高亮显示级别(logback-examples/src/main/resources/chapters/layouts/highlighted.xml)
传统格式
xml
<configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<withJansi>true</withJansi>
<encoder>
<pattern>[%thread] %highlight(%-5level) %cyan(%logger{15}) -%kvp -%msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
规范格式 (1.3)
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>
<configuration debug="true">
<import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
<import class="ch.qos.logback.core.ConsoleAppender"/>
<appender name="STDOUT" class="ConsoleAppender">
<withJansi>true</withJansi>
<encoder class="PatternLayoutEncoder">
<pattern>[%thread] %highlight(%-5level) %cyan(%logger{15}) -%kvp -%msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
将 withJansi
设置为 true 可以启用 Jansi 库的 ANSI 颜色代码解释,该库会在底层终端不兼容时透明地过滤掉 ANSI 转义序列。这是跨平台部署的最安全选择,但在类路径中需要具有 org.fusesource.jansi:jansi:1.17 或更高版本。请注意,基于 Unix 的操作系统(如 Linux 和 Mac OS X)本地支持 ANSI 颜色代码,通常不需要启用 Jansi 库,但这样做是无害的。然而,在 Windows 上,建议启用 Jansi 以便在 DOS 命令提示符上从颜色代码解释中受益,否则会发送 ANSI 转义序列,它们无法解释。
以下是对应的输出:
accesslog
[main] WARN c.l.TrivialMain - a warning message 0
[main] DEBUG c.l.TrivialMain - hello world number1
[main] DEBUG c.l.TrivialMain - hello world number2
[main] INFO c.l.TrivialMain - hello world number3
[main] DEBUG c.l.TrivialMain - hello world number4
[main] WARN c.l.TrivialMain - a warning message 5
[main] ERROR c.l.TrivialMain - Finish off with fireworks
创建一个彩色转换词只需要很少的代码。章节 创建自定义转换说明符 讨论了在配置文件中注册转换词所需的步骤。
【评估器】
如上所述,当需要一个转换说明符根据一个或多个 EventEvaluator
对象动态地进行处理时,选项列表非常有用。EventEvaluator
对象负责确定给定的日志事件是否符合评估器的条件。
让我们回顾一个涉及 EventEvaluator
的例子。下一个配置文件将日志事件输出到控制台,显示日期、线程、级别、消息和调用数据。鉴于提取记录器的调用者数据会比较昂贵,因此只有在日志请求来源于特定记录器并且消息包含某个字符串时,我们才会这样做。因此,我们确保仅特定的日志请求将生成并显示其调用者信息。在其他情况下,其中调用方数据是多余的,我们将不会惩罚应用程序性能。
评估器,尤其是 评估表达式 ,在 过滤器章节 中专门介绍,如果您想以任何有意义的方式使用评估器,则必须阅读该章节。还要注意,以下示例隐式基于 JaninoEventEvaluator
,它需要 Janino 库。请参阅设置文档中的 相应部分。
演示:EventEvaluators 的使用示例(logback-examples/src/main/resources/chapters/layouts/callerEvaluatorConfig.xml)
传统格式
xml
<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 -%kvp -%msg%n%caller{2, DISP_CALLER_EVAL}
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
规范格式 (1.3)
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>
<configuration>
<import class="ch.qos.logback.core.ConsoleAppender"/>
<import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
<evaluator name="DISP_CALLER_EVAL">
<expression>logger.contains("chapters.layouts") && \
message.contains("who calls thee")</expression>
</evaluator>
<appender name="STDOUT" class="ConsoleAppender">
<encoder class="PatternLayoutEncoder">
<pattern>%-4relative [%thread] %-5level -%kvp -%msg%n%caller{2, DISP_CALLER_EVAL}</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
上述评估表达式匹配来自名称包含字符串 "chapters.layouts"
的记录器发出的事件,并且消息包含字符串 "who calls thee"
。由于 XML 编码规则,&
字符不能直接写入,需要转义为 &
。
以下类利用了上述配置文件中提到的一些特性。
示例:EventEvaluators
的示例用法 (logback-examples/src/main/java/chapters/layouts/CallerEvaluatorExample.java)
java
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);
}
}
}
}
上述应用程序没有特别花哨的地方。发出五个日志记录请求,第三个请求发出消息 "who calls thee?"
。
命令
bash
java chapters.layouts.CallerEvaluatorExample src/main/java/chapters/layouts/callerEvaluatorConfig.xml
将产生以下输出:
accesslog
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 4
当发出日志记录请求时,相应的日志事件被评估。只有第三个日志事件符合评估标准,导致其调用者数据被显示。对于其他日志事件,评估标准不匹配,不会打印调用者数据。
可以更改表达式以对应实际情况。例如,可以结合记录器名称和请求级别。因此,从应用程序的敏感部分(例如财务交易模块)发出的级别为 WARN
及以上的日志记录请求将显示其调用者数据。
重要提示: 使用 caller
转换词,当 表达式评估为 true
时输出调用者数据。
让我们考虑另一种情况。当异常包含在日志记录请求中时,它们的堆栈跟踪也会输出。但是,有时可能希望对某些特定异常抑制堆栈跟踪。
下面显示的 Java 代码创建了三个具有异常的日志请求。第二个异常与其他异常不同:它包含字符串" do not display this",并且其类型为 chapters.layouts.TestException
。现在,让我们阻止第二个异常被打印。
示例:EventEvaluators
的示例用法 (logback-examples/src/main/java/chapters/layouts/ExceptionEvaluatorExample.java)
java
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 ExceptionEvaluatorExample {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(ExceptionEvaluatorExample.class);
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
try {
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.reset();
configurator.doConfigure(args[0]);
} catch (JoranException je) {
// StatusPrinter will handle this
}
StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
for (int i = 0; i < 3; i++) {
if (i == 1) {
logger.debug("logging statement " + i, new TestException(
"do not display this"));
} else {
logger.debug("logging statement " + i, new Exception("display"));
}
}
}
}
在下一个配置文件中,评估表达式匹配包含 chapters.layouts.TextException
类型的可抛出事件,这恰好是我们希望抑制的异常类型。
示例:EventEvaluators
的用法示例(logback-examples/src/main/resources/chapters/layouts/exceptionEvaluatorConfig.xml)
传统格式
xml
<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>
规范格式 (1.3)
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>
<configuration>
<import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
<import class="ch.qos.logback.core.ConsoleAppender"/>
<evaluator name="DISPLAY_EX_EVAL">
<expression>throwable != null && throwable instanceof \
chapters.layouts.TestException</expression>
</evaluator>
<appender name="STDOUT" class="ConsoleAppender">
<encoder class="PatternLayoutEncoder">
<pattern>%msg%n%ex{full, DISPLAY_EX_EVAL}</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
通过这个配置,每当 chapters.layouts.TestException
的实例被包含在日志请求中时,堆栈跟踪将被抑制。
运行以下命令
bash
java chapters.layouts.ExceptionEvaluatorExample src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml
会产生以下结果
accesslog
logging statement 0
java.lang.Exception: display
at chapters.layouts.ExceptionEvaluatorExample.main(ExceptionEvaluatorExample.java:43) [logback-examples-0.9.19.jar:na]
logging statement 1
logging statement 2
java.lang.Exception: display
at chapters.layouts.ExceptionEvaluatorExample.main(ExceptionEvaluatorExample.java:43) [logback-examples-0.9.19.jar:na]
注意第二个日志语句没有堆栈跟踪。我们成功地抑制了 TextException
的堆栈跟踪。每个堆栈跟踪行末尾的方括号中的文本是之前讨论过的 打包信息。
==注意== 使用 %ex
转换说明符时,当 表达式评估为 false
时显示堆栈跟踪。
创建自定义转换说明符
到目前为止,我们已经介绍了 PatternLayout
中内置的转换词。但是,您也可以添加自己制作的转换词。
构建自定义转换说明符包括两个步骤。
第一步
首先,您必须扩展 ClassicConverter
类。ClassicConverter
对象负责从 ILoggingEvent
实例中提取信息并生成字符串。例如,LoggerConverter
,即 %logger
转换词的基础转换器,从 ILoggingEvent
中提取 Logger 的名称并将其作为字符串返回。它可能在此过程中缩写 Logger 名称。
下面是一个返回自创建以来经过的纳秒数的自定义转换器的示例:
示例:自定义转换器示例(src/main/java/chapters/layouts/MySampleConverter.java)
java
public class MySampleConverter extends ClassicConverter {
long start = System.nanoTime();
@Override
public String convert(ILoggingEvent event) {
long nowInNanos = System.nanoTime();
return Long.toString(nowInNanos-start);
}
}
这个实现非常简单。MySampleConverter
类扩展了 ClassicConverter
,并实现了 convert
方法,该方法返回自创建以来经过的纳秒数的字符串。
第二步
在第二步中,我们必须让 logback 知道新的 Converter
。为此,我们需要在配置文件中声明新的转换词,如下所示:
示例:示例转换器示例(src/main/java/chapters/layouts/mySampleConverterConfig.xml)
传统格式
xml
<configuration>
<conversionRule conversionWord="nanos"
converterClass="chapters.layouts.MySampleConverter" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-6nanos [%thread] -%kvp -%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
规范格式 (1.3)
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>
<configuration>
<import class="ch.qos.logback.core.ConsoleAppender"/>
<import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
<appender name="STDOUT" class="ConsoleAppender">
<encoder class="PatternLayoutEncoder">
<pattern>%-6nanos [%thread] -%kvp -%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
一旦在配置文件中声明了新的转换词,我们就可以像其他转换词一样在 PatternLayout
模式中引用它。
以下命令:
bash
java chapters.layouts.SampleLogging src/main/java/chapters/layouts/mySampleConverterConfig.xml
应该产生类似于以下的输出:
accesslog
4868695 [main] DEBUG - Everything's going well
5758748 [main] ERROR - maybe not quite...
读者可能想看看其他 Converter
的实现,比如 MDCConverter
,以了解更复杂的行为,比如选项处理。要创建自己的着色方案,请查看 HighlightingCompositeConverter
。
HTMLLayout
HTMLLayout
(包含在 logback-classic 中)以 HTML 格式生成日志。HTMLLayout
将日志事件输出为 HTML 表格,其中表的每一行对应一个日志事件。
下面是使用默认 CSS 样式表生成的 HTMLLayout
的示例输出:
表列的内容通过转换模式指定。有关转换模式的文档,请参见 PatternLayout
。因此,您可以完全控制表的内容和格式。您可以选择和显示 PatternLayout
所知道的任何转换器的任意组合。
关于在 HTMLLayout
中使用 PatternLayout
的一个显着例外是,转换说明符不应由空格字符或更一般地由文本文字分隔。模式中找到的每个说明符都将生成一个单独的列。同样,对于模式中找到的每个文本块,将生成一个单独的列,可能会浪费宝贵的屏幕空间。
下面是一个简单但功能齐全的配置文件示例,演示了如何使用 HTMLLayout
。
示例:HTMLLayout
示例(src/main/java/chapters/layouts/htmlLayoutConfig1.xml)
传统格式
xml
<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>
规范格式 (1.3)
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>
<configuration debug="true">
<import class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"/>
<import class="ch.qos.logback.core.FileAppender"/>
<import class="ch.qos.logback.classic.html.HTMLLayout"/>
<appender name="FILE" class="FileAppender">
<encoder class="LayoutWrappingEncoder">
<layout class="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>
TrivialMain 应用程序记录了一些以异常结束的消息。以下命令:
bash
java chapters.layouts.TrivialMain src/main/java/chapters/layouts/htmlLayoutConfig1.xml
将在当前文件夹中创建名为 test.html 的文件。test.html 的内容应类似于以下内容:
堆栈跟踪
如果您使用 %em
转换词来显示堆栈跟踪,将创建一个表列来显示堆栈跟踪。在大多数情况下,该列将为空,浪费屏幕空间。此外,在单独的列上打印堆栈跟踪不会得到非常可读的结果。幸运的是,%ex
转换词并不是显示堆栈跟踪的唯一方法。
通过实现 IThrowableRenderer
接口,可以提供更好的解决方案来管理与异常相关的显示数据,并将其分配给 HTMLLayout
。默认情况下,每个 HTMLLayout
实例都分配了一个 DefaultThrowableRenderer
,它以易于阅读的方式将异常和其堆栈跟踪写在 新表行 中,如上图所示。
如果出于某种原因,您仍然希望使用 %ex
模式,则可以在配置文件中指定 NOPThrowableRenderer
,以禁用为堆栈跟踪显示单独的行。我们不知道为什么您会这样做,但如果您希望,您可以这样做。
CSS
通过级联样式表(CSS)来控制 HTMLLayout
创建的 HTML 的呈现方式。如果没有特定的指令,HTMLLayout
将默认使用内部 CSS。但是,您可以指示 HTMLLayout
使用外部 CSS 文件。为此,可以在 <layout>
元素中嵌套一个 cssBuilder
元素,如下所示:
xml
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%relative...%msg</;pattern>
<cssBuilder class="ch.qos.logback.classic.html.UrlCssBuilder">
<!-- css 文件所在的 url -->
<url>http://...</url>
</cssBuilder>
</layout>
HTMLLayout
通常与 SMTPAppender
结合使用,以便以 HTML 格式良好地格式化发送的电子邮件。
Log4j XMLLayout
XMLLayout(属于 logback-classic)生成符合 log4j.dtd 格式的输出,以与 Chainsaw 和 Vigilog 等工具进行交互,这些工具可以处理由 log4j 的 XMLLayout 生成的文件。
与 log4j 版本 1.2.15 中的原始 XMLLayout 一样,logback-classic 中的 XMLLayout 具有两个布尔属性:locationInfo
和 properties
。将 locationInfo
设置为 true
可在每个事件中包含位置信息(调用者数据)。将 properties
设置为 true
可包含 MDC 信息。这两个选项默认情况下都设置为 false
。
以下是一个示例配置:
示例:Log4jXMLLayout
示例(src/main/java/chapters/layouts/log4jXMLLayout.xml)
传统格式
xml
<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>
规范格式 (1.3)
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>
<configuration>
<import class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"/>
<import class="ch.qos.logback.classic.log4j.XMLLayout"/>
<import class="ch.qos.logback.core.FileAppender"/>
<appender name="FILE" class="FileAppender">
<file>test.xml</file>
<encoder class="LayoutWrappingEncoder">
<layout class="XMLLayout">
<locationInfo>true</locationInfo>
</layout>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE"/>
</root>
</configuration>
Logback access
logback-access 对日志的布局大多是基于 logback-classic 进行调整的。logback-classic 和 logback-access 模块满足不同的需求,但总体上提供了类似的功能。
编写自定义布局
编写 logback access 的自定义 Layout
与 logback-classic 中的兄弟类 Layout
几乎完全相同。
PatternLayout
在 logback-access 中,可以通过配置 PatternLayout
来实现与经典模式相似的功能。然而,它还包含了适用于记录仅在 HTTP Servlet 请求和 HTTP Servlet 响应中可用的特定信息的额外转换说明符。
下面是 logback-access 中 PatternLayout
的转换说明符列表。
转换说明符 | 效果 |
---|---|
a / remoteIP | 远程 IP 地址。 |
A / localIP | 本地 IP 地址。 |
b / B / bytesSent | 响应的内容长度。 |
h / clientHost | 远程主机。 |
H / protocol | 请求协议。 |
l | 远程日志名称。在 logback-access 中,此转换器始终返回值为 "-" 。 |
reqParameter{paramName} | 响应的参数。 此转换词获取花括号中的第一个选项,并在请求中查找相应的参数。 %reqParameter{input_data} 显示相应的参数。 |
i{header } / header{header} | 请求头。 此转换词获取花括号中的第一个选项,并在请求中查找相应的头部。 %header{Referer} 显示请求的引用页。 如果未指定选项,则显示所有可用的头部。 |
m / requestMethod | 请求方法。 |
r / requestURL | 请求的 URL。 |
s / statusCode | 请求的状态码。 |
D / elapsedTime | 为服务请求所花费的时间,以毫秒为单位。 |
T / elapsedSeconds | 为服务请求所花费的时间,以秒为单位。 |
t / date | 输出日志事件的日期。日期转换说明符后面可以跟随一个括号,其中包含 java.text.SimpleDateFormat 使用的日期和时间模式字符串。ISO8601 也是一个有效的值。 例如,%t{HH:mm:ss,SSS} 或 %t{ddMMMyyyy;HH:mm:ss,SSS} 。如果没有指定日期格式说明符,则假定为通用日志格式的日期格式,即 %t{dd/MMM/yyyy:HH:mm:ssZ} |
u / user | 远程用户。 |
q / queryString | 请求查询字符串,以'?'开头。 |
U / requestURI | 请求的 URI。 |
S / sessionID | 会话 ID。 |
v / server | 服务器名称。 |
I / threadName | 处理请求的线程名称。 |
localPort | 本地端口。 |
reqAttribute{attributeName} | 请求属性。 此转换词获取花括号中的第一个选项,并在请求中查找相应的属性。 %reqAttribute{SOME_ATTRIBUTE} 显示相应的属性。 |
reqCookie{cookie} | 请求 Cookie。 此转换词获取花括号中的第一个选项,并在请求中查找相应的 Cookie。 %cookie{COOKIE_NAME} 显示相应的 Cookie。 |
responseHeader{header} | 响应头。 此转换词获取花括号中的第一个选项,并在响应中查找相应的头部。 %header{Referer} 显示响应的引用页。 |
requestContent | 此转换词显示请求的内容,即请求的 InputStream 。它与 TeeFilter 一起使用,TeeFilter 是一个 javax.servlet.Filter ,它将原始的 HttpServletRequest 替换为 TeeHttpServletRequest 。后者允许多次访问请求的 InputStream 而不丢失任何数据。 |
fullRequest | 此转换器输出与请求相关的所有数据,包括所有头部和请求内容。 |
responseContent | 此转换词显示响应的内容,即响应的 InputStream 。它与 TeeFilter 一起使用,TeeFilter 是一个 javax.servlet.Filter ,它将原始的 HttpServletResponse 替换为 TeeHttpServletResponse 。后者允许多次访问请求的 InputStream 而不丢失任何数据。 |
fullResponse | 此转换词获取与响应相关的所有可用数据,包括响应的所有头部和响应内容。 |
logback-access 的 PatternLayout
还识别三个关键字,它们像快捷方式一样起作用。
关键字 | 等效的转换模式 |
---|---|
common 或 CLF |
*%h %l %u [%t] "%r" %s %b* |
combined |
%h %l %u [%t] "%r" %s %b "%i{Referer}" "%i{User-Agent}" |
common
关键字对应的模式是 '%h %l %u [%t] "%r" %s %b'
,显示客户端主机、远程日志名称、用户、日期、请求的 URL、状态码和响应的内容长度。
combined
关键字是 '%h %l %u [%t] "%r" %s %b "%i{Referer}" "%i{User-Agent}"'
的快捷方式。该模式与 common
模式类似,但还显示了两个请求头,即引用页和用户代理。
HTMLLayout
logback-access 中的 HTMLLayout
类与 logback-classic 中的 HTMLLayout
类相似。
默认情况下,它会创建一个包含以下数据的表格:
- 远程 IP
- 日期
- 请求的 URL
- 状态码
- 内容长度
以下是 logback-access 中的 HTMLLayout
生成的示例输出:
有什么比一个真实世界的例子更好呢?我们自己的 log4j 日志配置文件中使用了 logback-access 来演示带有 HTMLLayout
的 RollingFileAppender
的实时输出。
每当用户在我们的 translator 网络应用程序上发起新的请求时,将向访问日志添加新条目,您可以通过 点击此链接 查看。
版权声明:本文为博主「佳佳」的原创文章,遵循 CC 4.0 BY-NC-SA 版权协议,转载请附上原文出处链接及本声明。