• 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"?>
    <Configuration status="info" name="log4j2-name" monitorInterval="5">
        <Properties>
            <Property name="console.pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} - [%t] %-5level %logger{36} - %msg%n</Property>
            <Property name="file.pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} - [%t] %-5level %logger{36} - %msg%n</Property>
        </Properties>
    
        <Appenders>
            <Console name="console-appender" target="SYSTEM_OUT">
                <PatternLayout pattern="${console.pattern}"/>
            </Console>
    
            <File name="files-appender" fileName="logs/files-appender.log" append="false">
                <PatternLayout>
                    <Pattern>${file.pattern}</Pattern>
                </PatternLayout>
            </File>
    
            <Async name="async-appender">
                <AppenderRef ref="files-appender"/>
            </Async>
    
            <RandomAccessFile name="random-access-file-appender" fileName="logs/random-access-file.log">
                <PatternLayout>
                    <Pattern>${file.pattern}</Pattern>
                </PatternLayout>
            </RandomAccessFile>
    
            <RollingFile name="rolling-file-appender" fileName="logs/rolling-file-appender.log"
                         filePattern="logs/rolling-file-appender-INFO-%d{yyyy-MM-dd}_%i.log.gz">
                <PatternLayout>
                    <Pattern>${file.pattern}</Pattern>
                </PatternLayout>
    
                <Policies>
                    <TimeBasedTriggeringPolicy interval="1"/>
                    <SizeBasedTriggeringPolicy size="1MB"/>
                </Policies>
            </RollingFile>
    
            <RollingRandomAccessFile name="rolling-random-access-file-appender"
                                     fileName="logs/rolling-random-access-file.log"
                                     filePattern="logs/$${date:yyyy-MM}/rolling-random-access-file-%d{MM-dd-yyyy}-%i.log.gz">
                <PatternLayout>
                    <Pattern>${file.pattern}</Pattern>
                </PatternLayout>
    
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="1 MB"/>
                </Policies>
            </RollingRandomAccessFile>
    
            <!-- to 收件者 from 寄件者  -->
            <SMTP name="mail-appender" subject="错误日志信息" to="发送到哪里" from="发送者"
                  smtpHost="smtp.qiye.163.com"
                  smtpPort="465"
                  bufferSize="1"
                  smtpUsername="SMTP用户名"
                  smtpPassword="SMTP密码"
                  smtpProtocol="smtps"
                  mail.smtp.ssl.enable="true"
                  mail.smtp.starttls.enable="true"
            >
                <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout>
                    <Pattern>${file.pattern}</Pattern>
                </PatternLayout>
            </SMTP>
    
        </Appenders>
        <Loggers>
    				<logger name="org.mybatis" level="INFO"></logger>
            <Root level="info">
                <AppenderRef ref="console-appender"/>
                <!--            <AppenderRef ref="file-appender"/>-->
                <AppenderRef ref="rolling-file-appender"/>
                <AppenderRef ref="async-appender"/>
                <AppenderRef ref="random-access-file-appender"/>
                <AppenderRef ref="rolling-random-access-file-appender"/>
                <AppenderRef ref="mail-appender"/>
            </Root>
        </Loggers>
    </Configuration>
    

    上面是我常用的几个标签,每个标签都有其各自的意义。

    Configuration

    整个配置中最核心的标签,他对应 log4j 的 ConfigurationFactory 因为我用的是 xml 所以 ConfigurationFactory 会把配置传递给 XmlConfigurationFactory ,最常用的标签就是下面这些。

    属性名称 描述
    name 配置的名称。
    status 日志的等级,有"off", "trace", "debug", "info", "warn", "error", "fatal" 和 "all" ,选择 "trace" 就可以把 Log4j 的日志也显示出来
    monitorInterval 每隔多少秒更新日志的配置信息

    Properties & Property

    properties 这个标签很简单就是一个属性标签可以配置一些全局的属性,可以给后面的标签使用。

    <Properties>
        <Property name="属性名称"></Property>
    </Properties>
    

    Appenders

    Appenders 单独没有什么作用,主要是他的各种子标签。下面子标签的属性是我常用的一些,如果不常用的可能没有列出来。

    • Console 日志通过控制台打印

      Parameter Name Type Description
      layout Layout 输出格式化,可以使用 PatternLayout 标签替代
      name String 标识符
      target String "SYSTEM_OUT" or "SYSTEM_ERR". 默认为 "SYSTEM_OUT".
      <Console name="console-appender" target="SYSTEM_OUT">
          <!--PatternLayout: 输出日志的格式-->
          <PatternLayout pattern=" %msg%n"/>
      		<!--ThresholdFilter :日志输出过滤-->
          <!--level="info" :日志级别,onMatch="ACCEPT" :级别在info之上则接受,onMismatch="DENY" :级别在info之下则拒绝-->
          <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
      </Console>
      
    • 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 name="files-appender" fileName="logs/files-appender.log" append="false">
       <!--PatternLayout: 输出日志的格式 这种写法和上面那个等同-->
          <PatternLayout>
              <Pattern>${file.pattern}</Pattern>
          </PatternLayout>
      </File>
      
    • Async 和其他的 Appenders 配合使用,可以使得 Appenders 变为异步处理

      Parameter Name Type Description
      name String 标识符
      <Async name="async-appender">
      		<!--AppenderRef: 引用其他的 appender 使其成为异步处理-->
      		<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
          <AppenderRef ref="files-appender"/>
      </Async>
      
    • 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 标识符
      <RandomAccessFile name="random-access-file-appender" fileName="logs/random-access-file.log">
          <PatternLayout>
              <Pattern>${file.pattern}</Pattern>
          </PatternLayout>
      		<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
      </RandomAccessFile>
      
      
    • 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 标识符
      <RollingFile name="rolling-file-appender" fileName="logs/rolling-file-appender.log"
                   filePattern="logs/rolling-file-appender-INFO-%d{yyyy-MM-dd}_%i.log.gz">
          <PatternLayout>
              <Pattern>${file.pattern}</Pattern>
          </PatternLayout>
      		<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
          <Policies>
      				<!-- TimeBasedTriggeringPolicy :时间滚动策略,默认0点小时产生新的文件
      						,interval="6" : 自定义文件滚动时间间隔,每隔6小时产生新文件, 
      						modulate="true" : 产生文件是否以0点偏移时间,即6点,12点,18点,0点-->
              <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
      				<!-- SizeBasedTriggeringPolicy: 当文件超过设定的大小就开始滚动-->
              <SizeBasedTriggeringPolicy size="1MB"/>
          </Policies>
      </RollingFile>
      
    • 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 用户名
      <SMTP name="mail-appender" subject="错误日志信息" to="发送到哪里" from="发送者"
              smtpHost="smtp.qiye.163.com"
              smtpPort="465"
              bufferSize="1"
              smtpUsername="SMTP用户名"
              smtpPassword="SMTP密码"
              smtpProtocol="smtps"
              mail.smtp.ssl.enable="true"
              mail.smtp.starttls.enable="true"
        >
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
      			
            <PatternLayout>
                <Pattern>${file.pattern}</Pattern>
            </PatternLayout>
        </SMTP>
      

      配置 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 导入下面坐标即可。

      <dependency>
          <groupId>javax.mail</groupId>
          <artifactId>mail</artifactId>
          <version>1.5.0-b01</version>
      </dependency>
      

    Loggers

    <Loggers>
    		<logger name="org.springframework" level="INFO"></logger>
        <Root level="info">
            <AppenderRef ref="console-appender"/>
            <!--            <AppenderRef ref="file-appender"/>-->
            <AppenderRef ref="rolling-file-appender"/>
            <AppenderRef ref="async-appender"/>
            <AppenderRef ref="random-access-file-appender"/>
            <AppenderRef ref="rolling-random-access-file-appender"/>
            <AppenderRef ref="mail-appender"/>
        </Root>
    </Loggers>
    

    使用 Logger 配置各种 Appenders ,Logger 必须指定一个包路径。还可以给这个包设置一个日志等级(TRACE、DEBUG、INFO、WARN、ERROR、ALL 或 OFF)。比如上面的 org.springframework ,如果未指定等级,默认为 ERROR。如果在标签内设置 additivity 属性如果为 true 则被该标签捕获的内容不会出现在 Root 节点。

    <logger name="org.springframework" level="INFO"></logger>
    

    Logger 也可以使用 AppenderRef 标签来指定输出位置和日志等级

    <logger name="org.springframework" level="INFO">
    		<AppenderRef ref="console-appender" level="error"/>
    </logger>
    

    没有使用 logger 标签捕获到的内容或者没有设置additivity 为 true 的日志会出现在 Root 节点, Root 节点没有 additivity。

    <Root level="info">
        <AppenderRef ref="console-appender"/>
        <!--            <AppenderRef ref="file-appender"/>-->
        <AppenderRef ref="rolling-file-appender"/>
        <AppenderRef ref="async-appender"/>
        <AppenderRef ref="random-access-file-appender"/>
        <AppenderRef ref="rolling-random-access-file-appender"/>
        <AppenderRef ref="mail-appender"/>
    </Root>
    

    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/

  • 相关阅读:
    CF819B Mister B and PR Shifts
    HDU5969 最大的位或
    UVA1464 Traffic Real Time Query System
    [SCOI2010]连续攻击游戏
    [USACO11JAN] Roads and Planes
    [POJ3613] Cow Relays(Floyd+矩阵快速幂)
    洛谷P3237 [HNOI2014]米特运输(树形dp)
    awk 正则表达式、正则运算符详细介绍
    awk单行脚本快速参考
    Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.
  • 原文地址:https://www.cnblogs.com/l5gw/p/15953185.html
Copyright © 2020-2023  润新知