`
jakoes
  • 浏览: 67887 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Log4j源代码阅读—Log4j初始化

阅读更多
一、Log4j的初始化(LogManager类中的静态块中)。

    1、 以DEBUG等级创建一个RootLogger,然后以RootLogger为参数创建一个Hierarchy类的实例。
    2、 Hierarchy类中实现了LoggerRepository接口和RendererSupport接口。LoggerRepository接口主要提供了对Logger聚集的一些访问方法和Threshold等级的支持。
    3、 以Hierarchy为参数创建一个DefaultRepositorySelector类的实例。以便提供一种获取LoggerRepository的方法。
    4、 DefaultRepositorySelector类实现了RepositorySelector接口。RepositorySelector提供了一个获取LoggerRepository的方法。
    5、 下面开始读取默认配置文件。首先尝试读取Log4j.xml,如果不存在就读取Log4j.properties。如果都不存在就放弃作默认配置。继续运行。

二、Log4j配置文件的读取(PropertyConfigurator,读取Log4j.properties文件)

    1、 准备工作
    PropertyConfigurator的静态方法Configure()可以接受三种参数:String,URL, Properties;Configure()方法生成一个PropertyConfigurator的实例并调用相应的doConfigure(XXX,LoggerRepository)。以String和URL为参数的doCofigure()方法在读取了配置文件后都会调用doConfigure(Properties,LoggerRepository)方法。
    2、 doConfigure(Properties,LoggerRepository)方法
    doConfigure()方法首先设置Log4j类库本身的调试状态,即读取”log4j.debug”属性;然后设置Log4j的Hierarchy的Threshold属性。这两个属性也是配置文件中两个唯一的顶层属性。
    下面doConfigure()调用了configureRootCategory();configureLoggerFactory(); parseCatsAndRenderers()方法分别配置RootLogger,LoggerFacory,其他Logger和Renderer。

三、onfigureRootCategory(Properties,LoggerRepository)配置RootLogger

    读取”log4j.rootLogger”属性,同步化RootLogger调用parseCatetory()方法开始配置RootLogger。
    1、 parseCategory(Properties,Logger,String key,String LoggerName,String value)配置Logger
    value第一个逗号前的是Logger的等级,除了RootLogger,其他的Logger也可以设置为”internal”,如果Logger设置了Level合法则设置Level,否则Level设为空。
    在开始配置Logger的Appender前先删除并关闭Logger中所有的Appender。在这里删除本Logger关联的Appender可以理解,可是将涉及到的Appender全部关闭,不知道有什么玄机。关闭所关联有的Appender也让Log4j的多次配置,很容易出错。
    Value中第一个逗号以后是以逗号分割的多个Appender,在读取了有效的AppenderName以后,重复调用parseAppender()配置Appender,配置完了后将配置好的Appender挂到Logger中。
    2、 parseAppender(Properties,String appenderName)配置appender
    首先尝试读取registry,看在本次的配置过程中这个appender是否已经配置过了,如果已经有配置好的Appender,直接返回配置好的Appender。
    如果这是第一次配置这个AppenderName,读取log4j.appender.[AppenderName]属性,生成相应的Appender实例。并设这Appender的名称为[AppenderName]。
    判断声称的Appender是否是OptionHandler的实例,并判断Appender是否需要Layout,如果需要就读取”log4j.appender.[AppenderName].layout’属性,生成相应的LayOut实例,并加载到Appender中。然后调用PropertySetter.setProperties()设置LayOut的属性。
    然后调用PropertySetter.setProperties()设置Appender的属性(设置过程可以参照上面LayOut属性的设置)。
    最后,将配置好的Appender添加到registry中。
    3、 PropertySetter类利用Introspection和Reflection设制相应设立的属性。(所要设置的类必须有相应得Setter,Getter方法,且方法中只能有一个参数(默认为String))。
    静态方法setProperties(Object,Properties,String prefix)首先以Object为参数生成一个PropertySetter的实例,然后调用setProperties(Properties,prefix)方法。
    setProperties(Properties,String prefix)方法遍历Properties中为[prefix]开头并且[prefix]后面不是直接跟点号”.”的属性。当设置的Object是Appender的一个实例的时候不出力”[prefix.layout]”属性(因为这个属性已经在parseAppender()方法中配置过了)。然后调用setProperty(key,value)方法设置属性。
    setProperty(String name,String value)方法首先利用内省获取name属性的PropertyDescriptor,然后调用setProperty(PropertyDescriptor,name,value)利用Reflection真正设置Object的name属性。
    最后如果所设置的对象是OptionHandler的实例,调用activateOptions()方法,实施所设置的属性,比如将设置的FileName检查一下,然后应用到相应的属性中。


四、configureLoggerFactory(Properties)配置LoggerFactory,LoggerFactory影响到后面Logger的创建。

    1、 读取”log4j.loggerFactory”属性,如果属性是一个有效的类名,并且使LoggerFactory的子类,就创建一个给类的实例,并保存到PropertyConfigurator类的一个保护变量loggerFactory中。
    2、 调用PropertySetter.setProperties()方法,以”log4j.factory.”为前缀给LoggerFactory设制属性(设置过程可以参照上面LayOut属性的设置)。

五、parseCatsAndRenderers(Properties,LoggerRepository)配置普通的Logger和Renderer。

    1、 普通Logger的配置
        遍历Properties,读取所有以”log4j.category.”和”log4j.logger.”开头的属性,截取Logger名称调用LoggerRepository.getLogger(loggerName,loggerFactory)生成一个新的Logger。关于Logger的新建,在后面单独讨论。
        同步化新建的Logger,调用parseCategory()方法配置Logger的属性(参见前面RootLogger的配置)。然后调用parseAdditivityForLogger()方法设置Logger的继承属性。
        parseAdditivityForLogger(Properties,Logger,String loggerName),首先读取”log4j.additivity.[loggerName]”属性,并调用Logger.setAdditivity()方法设置Logger的继承属性。
    2、 Renderer的配置
        遍历Properties,读取所有以”log4j.renderer.”开头的属性,截取Renderer名称,如果LoggerRepository是RendererSupport的一种实例,调用RendererMap.addRenderer()方法添加Renderer。
    3、 RendererMap.addRender(RendererSupport,String renderedClassName,String renderingClassName)添加解释器
        生成renderingClassName类的实例,然后调用RendererSupport.setRenderer (renderedClass,renderer)将renderer添加到Logger容器中。

六、最后将保存配置的Appender的registry清空。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ifeegoo/archive/2009/01/08/3736213.aspx
分享到:
评论

相关推荐

    log4net .net日志打印源代码 支持win32或wm

    // 初始化日志文件,根据指定文件的大小备份日志文件。 // // 参数: // fileSize: // 日志文件大小,单位:KB。 public bool Initilize(long fileSize) { } // 摘要: // 释放由 FENIO.Log4net 使用的所有...

    log4ce_cxx 嵌入日志源代码

    ce或嵌入式设备日志打印源代码:功能强大,代码简洁 class Log4ce_cxx { public: /************************************************************************/ /* lpcsLogFile:日志全路径文件名,默认:\Temp\...

    snort源代码分析

    下面对源代码文件分组说明。 snort.c(.h)是主程序所在的文件,实现了main函数和一系列辅助函数。 decode.c(.h)把数据包层层剥开,确定该包属于何种协议,有什么特征。并 标记到全局结构变量pv中。 log.c(.h)...

    mihoyo-signin:米游社app自动签到程序-源代码

    mihoyo-signin:米游社app自动签到程序-源代码 Mihoyo登录 自动完成米游币任务 论坛区签到 阅读帖子 点赞帖子 分享帖子 安全提醒 1工作流程是所有注册用户都可见的,包括log,在旧版本中有一些log,可能会导致你们的...

    Log4cxx_win32

    Win32 日志源代码 支持Unicode和非Unicode字符 支持日志级别输出 设定日志文件大小 class Log4cxx { public: /************************************************************************/ /* lpcsLogFile:日志...

    毕业设计-微信小程序在线免费小说应用源代码

    |- init-database.js --- 初始化数据库,主要是往数据库写入一些书籍数据 |- utils |- chineseToNum.js --- 解析数字,比如一千二百会变成1200 |- fakeUserAgent.js --- 随机userAgent,反爬虫 |- log.js --- ...

    互信息matlab源代码

    %初始化直方图数组 hab = zeros(256,256); ha = zeros(1,256); hb = zeros(1,256); %归一化 if max(max(a))~=min(min(a)) a = (a-min(min(a)))/(max(max(a))-min(min(a))); else a = zeros(M,N); end if max(max...

    APDUAnalysiser及Java源代码

    卡上电话本记录初始化解析; d.短信读取及TPDU解析(与QCAT工具显示方式相同,支持中文解析); e.鉴权操作Tag解析; 3).OTA信息 列表显示及按类型过滤显示。这部分Log的显示高通工具做得本身比较好,这里的功能与...

    MATLAB的数据采集与分析系统源代码

    这个.M文件可以分为GUI初始化和回调函数两个部分,用户控件的回调函数根据用户与GUI的具体交互方式分别调用。回调函数就是在调用对象时,该对象所要回应的动作。 因此,如何编写对象的回调函数是该系统的一大难点。...

    基于springboot的设备管理系统+源代码+文档说明

    - 日志管理:SLF4J 1.7、Log4j - 页面交互:Vue2.x **软件需求** - JDK1.8 - MySQL5.5+ - Maven3.0+ **本地部署** - 通过git下载源码 - 创建数据库renren_security,数据库编码为UTF-8 - 执行db/...

    hook以驱动方式注入内核源代码

    TRACEMSG("初始化例程...完成"); //创建设备。 TRACEMSG("创建设备..."); PDEVICE_OBJECT pKeyboardDevice = NULL; if (!NT_SUCCESS(retValue = CreateDevice(pDriverObject, &pKeyboardDevice))) { ...

    C++日志类libglog使用

    1:把glog文件夹拷贝到源代码目录 2:在工程设置中添加附加包含目录(glog\include;)和附加库目录(glog\lib;),在附件依赖项中添加对应lib文件,一一对应关系如下: MDd libglog32MDd.lib MD libglog32MD.lib MTd...

    一个求积分的VC++类及Demo源代码

    内容索引:VC/C++源码,其它分类,积分 一个求积分的VC++类及Demo源代码,特点:  1. 支持各种复杂的积分表达式,可含任何数学函数,如 3*exp(x)*tan(x)/(8+log(x))  2. 可检查出表达式的书写错误  3. 可设置积分...

    将 Flex 集成到 Java EE 应用程序的最佳实践(完整源代码)

    HttpFlexSession 是 BlazeDS 提供的一个 Listener,负责监听 Flex 远程调用请求,并进行一些初始化设置: 清单 4. 定义 Flex Listener <listener> <listener-class>flex.messaging.HttpFlexSession...

    【JavaScript源代码】JS中for,for...in,for...of和forEach的区别和用法实例.docx

     基本语法格式: for(初始化变量;条件表达式;操作表达式){    循环体语句;  } 普通for循环在Array和Object中都可以使用。for循环中可以使用return、break等来中断循环。 //遍历数组 var arr = [1,2,3,4,5];...

    +Flex+集成到+Java+EE+应用程序的最佳实践(完整源代码)

    HttpFlexSession 是 BlazeDS 提供的一个 Listener,负责监听 Flex 远程调用请求,并进行一些初始化设置: 清单 4. 定义 Flex Listener <listener> <listener-class>flex.messaging.HttpFlexSession...

    Python-Apache-Log-Analysis:用于执行日志数据分析的Python源代码-apache source code

    LogAnalyzer:初始化必要的变量和数据结构并维护方法的类 init :构造函数逐行读取并动态更新统计信息 record_validity:检查记录有效性的方法 identify_active_hosts:识别最活跃的十大主机/ IP地址的方法 identify...

    Codesys记录日志,获取系统时间,功能块源码

    实现类似于C#上位机那种Log日志功能,即运行一次即可实现记录当前在何种时间做了何种动作,带时间戳和日期功能。可实现每日机器运行日志的功能。同时也方便与上位机或协作方进行查错,带时间戳功能,在哪一毫秒进行...

    蓝牙协议及其源代码分析.rar

    5.7 实现HCI 的部分源代码及其分析.......... PAGEREF _TOC120615691 \H 27 5.7.1 HCI 对上行数据流的处理过程......... PAGEREF _Toc120615692 \h 27 5 5.7.2 HCI 对下行数据流的处理过程......... PAGEREF _Toc...

    远程文件系统服务器源码

    远程文件系统服务器源码, 超过9000行C++源代码, 其中包含服务程序RFSvc.exe和RF32s.dll动态库源码, 文件清单如下: \RFServer\unit_rc\RCServer.h \RFServer\unit_rc\RCServerObj.cpp \RFServer\unit_rc\RCServerObj....

Global site tag (gtag.js) - Google Analytics