官方文档本节地址:http://logging.apache.org/log4j/2.x/manual/layouts.html
Layouts是什么
官方文档:“An Appender uses a Layout to format a LogEvent into a form that meets the needs of whatever will be consuming the log event.” Layout是Appender用来格式化日志事件并组织有用信息的工具。
在log4j1.X中,Layouts会将日志信息转化为字符串。但是在log4j2中,为了满足更多种类Appender的需要,改为返回字节数组。因此,我们需要额外注意Layouts的编码问题,以确保字节数组保存的是正确的内容。所有Layouts的根类是org.apache.logging.log4j.core.layout.AbstractStringLayout,它的默认编码是UTF-8。该类的子类可以提供自己的默认编码。
Layouts的分类
名称 | 描述 |
---|---|
CSV Layouts | 格式化日志参数为CSV(字符分隔值) |
GELF Layout | 格式化日志为Graylog Extended Log Format (GELF) 1.1 |
HTML Layout | 生成一个HTML页面,并将日志事件添加进一个table的行中 |
JSON Layout | 格式化日志事件为JSON格式 |
Pattern Layout | 通过转换模式配置的灵活的Layout |
RFC5424 Layout | 按照RFC 5424规范格式化日志 |
Serialized Layout | 使用Java序列化将日志事件简单地序列化为字节数组 |
Syslog Layout | 格式化为BSD Syslog 记录 |
XML Layout | 按照log4j.dtd的定义,将记录格式化为XML |
YAML Layout | 将以一些YAML事件格式化为序列化字节字符串 |
常用Layout详解
Pattern Layout
Pattern Layout是一个可以通过转换模式灵活配置的Layout。所谓的转换模式与C语言的printf格式很相近,它是由文本和一种称为转换说明符的格式控制表达式组成的。
注意特殊字符转义的问题,特殊字符包括“\t, \n, \r, \f”等。如果要在输出中插入一个反斜线,则需要使用“//”。
每一个转换说明符都由“%”开始,后面可跟格式修饰符和转换字符。转换字符是用来说明数据类型的。格式修饰符控制如宽度、填充、左右对齐等等。例如使用 “%-5p [%t]: %m%n”作为模式字符串,那么下面的代码块:
Logger logger = LogManager.getLogger("MyLogger");
logger.debug("Message 1");
logger.warn("Message 2");
会产生如下日志输出:
DEBUG [main]: Message 1
WARN [main]: Message 2
上面例子中的“%-5p”表示日志的优先级信息应该左对齐为5个字符宽度。
PatternLayout的参数列表
参数名 | 类型 | 描述 |
---|---|---|
charset | String | 字节数组的编码方式。若不设置,则使用平台默认的编码 |
pattern | String | 下面表中一个或多个转换模式的复合模式字符串 |
patternSelector | PatternSelector | 一个分析日志信息和确定使用哪个模式的组件,和pattern参数是互斥的 |
replace | RegexReplacement | 允许使用指定的字符串替换符合正则表达式的结果字符串 |
alwaysWriteExceptions | boolean | 默认为true,即使模式中没有配置异常转换,默认的异常格式器将会被添加到模式末尾,并将异常信息写出 |
header | String | 可向每个日志文件顶部添加的字符串信息 |
footer | String | 可向每个日志文件尾部添加的字符串信息 |
disableAnsi | boolean | 默认为false。如果为真,则不会输出ANSI控制码 |
noConsoleNoAnsi | boolean | 如果为true(默认false)并且System.console()为空,则不输出ANSI控制码 |
RegexReplacement的参数
参数名 | 类型 | 描述 |
---|---|---|
regex | String | Java正则表达式 |
replacement | String | 替换符合正则表达式的字符串 |
具体表达式
一、c{precision},logger{precision}
用于打印输出该logger的名字。如:
转换模式 | logger 名 | 结果 |
---|---|---|
%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{precision},class{precision}
用于输出产生该条日志记录的全限定类名,可以跟precision参数,规则和1相同。
三、 d{pattern},date{pattern}
用于输出日志事件发生的时间。pattern的可选参数和格式如下:
Pattern | Example |
---|---|
%d{DEFAULT} | 2012-11-02 14:34:02,781 |
%d{ISO8601} | 2012-11-02T14:34:02,781 |
%d{ISO8601_BASIC} | 20121102T143402,781 |
%d{ABSOLUTE} | 14:34:02,781 |
%d{DATE} | 02 Nov 2012 14:34:02,781 |
%d{COMPACT} | 20121102143402781 |
%d{HH:mm:ss,SSS} | 14:34:02,781 |
%d{dd MMM yyyy HH:mm:ss,SSS} | 02 Nov 2012 14:34:02,781 |
%d{HH:mm:ss}{GMT+0} | 18:34:02 |
%d{UNIX} | 1351866842 |
%d{UNIX_MILLIS} | 1351866842781 |
四、l , location
输出产生该日志的调用者的位置信息。这个地址通常由原点符分隔的全限定方法名,源文件名和行号组成。注意,生成位置信息是一项昂贵的开销,可能会影响到性能,要谨慎使用。
五、 L , Line
输出产生日志的地点的行号。
六、 m{nolookups}{ansi}, msg{nolookups}{ansi}, message{nolookups}{ansi}
输出与日志事件相关联的应用程序提供的消息。即我们调用logger.error(“balabala”)等方法想记录的balabala信息。{ansi}可以将 ANSI escape codes 一起返回,改ANSI用来修饰样式等属性。
通常情况下调用logger.info("Try ${date:YYYY-MM-dd}")
时,${date:YYYY-MM-dd}会被日期模板自动替换为实际的日期。而使用nolookups则会抑制这项特性,从而将日志信息以原字符串输出。
七、M ,method
输出产生日志的方法名
八、marker
The full name of the marker, including parents, if one is present.
九、n
输出一个平台相关的换行符,如”\n”或者”\r\n”
十、N nano
输出日志发生时的System.nanoTime()
十一、pid{[defaultValue]} processId{[defaultValue]}
输出产生该日志的进程id,如果平台不支持进程id,则会返回defaultValue默认值。
十二、p|level{level=label, level=label, …} p|level{length=n} p|level{lowerCase=true|false}
用于输出该日志的等级,示例如下:
//为日志等级起别名
%level{WARN=Warning, DEBUG=Debug, ERROR=Error, TRACE=Trace, INFO=Info}
//下面两行等效,只输出等级首字母
%level{WARN=W, DEBUG=D, ERROR=E, TRACE=T, INFO=I}
%level{length=1}
//混合使用,ERROR等级输出为Error,其他等级只输出前两个字母
%level{ERROR=Error, length=2}
//规定输出等级的大小写,默认是大写
%level{lowerCase=true}
十三、r relative
输出从JVM启动,到产生该日志时的毫秒数。
十四、replace{pattern}{regex}{substitution}
在pattern的范围内,用substitution替换符合regex(正则表达式)的部分,示例如下:
//该语句会将%logger %msg中的所有圆点替换为斜杠
"%replace{%logger %msg}{\.}{/}"
十五、rEx|rException|rThrowable
{
[“none” | “short” | “full” | depth]
[,filters(package,package,…)]
[,separator(separator)]
}
{ansi(
Key=Value,Value,…
Key=Value,Value,…
…)
}
{suffix(pattern)}
输出主异常及其子异常的堆栈信息。举例如下:
//输出日志信息的前n行
%rEx{n}
//下面的语句会抑制异常信息的输出
%rEx{none} or %rEx{0}
//下面的语句会抑制packages包内的异常输出,packages是一个包名列表
filters(packages)
//separator可以用来设置换行分隔符,默认的是系统的换行符,下面的语句会根据“|”来换行。
separator(|)
十六、style{pattern}{ANSI style}
使用ANSI修饰符来修饰pattern多代表的日志信息的样式,style可以用来增加如粗体、下划线、背景颜色等等样式。如:
%style{%d{ISO8601}}{black} %style{[%t]}{blue} %style{%-5level:}{yellow} %style{%msg%n%throwable}{green}
//可以和其他样式混用
%d %highlight{%p} %style{%logger}{bright,cyan} %C{1.} %msg%n
//可以直接使用%加颜色的方式
%black{%d{ISO8601}} %blue{[%t]} %yellow{%-5level:} %green{%msg%n%throwable}
十七、线程相关 T、t、tp、x、X{key[,key2…]}
- T , tid, threadid
输出产生该日志的线程id - t, tn, thread, threadName
输出产生该日志的线程名 - tp, threadPriority
输出产生该日志的线程的优先级 - x NDC
输出跟该日志相关的线程上下文堆栈信息 - X{key[,key2…]}, mdc{key[,key2…]},MDC{key[,key2…]}
输出线程上下文堆栈里面与key相对应的特定信息。如果不加后续选项,则会默认输出整个上下文的键值对信息。
十八、xEx|xException|xThrowable
{
[“none” | “short” | “full” | depth]
[,filters(package,package,…)]
[,separator(separator)]
}
{ansi(
Key=Value,Value,…
Key=Value,Value,…
…)
}
{suffix(pattern)}
和%Throwable类似,但该表达式会包含jar包的相关信息。
十七、%
使用“%%”来输出一个百分符号。
关于格式修饰符
格式修饰符通常位于%和转换字符之间。
第一个可选的格式修饰符是左对齐修饰符,用(-)表示。接着是最小宽度修饰符,这是一个代表输出字符数最小长度的十进制数字,如果实际输出字符数不足,那么会用空格在左边进行填充(即保持右对齐,但可以设置为左对齐)。如果字符数超过了这个最小值,那个这个范围就会被相应地拓展而不会截取信息。
与最小宽度修饰符相对应,也有最大宽度修饰符:用句号加一个十进制数字,如%.30c
代表c的长度最长为30,如果超出了30个,如32个字符,那么最前面的两个字符将被删掉。可以通过在句号后面加上一个减号(-)来设置截取最后的多余字符。
举例如下:
格式修饰符 | 左对齐 | 最小长度 | 最大长度 | 说明 |
---|---|---|---|---|
%20c | false | 20 | none | 长度不足时,用空格左填充至20 |
%-20c | true | 20 | none | 长度不足时,用空格右填充至20 |
%.30c | NA | none | 30 | 长度超出时,截掉开头字符 |
%20.30c | false | 20 | 30 | 截去和填充均在开头 |
%-20.30c | true | 20 | 30 | 在开头截去,在末尾填充 |
%-20.-30c | true | 20 | 30 | 截去和填充均在末尾 |
练习示例
采用如下配置:
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
测试类如下:
public static void main(final String... args) {
// Set up a simple configuration that logs on the console.
logger.trace("Entering application.");
logger.trace("Exiting application.");
}
则输出如下:
16:24:19.280 TRACE com.star.auto.MyApp 17 main - Entering application.
16:24:19.288 TRACE com.star.auto.MyApp 18 main - Exiting application.
试着编写自己的配置,巩固记忆吧!
更加完整的测试示例基于SpringBoot和Maven构建,包含控制台和文件输出,采用了上面示例中的PatternLayout格式化输出,已经通过测试,并且上传至Github,欢迎克隆学习!Github开源地址:https://github.com/Dodozhou/log4j2Learning