zoukankan      html  css  js  c++  java
  • Log4j

     


    Log4j

    通过配置文件(log4j.xml或log4j.properties)控制日志的输出,包括输出格式、输出形式、输出级别等,主要组件是apache的log4jjar包和配置文件;
    一、组件:log4j jar包和配置文件

    二、应用步骤

    (1)在classpath下添加配置文件

    (2)class内引入   import org.apache.log4j.Logger
    (3)声明一个logger private static Logger logger = Logger.getLogger(ClassName.class); 
    (4)在程序中的相应位置加入输出信息:logger.info("用户登录:"+user.getAccount());

    三、配置文件说明

    1、 log4j.rootCategory=INFO, stdout , R
    此句为将等级为INFO的日志信息输出到stdout和R这两个目的地,stdout和R的定义在下面的代码,可以任意起名。
    等级可分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL,如果配置OFF则不打出任何信息,如果配置为INFO这样只显示INFO, WARN, ERROR的log信息,而DEBUG信息不会被显示,优先级:ALL < DEBUG < INFO <WARN < ERROR < FATAL < OFF2、 log4j.appender.stdout=org.apache.log4j.ConsoleApp此句为定义名为stdout的输出端是哪种类型,可以是

    org.apache.log4j.ConsoleAppender(控制台),
    org.apache.log4j.FileAppender(文件),
    org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
    org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
    org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

    3、 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    此句为定义名为stdout的输出端的layout是哪种类型,可以是
    org.apache.log4j.HTMLLayout(以HTML表格形式布局,
    org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
    org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串,
    org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息

    4、 log4j.appender.stdout.layout.ConversionPattern= [QC] %p [%t] %C.%M(%L) | %m%n
    如果使用pattern布局就要指定的打印信息的具体格式ConversionPattern,打印参数如下:
    %m 输出代码中指定的消息;
    %M 输出打印该条日志的方法名;
    %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL;
    %r 输出自应用启动到输出该log信息耗费的毫秒数;
    %c 输出所属的类目,通常就是所在类的全名;
    %t 输出产生该日志事件的线程名;
    %n 输出一个回车换行符,Windows平台为"rn”,Unix平台为"n”;
    %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy-MM-dd HH:mm:ss,SSS},输出类似:2002-10-18 22:10:28,921;
    %l 输出日志事件的发生位置,及在代码中的行数;
    [QC]是log信息的开头,可以为任意字符,一般为项目简称。
    输出的信息:[TS] DEBUG [main] AbstractBeanFactory.getBean(189) | Returning cached instance of singleton bean 'MyAutoProxy'

    6、 log4j.appender.R=org.apache.log4j.DailyRollingFileAppender 此句与第3行一样。定义名为R的输出端的类型为每天产生一个日志文件。

    7、 log4j.appender.R.File=D:\Tomcat 5.5\logs\qc.log  此句为定义名为R的输出端的文件名和路径为D:\Tomcat 5.5\logs\qc.log可以自行修改。

    以下是设置框架包中日志级别   这些包的设置可根据项目的实际情况而自行定制。
    8、 log4j.logger.com. neusoft =DEBUG 指定com.neusoft包下的所有类的等级为DEBUG。

    9、 log4j.logger.com.opensymphony.oscache=ERROR

    10、log4j.logger.net.sf.navigator=ERROR 这两句是把这两个包下出现的错误的等级设为ERROR,如果项目中没有配置EHCache,则不需要这两句。
    11、 log4j.logger.org.apache.commons=ERROR
    12、 log4j.logger.org.apache.struts=WARN  这两句是struts的包。
    13、log4j.logger.org.displaytag=ERROR  这句是displaytag的包。(QC问题列表页面所用)
    14、 log4j.logger.org.springframework=DEBUG    此句为Spring的包。
    15、log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN
    16、log4j.logger.org.hibernate=DEBUG   此两句是hibernate的包。

    四、配置文件解
    Log4j支持两种配置文件格式,一种是XML(标准通用标记语言下的一个应用)格式的文件,一种是Java特性文件log4j.properties(键=值)。

    下面将介绍使用log4j.properties文件作为配置文件的方法:
    ①、配置根Logger    Logger 负责处理日志记录的大部分操作。
    其语法为: log4j.rootLogger = [ level ] , appenderName, appenderName, …
    其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的总开关。比如在这里定义了INFO级别,只有等于及高于这个级别的才进行处理,则应用程序中所有DEBUG级别的日志信息将不被打印出来。ALL:打印所有的日志,OFF:关闭所有的日志输出。 appenderName就是指定日志信息输出到哪个地方。可同时指定多个输出目的地。
    ②、配置日志信息输出目的地 Appender
    Appender 负责控制日志记录操作的输出。
    其语法为:
    log4j.appender.appenderName = fully.qualified.name.of.appender.class
    log4j.appender.appenderName.option1 = value1

    log4j.appender.appenderName.optionN = valueN
    这里的appenderName为在①里定义的,可任意起名。
    其中,Log4j提供的appender有以下几种:
    org.apache.log4j.ConsoleAppender(控制台),
    org.apache.log4j.FileAppender(文件),
    org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
    org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),可通过log4j.appender.R.MaxFileSize=100KB设置文件大小,还可通过log4j.appender.R.MaxBackupIndex=1设置为保存一个备份文件。
    org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
    例如:log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    定义一个名为stdout的输出目的地,ConsoleAppender为控制台。
    ③、配置日志信息的格式布局Layout    Layout 负责格式化Appender的输出。
    其语法为:
    log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
    log4j.appender.appenderName.layout.option1 = value1

    log4j.appender.appenderName.layout.optionN = valueN
    其中,Log4j提供的layout有以下几种:
    org.apache.log4j.HTMLLayout(以HTML表格形式布局),
    org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
    org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
    org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
    格式化日志信息
    Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:
    %m 输出代码中指定的消息;
    %M 输出打印该条日志的方法名;
    %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL;
    %r 输出自应用启动到输出该log信息耗费的毫秒数;
    %c 输出所属的类目,通常就是所在类的全名;
    %t 输出产生该日志事件的线程名;
    %n 输出一个回车换行符,Windows平台为"rn”,Unix平台为"n”;
    %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy-MM-dd HH:mm:ss,SSS},输出类似:2002-10-18 22:10:28,921;
    %l 输出日志事件的发生位置,及在代码中的行数。

    另:log4j.appender.FILE.Threshold Threshold是个全局的过滤器,它将把低于所设置的level的信息过滤不显示出来。

    五、log4j.properties与log4j.xml

    log4j.properties配置文件,配置简单,但不支持复杂过滤器filter,log4j.xml虽然配置文件看似复杂,但支持复杂过滤器和Log4j的新特性。推荐使用log4j.xml

    1、路径问题:d:/log/abc.log   可以指定但分隔符是斜线   不是windows特有的反斜线
    2、如果在程序中使用log.setLevel(Level.DEBUG);设置了日志级别  会覆盖配置文件中配置的日志级别

    附上log4j.xml示例:

    <?xml version="1.0" encoding="UTF-8"?>     
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">     
            
    <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' >     
            
        <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">     
            <layout class="org.apache.log4j.PatternLayout">     
                <param name="ConversionPattern"        
                    value="[%d{dd HH:mm:ss,SSS} %-5p] [%t] %c{2} - %m%n" />     
            </layout>     
            <!--过滤器设置输出的级别-->     
            <filter class="org.apache.log4j.varia.LevelRangeFilter">     
                <param name="levelMin" value="debug" />     
                <param name="levelMax" value="warn" />     
                <param name="AcceptOnMatch" value="true" />     
            </filter>     
        </appender>     
         
        <appender name="myFile" class="org.apache.log4j.RollingFileAppender">        
            <param name="File" value="D:/output.log" /><!-- 设置日志输出文件名 -->     
            <!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->     
            <param name="Append" value="true" />     
            <param name="MaxBackupIndex" value="10" />     
            <layout class="org.apache.log4j.PatternLayout">     
                <param name="ConversionPattern" value="%p (%c:%L)- %m%n" />     
            </layout>     
        </appender>     
           
        <appender name="activexAppender" class="org.apache.log4j.DailyRollingFileAppender">     
            <param name="File" value="E:/activex.log" />       
            <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />       
            <layout class="org.apache.log4j.PatternLayout">     
             <param name="ConversionPattern"       
                value="[%d{MMdd HH:mm:ss SSS} %-5p] [%t] %c{3} - %m%n" />     
            </layout>       
        </appender>     
            
        <!-- 指定logger的设置,additivity指示是否遵循缺省的继承机制-->     
        <logger name="com.runway.bssp.activeXdemo" additivity="false">     
            <priority value ="info"/>       
            <appender-ref ref="activexAppender" />       
        </logger>     
         
        <!-- 根logger的设置-->     
        <root>     
            <priority value ="debug"/>     
            <appender-ref ref="myConsole"/>     
            <appender-ref ref="myFile"/>        
        </root>     
    </log4j:configuration>

    六、Log4j启动过程

    除了Log4j之外,还需要一个common-logging来协同进行日志记录。common-logging是一个日志的管理框架,具体的事情还是交由log4j来进行记录。

    源码:
    Logger getLogger(Class clazz)

     {   
           return LogManager.getLogger(clazz.getName());   
     }  

    转入LogManager,首先应该注意的是这个类的static块, 这个块其实就是一个加载log4j配置文件的过程。即在程序启动之初,在JVM需要加载这个类时,这个初始化块会自动运行,并且加载整个配置,以完成log4j的启动。
    Java代码  
    Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG));   
    ......   
    OptionConverter.selectAndConfigure(url, configuratorClassName,  LogManager.getLoggerRepository());  

    上面的所有代码均完成两件事,第一件事就是构造一个ROOT的Logger对象,此对象作为所有logger对象的最上层,其它logger的相应属性均从这个对象进行继承或改写,就好像java里的继承一样,这个类是内定的,不能由配置文件直接指定,且root都是在最顶层的,其他logger均在此下,这样形成一个完整的logger树。下层可以引用上层,上层管理下层。    第二件事则是去寻找配置文件的地址信息,通过各种方法都寻找log4j.xml或log4j.properties文件,然后对文件进行解析。(在此处,通过properties文件进行解析)
    Java代码  
    OptionConverter.void selectAndConfigure(URL url, String clazz, LoggerRepository hierarchy)  
    这个方法会最终通过指定的文件解析类(此处是PropertyConfigurator)进行解析,转入。

    Java代码  
    configurator.doConfigure(url, hierarchy)  
    这个方法将,url转化成一个properties对象,进行解析。
    Java代码  
    doConfigure(props, hierarchy); 进入这个方法
    Java代码  
    String value = properties.getProperty(LogLog.DEBUG_KEY);//即log4j.debug   
    if(value == null)    
    value = properties.getProperty("log4j.configDebug");   
    if(value != null)    
    LogLog.setInternalDebugging(OptionConverter.toBoolean(value, true));

      上面方法读取一个关于log4j自身的debug Level信息,主要用于log4j内部在解析时调用(因为log4j还不能使用logger对象进行写信息,它用到一个LogLog的类,来模拟logger记录,用于在自身解析的过程中输出一些信息),一般来说,这个都用不到。

    主要的信息集中在以下三句话:
    Java代码  
    configureRootCategory(properties, hierarchy);   
    configureLoggerFactory(properties);   
    parseCatsAndRenderers(properties, hierarchy);  
    configureRootCategory(properties, hierarchy);
    configureLoggerFactory(properties);
    parseCatsAndRenderers(properties, hierarchy);
     
    第一句话用于解析root根对象上的相关配置。
    第二句话用于解析loggerFactory(factory用于创建logger对象)
    第三句话用于解析除rootLogger之外的其他logger以及render信息。
    当然上面这个方法,即不是尽为rootLogger服务,对于其他logger也调用这个方法,故上面在解析Level时,对root作了单独判断(因为rootLogger的Level不能为空,至少均需要一个值)。处理Level,即将level值简单设置在logger上即可以了。
       接下来即解析appender信息,通过紧接着level后面的字符串,按列表方式进行解析,然后将appender加入logger的appenderList(即要进行信息处理的监听器表)中。进入parseAddpender(解析appender)即是解析appender对象,通过log4j.appender.X的前缀(X表示在rootLogger后的appender名称)来取得appender类名,并尝试实例化,然后根据appender来判断是否需要再解析appender的layout(即log4j.appender.X.layout这个键),解析并设置相应属性,最后分别解析appender本身的属性信息和layout的属性信息。(通过ProperSetter这个类,根据javaBean属性映射,将指定后缀后的信息当作一个键,后缀在属性文件中的值作为指定键的值,并将这个键值映射,通过javaBean设置到相应的对象上)至此,rootLogger即解析完毕。
    第二句:解析loggerFactory,略。
    第三句:解析其他logger信息。 
    至此,整个log4j的配置信息已经完成,而这个配置是由JVM保证线程化的(即只能被加载一次),在使用时整个配置已经加载成功,得到的已经是从配置信息中得到的logger对象了。


    七、Log4j加载配置文件位置的顺序:
    默认情况下,log4j 会自动加载classpath 中的配置文件。而且没有打包的log4j.properties 优先于大在jar 包中的log4j.properties 文件。

    加载顺序: 
    1  Trying to find [" + resource + "] using context classloader " + classLoader + "."       加载本工程中的配置文件
    2  Trying to find [" + resource + "] using " + classLoader + " class loader.          加载jar 包中的配置文件
    3   Trying to find [" + resource + "] using ClassLoader.getSystemResource().  加载系统类路径的配置文件

    八、日志级别三层过滤:根记录器,子记录器,Appender的Threshold配置级别

    所有包中都会使用logger.debug(),logger.info(),logger.warn(),logger.error()来设置不同级别的日志记录,那么什么样的日志才会被打印出来呢?

    按照日志记录过滤的顺序来看:根据记录器配置的级别,大于这个级别的将被记录,小于的过滤掉以后也不会被记录;

    主记录器设定的级别,如果对同一包配置子记录器,不管级别高低,子记录器级别会覆盖根记录器级别;

    然后Appender的Threshold配置级别,如果级别高于记录器级别 则按此级别输出,否则按记录器级别输出;

  • 相关阅读:
    Activiti系列——如何在eclipse中安装 Activiti Designer插件
    C语言 二维数组与指针笔记
    Ubuntu linux设置从当前目录下加载动态库so文件
    Ubuntu14.04安装nfs服务器
    Ubuntu14.04 搭建FTP服务器
    Linux备忘命令
    Java实现对xml文件的增删改查
    Java利用jacob实现打印Excel文件
    git操作列表
    swiper 窗口宽度变化,页面宽度高度变化 导致自动滑动 解决方案
  • 原文地址:https://www.cnblogs.com/cac2020/p/5225173.html
Copyright © 2011-2022 走看看