qweewq123qwe 发表于 2017-1-10 07:40:51

Java日志学习三:Apache Log4j源码浅析

一.Apache Log4j


[*]http://logging.apache.org/log4j/2.x/
[*]本文只讲初始化Logger的过程。

二.Apache Log4j里的几个核心类


[*]Logger:日志类。getLogger()交给LogManager去实现。
[*]Level:八个级别。 #OFF,FATAL,ERROR,WARN,INFO,DEBUG,TRACE,ALL。
[*]LogManager:Use the LogManager  class to retreive  Logger instances or to operate on the current
 LoggerRepository。
[*]RepositorySelector:该接口只有一个方法LoggerRepository getLoggerRepository()。LogManager有一个RepositorySelector对象。
[*]LoggerRepository:创建和管理Logger。
[*]Hierarchy:实现LoggerRepository, RendererSupport,是最重要的一个数据结构,维护着整个日志树。调用LoggerFactory产生Logger。
[*]LoggerFactory:该接口只有一个方法 Logger makeNewLoggerInstance(String name)。DefaultCategoryFactory实现这个接口,最终就是这里new Logger(name)。
[*]ObjectRenderer:该接口只有一个方法String doRender(Object o)。Log4J中,对传入的message实例,如果是非String类型,会先使用注册的ObjectRender(在LogRepository中查找注册的ObjectRender信息)处理成String后返回,若没有找到相应的ObjectRender,则使用默认的ObjectRender,它只是调用该消息实例的toString()方法。比喻log4j.porperties里的log4j.renderer.com.jyz.study.jdk.logger.User=com.jyz.study.jdk.logger.UserRenderer,UserRenderer就是一个ObjectRender。但是这个东西实际开发中很少用到。
[*]
Appender:该接口定义了日志的输出方式,如经常用的两个Appender
#输出到控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
#输出到DailyRolling文件
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
 

三.Logger初始化
  Logger logger = Logger.getLogger(Log4jTest.class)将发生以下事情。
       LogManager静态代码块里:


[*]以DEBUG等级创建一个RootLogger,然后以RootLogger为参数创建一个Hierarchy类的实例。
[*]以Hierarchy为参数创建一个DefaultRepositorySelector类的实例,就是我们上面说的“LogManager有一个RepositorySelector对象。”
[*]读取配置文件。
       正式进入LogManager.getLogger(name)


[*]  静态代码块完后LogManager.getLogger(name)由getLoggerRepository().getLogger(name)去实现。

[*]getLoggerRepository()会调用上面的DefaultRepositorySelector.getLoggerRepository(),也就是Hierarchy。
[*]Hierarchy.getLogger(name)最终由LoggerFactory.makeNewLoggerInstance(name)实现。
       单独说一下配置文件的读取,最终会进入PropertyConfigurator的doConfigure(Properties properties, LoggerRepository hierarchy)方法。


[*]解析log4j.reset,看hierarchy是否需要重置。
[*]解析log4j.threshold。Threshold是个全局的过滤器,它将把低于所设置的level的信息过滤不显示出来。
[*]解析log4j.rootCategory。设置日志级别和初始化所有appender。
[*]解析og4j.loggerFactory。可以自定义lLoggerFactory类,要实现LoggerFactory接口。
[*]解析log4j.category.     log4j.logger.     log4j.renderer.。前两者有什么区别?
#指定com.neusoft包下的所有类的等级为DEBUG,对不同的类输出不同的文件
log4j.logger.org.apache.commons=ERROR test1appender
#指定com.jyz包下的所有类的等级为INFO,对不同的类输出不同的文件
log4j.category.com.jyz=INFO test1appender
#指定日志输出User对象,使用UserRenderer
log4j.renderer.com.jyz.study.jdk.logger.User=com.jyz.study.jdk.logger.UserRenderer
 
页: [1]
查看完整版本: Java日志学习三:Apache Log4j源码浅析