Log4j 的 layout 配置

来自姬鸿昌的知识库
跳到导航 跳到搜索

https://www.bilibili.com/video/BV1iJ411H74S?p=14

格式化器类型 作用
HTMLLayout 格式化日志输出为 HTML 表格形式
XMLLayout 格式化日志输出为 XML 形式
SimpleLayout 简单的日志输出格式化,打印的日志格式为(info - message)
PatternLayout 最强大的格式化器,可以根据自定义格式输出日志,如果没有指定转换格式,

就使用默认的转换格式

测试使用 HTMLLayout

log4j.properties

# 指定 RootLogger 顶级父元素默认配置信息
# 指定日志级别=trace,使用的 appender 为 console
log4j.rootLogger = trace,console
# 指定控制台日志输出的 appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式 layout
log4j.appender.console.layout = org.apache.log4j.HTMLLayout
log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Log4J Log Messages</title>
<style type="text/css">
<!--
body, table {font-family: arial,sans-serif; font-size: x-small;}
th {background: #336699; color: #FFFFFF; text-align: left;}
-->
</style>
</head>
<body bgcolor="#FFFFFF" topmargin="6" leftmargin="6">
<hr size="1" noshade>
Log session start time Fri Feb 24 16:06:11 CST 2023<br>
<br>
<table cellspacing="0" cellpadding="4" border="1" bordercolor="#224466" width="100%">
<tr>
<th>Time</th>
<th>Thread</th>
<th>Level</th>
<th>Category</th>
<th>Message</th>
</tr>

<tr>
<td>0</td>
<td title="main thread">main</td>
<td title="Level">INFO</td>
<td title="io.github.jihch.Log4jTest category">io.github.jihch.Log4jTest</td>
<td title="Message">hello log4j</td>
</tr>

<tr>
<td>1</td>
<td title="main thread">main</td>
<td title="Level"><font color="#993300"><strong>FATAL</strong></font></td>
<td title="io.github.jihch.Log4jTest category">io.github.jihch.Log4jTest</td>
<td title="Message">fatal</td>
</tr>

<tr>
<td>1</td>
<td title="main thread">main</td>
<td title="Level"><font color="#993300"><strong>ERROR</strong></font></td>
<td title="io.github.jihch.Log4jTest category">io.github.jihch.Log4jTest</td>
<td title="Message">error</td>
</tr>

<tr>
<td>1</td>
<td title="main thread">main</td>
<td title="Level"><font color="#993300"><strong>WARN</strong></font></td>
<td title="io.github.jihch.Log4jTest category">io.github.jihch.Log4jTest</td>
<td title="Message">warn</td>
</tr>

<tr>
<td>1</td>
<td title="main thread">main</td>
<td title="Level">INFO</td>
<td title="io.github.jihch.Log4jTest category">io.github.jihch.Log4jTest</td>
<td title="Message">info</td>
</tr>

<tr>
<td>1</td>
<td title="main thread">main</td>
<td title="Level"><font color="#339933">DEBUG</font></td>
<td title="io.github.jihch.Log4jTest category">io.github.jihch.Log4jTest</td>
<td title="Message">debug</td>
</tr>

<tr>
<td>1</td>
<td title="main thread">main</td>
<td title="Level"><font color="#339933">DEBUG</font></td>
<td title="io.github.jihch.Log4jTest category">io.github.jihch.Log4jTest</td>
<td title="Message">trace</td>
</tr>

Process finished with exit code 0




测试使用 XMLLayout

log4j.properties

# 指定 RootLogger 顶级父元素默认配置信息
# 指定日志级别=trace,使用的 appender 为 console
log4j.rootLogger = trace,console
# 指定控制台日志输出的 appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式 layout
log4j.appender.console.layout = org.apache.log4j.xml.XMLLayout
log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
<log4j:event logger="io.github.jihch.Log4jTest" timestamp="1677226131199" level="INFO" thread="main">
<log4j:message><![CDATA[hello log4j]]></log4j:message>
</log4j:event>

<log4j:event logger="io.github.jihch.Log4jTest" timestamp="1677226131200" level="FATAL" thread="main">
<log4j:message><![CDATA[fatal]]></log4j:message>
</log4j:event>

<log4j:event logger="io.github.jihch.Log4jTest" timestamp="1677226131200" level="ERROR" thread="main">
<log4j:message><![CDATA[error]]></log4j:message>
</log4j:event>

<log4j:event logger="io.github.jihch.Log4jTest" timestamp="1677226131200" level="WARN" thread="main">
<log4j:message><![CDATA[warn]]></log4j:message>
</log4j:event>

<log4j:event logger="io.github.jihch.Log4jTest" timestamp="1677226131200" level="INFO" thread="main">
<log4j:message><![CDATA[info]]></log4j:message>
</log4j:event>

<log4j:event logger="io.github.jihch.Log4jTest" timestamp="1677226131200" level="DEBUG" thread="main">
<log4j:message><![CDATA[debug]]></log4j:message>
</log4j:event>

<log4j:event logger="io.github.jihch.Log4jTest" timestamp="1677226131200" level="DEBUG" thread="main">
<log4j:message><![CDATA[trace]]></log4j:message>
</log4j:event>


Process finished with exit code 0


测试使用 PatternLayout

log4j.properties

# 指定 RootLogger 顶级父元素默认配置信息
# 指定日志级别=trace,使用的 appender 为 console
log4j.rootLogger = trace,console
# 指定控制台日志输出的 appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式 layout
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
hello log4j
fatal
error
warn
info
debug
trace

Process finished with exit code 0

log4j.properties

# 指定 RootLogger 顶级父元素默认配置信息
# 指定日志级别=trace,使用的 appender 为 console
log4j.rootLogger = trace,console
# 指定控制台日志输出的 appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式 layout
log4j.appender.console.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
log4j.appender.console.layout.ConversionPattern = %r [%t] %p %c %x - %m%n
log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: Setting property [conversionPattern] to [%r [%t] %p %c %x - %m%n].
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
0 [main] INFO io.github.jihch.Log4jTest  - hello log4j
0 [main] FATAL io.github.jihch.Log4jTest  - fatal
0 [main] ERROR io.github.jihch.Log4jTest  - error
0 [main] WARN io.github.jihch.Log4jTest  - warn
0 [main] INFO io.github.jihch.Log4jTest  - info
0 [main] DEBUG io.github.jihch.Log4jTest  - debug
0 [main] DEBUG io.github.jihch.Log4jTest  - trace



log4j.properties

# 指定 RootLogger 顶级父元素默认配置信息
# 指定日志级别=trace,使用的 appender 为 console
log4j.rootLogger = trace,console
# 指定控制台日志输出的 appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式 layout
log4j.appender.console.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
log4j.appender.console.layout.ConversionPattern = [%p]%r %c %t %F %L %d{yyyy年MM月dd日 HH:mm:ss.SSS} %m%n
log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: Setting property [conversionPattern] to [[%p]%r %c %t %F %L %d{yyyy?MM?dd? HH:mm:ss.SSS} %m%n].
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
[INFO]0 io.github.jihch.Log4jTest main Log4jTest.java 24 2023?02?24? 16:45:17.781 hello log4j
[FATAL]2 io.github.jihch.Log4jTest main Log4jTest.java 27 2023?02?24? 16:45:17.783 fatal
[ERROR]2 io.github.jihch.Log4jTest main Log4jTest.java 29 2023?02?24? 16:45:17.783 error
[WARN]2 io.github.jihch.Log4jTest main Log4jTest.java 30 2023?02?24? 16:45:17.783 warn
[INFO]2 io.github.jihch.Log4jTest main Log4jTest.java 31 2023?02?24? 16:45:17.783 info
[DEBUG]3 io.github.jihch.Log4jTest main Log4jTest.java 32 2023?02?24? 16:45:17.784 debug
[DEBUG]3 io.github.jihch.Log4jTest main Log4jTest.java 34 2023?02?24? 16:45:17.784 trace

Process finished with exit code 0

控制台字符集编码的原因,年、月、日汉字出现乱码,调整格式为

log4j.appender.console.layout.ConversionPattern = [%p]%r %c %t %F %L %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

就没有乱码了

log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: Setting property [conversionPattern] to [[%p]%r %c %t %F %L %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n].
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
[INFO]0 io.github.jihch.Log4jTest main Log4jTest.java 24 2023-02-24 16:53:56.215 hello log4j
[FATAL]2 io.github.jihch.Log4jTest main Log4jTest.java 27 2023-02-24 16:53:56.217 fatal
[ERROR]2 io.github.jihch.Log4jTest main Log4jTest.java 29 2023-02-24 16:53:56.217 error
[WARN]2 io.github.jihch.Log4jTest main Log4jTest.java 30 2023-02-24 16:53:56.217 warn
[INFO]2 io.github.jihch.Log4jTest main Log4jTest.java 31 2023-02-24 16:53:56.217 info
[DEBUG]3 io.github.jihch.Log4jTest main Log4jTest.java 32 2023-02-24 16:53:56.218 debug
[DEBUG]3 io.github.jihch.Log4jTest main Log4jTest.java 34 2023-02-24 16:53:56.218 trace

Process finished with exit code 0




用 “%l” 代替 “%c %t %F %L”

log4j.appender.console.layout.ConversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/E:/record/2023/2/19/log4j-demo/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: Setting property [conversionPattern] to [[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n].
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
[INFO]0 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:24) 2023-02-24 16:55:44.537 hello log4j
[FATAL]1 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:27) 2023-02-24 16:55:44.538 fatal
[ERROR]1 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:29) 2023-02-24 16:55:44.538 error
[WARN]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:30) 2023-02-24 16:55:44.539 warn
[INFO]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:31) 2023-02-24 16:55:44.539 info
[DEBUG]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:32) 2023-02-24 16:55:44.539 debug
[DEBUG]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:34) 2023-02-24 16:55:44.539 trace




日志级别占10个字符宽度,右对齐

log4j.appender.console.layout.ConversionPattern = [%10p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
[      INFO]0 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:24) 2023-02-24 17:27:10.204 hello log4j
[     FATAL]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:27) 2023-02-24 17:27:10.206 fatal
[     ERROR]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:29) 2023-02-24 17:27:10.206 error
[      WARN]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:30) 2023-02-24 17:27:10.206 warn
[      INFO]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:31) 2023-02-24 17:27:10.206 info
[     DEBUG]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:32) 2023-02-24 17:27:10.206 debug
[     DEBUG]3 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:34) 2023-02-24 17:27:10.207 trace




日志级别占10个字符宽度,左对齐

log4j.appender.console.layout.ConversionPattern = [%-10p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
[INFO      ]1 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:24) 2023-02-24 17:28:58.074 hello log4j
[FATAL     ]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:27) 2023-02-24 17:28:58.075 fatal
[ERROR     ]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:29) 2023-02-24 17:28:58.075 error
[WARN      ]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:30) 2023-02-24 17:28:58.075 warn
[INFO      ]2 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:31) 2023-02-24 17:28:58.075 info
[DEBUG     ]3 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:32) 2023-02-24 17:28:58.076 debug
[DEBUG     ]3 io.github.jihch.Log4jTest.testQuick(Log4jTest.java:34) 2023-02-24 17:28:58.076 trace







Layout 的格式

在 log4j.properties 配置文件中,我们定义了日志输出级别与输出端,在输出端中分别配置日志的输出格式。

*log4j 采用类似 C 语言的 printf 函数的打印格式格式化日志信息,具体的占位符及其含义如下:

%m 输出代码中指定的日志信息
%p 输出优先级,即 DEBUG、INFO 等
%n 换行符(Windows 平台的换行符为“\r\n”,Unix 平台为 “\n”)
%r 输出自应用启动到输出该 log 信息的毫秒数
%c 输出打印语句所属的类的全名
%t 输出产生该日志的线程全名
%d 输出服务器当前时间,默认为 ISO8601,也可以指定格式,如:%d{yyyy年MM月dd日 HH:mm:ss.SSS}
%l 输出日志事件发生的位置,包括类名、线程、及在代码中的行数。如:Test.main(Test.java:10)
%F 输出日志消息产生时所在的文件名称
%L 输出代码中的行号
%% 输出一个“%”字符

*可以在 % 与字符之间加上修饰符来控制最小宽度、最大宽度和文本的对其方式:

%5c 输出 category 名称,最小宽度是5,category<5,默认的情况下右对齐
%-5c 输出 category 名称,最小宽度是5,category<5,“-”号指定左对齐,会有空格
%.5c 输出 category 名称,最大宽度是5,category>5,就会将左边多出的字符截掉,<5不会有空格
%20.30c category 名称<20补空格,并且右对齐,>30字符,就从左边较远处的字符截掉