log4j源码探究

Posted 架构思考

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了log4j源码探究相关的知识,希望对你有一定的参考价值。

log4j是一种常用的日志框架,帮助我们打印日志,以便日后出现问题时通过查看日志来排查原因。


首先对log4j进行一次简单的应用展示。


第一步:在idea中新建一个maven工程,并在pom文件中导入依赖。

 <dependencies> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>apache-log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> </dependency> </dependencies>


第二步:在resources目录下创建log4j.properties文件,配置log4j的属性。

# 定义rootLogger的日志级别为DEBUG,即优先级高于DEBUG的日志都会被记录下来# 定义rootLogger的appender的名称为FILElog4j.rootLogger = DEBUG, FILE
# 定义FILE这个appender的类型为FileAppender,日志会被记录到指定的文件中log4j.appender.FILE=org.apache.log4j.FileAppender# user.dir 为当前工程目录的下的src目录log4j.appender.FILE.File=${user.dir}/log.out
# Define the layout for file appenderlog4j.appender.FILE.layout=org.apache.log4j.PatternLayout

上述配置生成的log.out文件的位置如下图所示:


第三步:编写测试代码。

import org.apache.log4j.Logger;import java.io.*;import java.sql.SQLException;
public class Test{ public static void main(String[] args)throws IOException,SQLException{ Logger logger = Logger.getLogger(Test.class.getName()); logger.trace("Trace Message!"); logger.debug("Debug Message!"); logger.info("Info Message!"); logger.warn("Warn Message!"); logger.error("Error Message!"); logger.fatal("Fatal Message!"); }}


由于在log4j.properties文件中配置了logger的日志级别为DEBUG,所以只有9-12行的日志才会被记录到log.out文件中。结果如下图所示:

log4j源码探究




基本用法介绍完毕后,我们来探一探其实现原理。


log4j的核心组件有两个:

  1. logger

  2. appender


logger负责采集日志,然后将日志传递给appender,appender负责将日志通过IO操作写到指定的位置。


普通的appender,如FileAppender是同步操作的,性能较差。log4j中更强大的appender是AsyncAppender,它是异步操作的,性能有较大的提升。


AsyncAppender的核心原理就是开辟一片缓存区域,用于缓存日志;并运行一个守护线程程dispatcher,该守护线程从缓存区域中取出日志传递给挂在AsyncAppender上的同步appender,由同步appender将日志写入指定的地方。


首先看一下AsyncAppender的构造器:

log4j源码探究


AsyncAppender在append方法中处理日志(下面两张图都是append函数的代码,因为代码太长,所以截成两张图):

log4j源码探究

log4j源码探究


守护线程dispatcher的核心是Dispatcher类,该类实现了Runnable接口,下面的代码是其核心的run方法:



ps:读源码一定要抓主逻辑,细枝末节先忽略:)

以上是关于log4j源码探究的主要内容,如果未能解决你的问题,请参考以下文章

Vue源码探究-虚拟DOM的渲染

log4j源码阅读

MVCC原理探究及MySQL源码实现分析

vue-router源码阅读 内部探究

AQS源码探究_01 手写一个简化的ReentrantLock可重入锁

AQS源码探究_01 手写一个简化的ReentrantLock可重入锁