Log4j2官方文档翻译、学习笔记之三——Layouts的分类及常用类型示例

时间:2022-12-30 21:48:58

官方文档本节地址: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