Log4j

前言

1、Log4j

  • Log4j API 包是根据 Apache 软件许可证分发的。

  • 最新的 log4j 版本,包括全源代码,类文件和文档可以在 Log4j 官网 找到。

  • 我们可以从上面的链接下载 apache-log4j-x.x.x.tar.gz 或 zip 文件。

  • 我们可以使用 log4j 将信息记录到各种目的地,例如发送电子邮件,数据库或文件。

1.1 Log4j2

  • Log4j2 是一个 Java 日志组件,被各类 Java 框架广泛地使用。

  • Log4j2 的前身是 Log4j。

  • Log4j2 重新构建和设计了框架,可以认为两者是完全独立的两个日志组件。

  • Log4j 和 Log4j2 的区别

    • jar 包

      • Log4j2 分为 2 个 jar 包,一个是接口 log4j-api-${版本号}.jar,一个是具体实现 log4j-core-${版本号}.jar
      • Log4j 只有一个 jar 包 log4j-${版本号}.jar
    • 版本号

      • Log4j2 的版本号目前均为 2.x。
      • Log4j 的版本号均为 1.x。
    • package 名

      • Log4j2 的 package 名称前缀为 org.apache.logging.log4j
      • Log4j 的 package 名称前缀为 org.apache.log4j
  • 注意:Log4j2 以下版本存在 漏洞,尽量避免使用这些版本!

    1
    Apache log4j2 v2.0-beta9 到 v2.15.0

2、入门

  • 通常,我们写代码的过程中,免不了要输出各种调试信息。在没有使用任何日志工具之前,都会使用 System.out.println 来做到。

  • 这么做直观有效,但是有一系列的缺点

    • 不知道这句话是在哪个类,哪个线程里出来的。
    • 不知道什么时候前后两句输出间隔了多少时间。
    • 无法关闭调试信息,一旦 System.out.println 多了之后,到处都是输出,增加定位自己需要信息的难度。
    • 等等。
  • 为了应对这种情况,我们使用 Log4j 来进行日志输出。采用如下代码,执行雷同的输出。可以看到输出结果有几个改观。

    • 知道是 log4j.TestLog4j 这个类里的日志。
    • 是在哪个线程里的日志。
    • 日志级别可观察,一共有 6 个级别 TRACE DEBUG INFO WARN ERROR FATAL。
    • 日志输出级别范围可控制,如只输出高于 DEBUG 级别的,那么 TRACE 级别的日志自动不输出。
    • 每句日志消耗的毫秒数 (最前面的数字),可观察,这样就可以进行性能计算。
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import org.apache.log4j.BasicConfigurator;
    import org.apache.log4j.Level;
    import org.apache.log4j.Logger;

    public class TestLog4j {

    static Logger logger = Logger.getLogger(TestLog4j.class); // 基于类的名称获取日志对象

    public static void main(String[] args) throws InterruptedException {

    BasicConfigurator.configure(); // 进行默认配置
    logger.setLevel(Level.DEBUG); // 设置日志输出级别,只输出高于 DEBUG 级别的,那么 TRACE 级别的日志自动不输出

    logger.trace("跟踪信息"); // 进行不同级别的日志输出
    logger.debug("调试信息");
    logger.info("输出信息");
    logger.warn("警告信息");
    logger.error("错误信息");
    logger.fatal("致命信息");
    }
    }

3、配置

  • 依赖导入

    • pom.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.4.1</version>
      </dependency>

      <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.4.1</version>
      </dependency>
  • 配置方式

    • 默认配置

      1
      2
      // 进行默认配置
      BasicConfigurator.configure();
    • 采用指定配置文件

      1
      2
      // 按照文件 e:\project\log4j\src\log4j.properties 中的设置进行
      PropertyConfigurator.configure("e:\\project\\log4j\\src\\log4j.properties");
      1
      2
      // 除了使用 log4j.properties,也可以使用 xml 格式文件进行配置
      PropertyConfigurator.configure("e:\\project\\log4j\\src\\log4j.xml");
  • 配置文件

    • log4j.properties

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      # 设置日志输出的等级为 debug, 低于 debug 就不会输出了。设置日志输出到两种地方,分别叫做 stdout 和 R
      log4j.rootLogger=debug, stdout, R

      # 第一个地方 stdout, 输出到控制台
      log4j.appender.stdout=org.apache.log4j.ConsoleAppender
      log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

      # Pattern to output the caller's file name and line number. 输出格式是 %5p [%t] (%F:%L) - %m%n
      log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

      # 第二个地方 R, 以滚动的方式输出到文件,文件名是 example.log
      log4j.appender.R=org.apache.log4j.RollingFileAppender
      log4j.appender.R.File=example.log

      # 文件最大 100k
      log4j.appender.R.MaxFileSize=100KB

      # Keep one backup file. 最多滚动 5 个文件
      log4j.appender.R.MaxBackupIndex=5

      # 输出格式是 %p %t %c - %m%n
      log4j.appender.R.layout=org.apache.log4j.PatternLayout
      log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
    • log4j.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">

      <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

      <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
      <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d %-5p %c.%M:%L - %m%n"/>
      </layout>
      </appender>

      <!-- specify the logging level for loggers from other libraries -->
      <logger name="com.opensymphony">
      <level value="ERROR" />
      </logger>

      <logger name="org.apache">
      <level value="ERROR" />
      </logger>
      <logger name="org.hibernate">
      <level value="ERROR" />
      </logger>

      <!-- for all other loggers log only debug and above log messages -->
      <root>
      <priority value="ERROR"/>
      <appender-ref ref="STDOUT" />
      </root>

      </log4j:configuration>
  • 日志输出格式

格式 说明
%c 输出日志信息所属的类的全名
%d 输出日志时间点的日期或时间,默认格式为 ISO8601,也可以在其后指定格式,
比如:%d{yyy-MM-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28
%f 输出日志信息所属的类的类名
%l 输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行
%m 输出代码中指定的信息,如 log(message) 中的 message
%n 输出一个回车换行符,Windows 平台为 “rn”,Unix 平台为 “n”
%p 输出优先级,即 DEBUG,INFO,WARN,ERROR,FATAL。
如果是调用 debug() 输出的,则为 DEBUG,依此类推
%r 输出自应用启动到输出该日志信息所耗费的毫秒数
%t 输出产生该日志事件的线程名

4、Log4j2 漏洞

  • Log4j2 以下版本存在漏洞,尽量避免使用这些版本!

    1
    Apache log4j2 v2.0-beta9 到 v2.15.0
  • 漏洞描述

  • 漏洞防范

    • 升级 Log4j2 到最新版本

    • 使用最新版 JDK

    • 临时解决方案

      • 设置 jvm 参数 -Dlog4j2.formatMsgNoLookups=true
      • 在项目 classpath 目录下添加 log4j2.component.properties 配置文件,设置 log4j2.formatMsgNoLookups=true
      • 设置系统环境变量 LOG4J_FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为 true
文章目录
  1. 1. 前言
  2. 2. 1、Log4j
    1. 2.1. 1.1 Log4j2
  3. 3. 2、入门
  4. 4. 3、配置
  5. 5. 4、Log4j2 漏洞
隐藏目录