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 标识符
    
    		
    		
        
    
    
  • RandomAccessFileFile 是一样的只不过 RandomAccessFile 是始终是缓冲的而且不能关闭。据官方测量性能比 File 开启 bufferedIO 还要快 200%。内部使用的机制是 ByteBuffer + RandomAccessFile 而不是BufferedOutputStream

    Parameter 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}
        
    		
        
    				
            
    				
            
        
    
    
  • RollingRandomAccessFileRollingFile 是一样的,性能和 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/