Log4j2 打印日志实践
Apache Log4j 是一个基于 Java 的日志记录工具。它是由瑞士程序员 Ceki Gülcü 于 2001 年开发的,现在则是Apache软件基金会的一个项目。 Log4j是几种Java日志框架之一。Log4j 团队创建了 Log4j 的继任者,版本号为 2.0 的新版本。Log4j 2.0 着重于 Log4j 1.2、1.3、java.util.logging 和logback中的问题,并解决这些框架中的架构问题。此外,Log4j 2.0 提供了一个插件架构,这使得其更可扩展。Log4j 2.0 不是与 1.x 向后兼容的版本。
—— wikipedia
日志系统在整个项目架构设计中占得比例很重,比如管理员操作记录,一些捕获的异常记录等等。这时候有一个好的日志框架就是我们所必须的。目前最流行的是 Log4j 2.0 版本虽然前一段时间出了一个 0day 的 BUG 但是瑕不掩瑜。Log4j2 的配置也比较简单,支持 yml 、xml 甚至是 json 都是可以的。这个实践中我用的是 xml 格式,毕竟其他的没用过。
先来看下整体的配置,然后在根据每个标签单独研究。
<?xml version="1.0" encoding="UTF-8"?>
%d{yyyy-MM-dd HH:mm:ss.SSS} - [%t] %-5level %logger{36} - %msg%n
%d{yyyy-MM-dd HH:mm:ss.SSS} - [%t] %-5level %logger{36} - %msg%n
${file.pattern}
${file.pattern}
${file.pattern}
${file.pattern}
${file.pattern}
上面是我常用的几个标签,每个标签都有其各自的意义。
Configuration
整个配置中最核心的标签,他对应 log4j 的 ConfigurationFactory
因为我用的是 xml 所以 ConfigurationFactory
会把配置传递给 XmlConfigurationFactory
,最常用的标签就是下面这些。
属性名称 | 描述 |
---|---|
name | 配置的名称。 |
status | 日志的等级,有"off", "trace", "debug", "info", "warn", "error", "fatal" 和 "all" ,选择 "trace" 就可以把 Log4j 的日志也显示出来 |
monitorInterval | 每隔多少秒更新日志的配置信息 |
Properties & Property
properties 这个标签很简单就是一个属性标签可以配置一些全局的属性,可以给后面的标签使用。
Appenders
Appenders 单独没有什么作用,主要是他的各种子标签。下面子标签的属性是我常用的一些,如果不常用的可能没有列出来。
-
Console 日志通过控制台打印
Parameter Name Type Description layout Layout 输出格式化,可以使用 PatternLayout 标签替代 name String 标识符 target String "SYSTEM_OUT" or "SYSTEM_ERR". 默认为 "SYSTEM_OUT". -
File 日志通过文件存储
Parameter Name Type Description append boolean 如果为 true ( 默认值),则记录将追加到文件末尾。如果设置为 false,则在写入新记录之前将清除该文件。 bufferedIO boolean 当 true 时 - 默认值,记录将写入缓冲区,并在缓冲区已满时将数据写入磁盘,或者,如果设置了立即Flush,则在写入记录时将数据写入磁盘。文件锁定不能与缓冲IO一起使用。性能测试表明,即使启用了即时浮现,使用缓冲 I/O 也能显著提高性能。 bufferSize int 当 bufferedIO 为 true 时,可以配置此项的缓冲区大小,默认值为 8192 字节。 fileName String 写入文件的名称,如果文件或者目录不存在会创建生成 name String Appender 标识符 ${file.pattern} -
Async 和其他的 Appenders 配合使用,可以使得 Appenders 变为异步处理
Parameter Name Type Description name String 标识符 -
RandomAccessFile 和 File 是一样的只不过 RandomAccessFile 是始终是缓冲的而且不能关闭。据官方测量性能比 File 开启
bufferedIO
还要快 200%。内部使用的机制是 ByteBuffer + RandomAccessFile 而不是BufferedOutputStreamParameter Name Type Description append boolean 如果为 true ( 默认值),则记录将追加到文件末尾。如果设置为 false,则在写入新记录之前将清除该文件。 fileName String 要写入的文件的名称。如果文件或其任何父目录不存在,则将创建它们。 bufferSize int 缓冲区大小默认为 262144 字节 (256 * 1024)。 name String 标识符 ${file.pattern} -
RollingFile 是一个 OutputStreamAppender,它写入 fileName 参数中指定的 File,并根据 TriggeringPolicy 和 RolloverPolicy 滚动文件。
Parameter Name Type Description append boolean 如果为 true ( 默认值),则记录将追加到文件末尾。如果设置为 false,则在写入新记录之前将清除该文件。 bufferedIO boolean 当 true 时 - 默认值,记录将写入缓冲区,并在缓冲区已满时将数据写入磁盘,或者,如果设置了立即Flush,则在写入记录时将数据写入磁盘。文件锁定不能与缓冲IO一起使用。性能测试表明,即使启用了即时浮现,使用缓冲 I/O 也能显著提高性能。 bufferSize int 当 bufferedIO 为 true 时,可以配置此项的缓冲区大小,默认值为 8192 字节。 fileName String 要写入的文件的名称。如果文件或其任何父目录不存在,则将创建它们。 name String 标识符 ${file.pattern} -
RollingRandomAccessFile 和 RollingFile 是一样的,性能和 RandomAccessFile 差不多
Parameter Name Type Description append boolean 如果为 true ( 默认值),则记录将追加到文件末尾。如果设置为 false,则在写入新记录之前将清除该文件。 fileName String 要写入的文件的名称。如果文件或其任何父目录不存在,则将创建它们。 bufferSize int 当 bufferedIO 为 true 时,可以配置此项的缓冲区大小,默认值为 8192 字节。 name String 标识符 -
SMTP 通过邮箱发送日志信息
Parameter Name Type Description name String 标识符 from String 寄件者邮箱地址 replyTo String 以逗号分隔的接受者邮箱地址 to String 接受者邮箱地址 subject String 邮件的标题 bufferSize integer 当 bufferedIO 为 true 时,可以配置此项的缓冲区大小,默认值为 512。 smtpHost String SMTP HOST smtpPassword String SMTP 密码 smtpPort integer SMTP 端口 smtpProtocol String SMTP 传输协议 smtps 或 smtp 默认是 smtp smtpUsername String smtp 用户名 ${file.pattern} 配置 SMTP 之后报错
main ERROR Could not create plugin of type class org.apache.logging.log4j.core.appender.SmtpAppender for element SMTP: java.lang.NoClassDefFoundError: javax/mail/Authenticator java.lang.NoClassDefFoundError: javax/mail/Authenticator
是应为没有找到 javax.mail 导入下面坐标即可。
javax.mail mail 1.5.0-b01
Loggers
使用 Logger 配置各种 Appenders ,Logger 必须指定一个包路径。还可以给这个包设置一个日志等级(TRACE、DEBUG、INFO、WARN、ERROR、ALL 或 OFF)。比如上面的 org.springframework
,如果未指定等级,默认为 ERROR。如果在标签内设置 additivity 属性如果为 true 则被该标签捕获的内容不会出现在 Root 节点。
Logger 也可以使用 AppenderRef 标签来指定输出位置和日志等级
没有使用 logger 标签捕获到的内容或者没有设置additivity 为 true 的日志会出现在 Root 节点, Root 节点没有 additivity。
PatternLayout
上面一直出现的 PatternLayout 标签很明显是日志输出的格式。官方有一套自己的格式非常多,非常丰富。
%d:发生时间,%d{yyyy-MM-dd HH:mm:ss,SSS},输出类似:2020-02-20 22:10:28,921
%F:输出所在的类文件名
%t:线程名称
%p:日志级别
%c:日志消息所在类名
%m:消息内容
%M:输出所在函数名
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
%l:执行的函数名(类名称:行号)com.core.LogHelper.aroundService(LogHelper.java:32)
%n:换行
%i:从1开始自增数字
%-5level:输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
${sys:user.home}是HOME目录 如:C:\Users\heave, 此处指定任意目录如:D:\logs
%highlight{} 高亮颜色 如:%highlight{%d [%t]}
%style{%d [%t]}{black} 设置高亮颜色 Red Green Yellow Blue Magenta Cyan White 还有一个 bold 高亮和其他颜色配合使用
例如: [%d{yyyy-MM-dd HH:mm:ss} %p][%c]: %m%n
更详细的可以查看官方手册 https://logging.apache.org/log4j/2.x/manual/layouts.html
部分内容来自:
[1]Log4j2 官网 https://logging.apache.org/log4j/2.x/
[2]Log4j2中文文档 https://www.docs4dev.com/docs/zh/log4j2/2.x/all/