初识log4j1.x
研究源码首先要对项目要有整体的认识,这一章节主要让大家对log4j1.x有一个整体的认识,并以此为切入点,认识log4j1.x的整个框架
1 整体认识
先整体上对log4j1有一个整体的认识,然后再在后面对log4j的研究中逐渐加深对其的理解。先不必纠结在整体的类图和流程图中。
(这里类图和流程从简,能够表达内容即可)
1.1 打印日志流程图

流程说明:
�-第一步: 初始化Logger容器LoggerRepository
,默认为Hierachy
,�根节点是RootLogger
-第二步: 获取Logger
实例,调用LogManager.getLogger()
获得Logger
实例,存在直接返回,不存在创建返回
-第三步: 判断是否打印日志(请求打印日志的Level要高于或者等于Logger的级别,请求打印日志语句才能生效),Logger
实例的所有Appender
按照Layout
的格式输出日志
1.2 类图

类图说明:
-
LoggerFactory : Logger的工厂,用来获得Logger实例
-
LoggerRepository: Logger的容器
-
RepositorySelector: 获取Logger容器
-
LogManager: Logger的管理中心,获取Logger容器、Logger实例、RootLogger
-
Logger: 日志记录器
-
Appender: 日志输出目的地
-
Layout: 日志输出格式
2 �搭建环境
创建maven项目,加入依赖:
<!-- Log4j1 日志框架包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
3 �代码示例(以此为切入点了解架构)
public class BasicConfiguratorDemo {
private static final Logger LOGGER =Logger.getLogger(BasicConfiguratorDemo.class);
public static void main(String[] args){
BasicConfigurator.configure();
LOGGER.info("Hello World");
}
}
输出结果:
1 [main] INFO com.log.log4j.configure.BasicConfiguratorDemo - Hello World
4 代码运行流程

4.1 获取Logger流程(Logger.getLogger(BasicConfiguratorDemo.class))

4.2 BasicConfigurator.configure()配置流程
获得RootLogger,添加ConsoleAppender,由于继承关系,其他Logger的父Logger都是RootLogger.所以其他Logger的Appender都是这里定义的ConsoleAppender
public static void configure() {
Logger root = Logger.getRootLogger();
root.addAppender(new ConsoleAppender(
new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN)));
}
4.3 打印Hello World
(LOGGER.info("Hello World"))流程
源码:
public void info(Object message) {
if(repository.isDisabled(Level.INFO_INT))
return;
if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel()))
forcedLog(FQCN, Level.INFO, message, null);
}
//Level具有继承特性,如果Logger本身没有设置Level,会继承父Logger的Level,Logger至少有一个Parent(RootLogger),具体参考log4j文档
public Level getEffectiveLevel() {
for(Category c = this; c != null; c=c.parent) {
if(c.level != null)
return c.level;
}
return null; // If reached will cause an NullPointerException.
}
流程:
