<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    風行天下

    JAVA太極
    posts - 4, comments - 10, trackbacks - 0, articles - 55
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    log4j分析- -

    Posted on 2005-04-01 10:27 風太少 閱讀(509) 評論(0)  編輯  收藏
     日志log4j的實現(xiàn)模式有人說是AOP,不過我不清楚,這里重點講述一下LOG4J.一些使用.同時當前版本 的LOG4J與以前的版本差別也是很大的,所以一定要清楚使用的LOG4J版本,這里所述以最新的為準。
             log4j有三種主要的組件記錄器,存放器,布局
     1、      記錄器(記錄器可不關心log數(shù)據(jù)存放的事喲)
      log4j允許程序員定義多個記錄器,每個記錄器有自己的名字,記錄器之間通過名字來表明隸屬關系(或家族關系)。列如,記錄器a.b,與記錄器a.b.c之間是父子關系,而記錄器a與a.b.c之間是祖先與后代的關系,父子關系是祖先與后代關系的特例。通過這種關系,可以描述不同記錄器之間的邏輯關系。
      有一個記錄器叫根記錄器,它永遠存在,且不能通過名字檢索或引用,可以通過Logger.getRootLogger()方法取得它,而一般記錄器通過Logger.getLogger(String name)方法。下面是Logger類的基本方法。
    package org.apache.log4j;

    public class Logger {

    // Creation & retrieval methods:
    public static Logger getRootLogger();
    public static Logger getLogger(String name);

    // printing methods:
    public void debug(Object message);
    public void info(Object message);
    public void warn(Object message);
    public void error(Object message);
    public void fatal(Object message);

    // generic printing method:
    public void log(Level l, Object message);
    }


      記錄器還有一個重要的屬性,就是級別。(這好理解,就象一個家庭中,成員間存在輩份關系,但不同的成員的身高可能不一樣,且身高與輩份無關)程序員可以給不同的記錄器賦以不同的級別,如果某個成員沒有被明確值,就自動繼承最近的一個有級別長輩的級別值。根記錄器總有級別值。例如:
    記錄器名 賦予的級別值 繼承的級別值
    root Proot Proot
    X Px Px
    X.Y none Px
    X.Y.Z none Px

      程序員可以自由定義級別。級別值之間存在偏序關系,如上面幾種級別就有關系DEBUG   每一條要輸出的log信息,也有一個級別值。
      前面的Logger類中,就預定義了 DEBUG, INFO, WARN, ERROR ,F(xiàn)ATAL幾種級別,由于與方法綁定,讓人易產(chǎn)生誤解,其實這幾個方法只不過表明了要記錄的log信息的級別。當調(diào)用log()方法時,log信息的級別就需要在通過參數(shù)明確指定。
      如果一條log信息的級別,大于等于記錄器的級別值,那么記錄器就會記錄它。如果你覺得難以理解,可參考下例。
       // get a logger instance named "com.foo"
       Logger  logger = Logger.getLogger("com.foo");

       // Now set its level. Normally you do not need to set the
       // level of a logger programmatically. This is usually done
       // in configuration files.
       logger.setLevel(Level.INFO);

       Logger barlogger = Logger.getLogger("com.foo.Bar");

       // This request is enabled, because WARN >= INFO.
       logger.warn("Low fuel level.");

       // This request is disabled, because DEBUG < INFO.
       logger.debug("Starting search for nearest gas station.");

       // The logger instance barlogger, named "com.foo.Bar",
       // will inherit its level from the logger named
       // "com.foo" Thus, the following request is enabled
       // because INFO >= INFO.
       barlogger.info("Located nearest gas station.");

       // This request is disabled, because DEBUG < INFO.
       barlogger.debug("Exiting gas station search");


      有幾個有趣的情況,一是當一個記錄器實例化后,再一次用相同的名字調(diào)用getLogger()會返回對它的引用,這非常有利于用同一個記錄器在不同代碼或類中記錄log信息,另一個是與自然界中祖先先于后代出現(xiàn)不同,一個記錄器的祖先可以比后代記錄出現(xiàn)的晚,但會自動根據(jù)名字之間的關系建立這種家族關系。

    2、存放器
      在log4j中,log信息通過存放器輸出到目的地。支持的存放器有console, files, GUI components, remote socket servers, JMS, NT Event Loggers, remote UNIX Syslog daemons。通過file存放器,log信息可以被輸出到不同的文件中(即不同的目的地)。log信息可被異步存放。
      一個記錄器可以有多個存放器,可以通過方法addAppender來增加存放器。一條blog信息如果可被這個記錄器處理,則記錄器會把這條信息送往每個它所擁有的存放器。
      每個記錄器有一個繼承開關,其開關決定記錄器是/否繼承其父記錄器的存放器,注意,如果繼承則只繼承其父記錄器,而不考慮更遠的祖先的情況。參考下表:
    記錄器 增加的存放器 繼承的存放器 輸出的目的地 備注
    root A1 not applicable A1 The root logger is anonymous but can be accessed with the Logger.getRootLogger() method. There is no default appender attached to root.
    x A-x1, A-x2 TRUE A1, A-x1, A-x2 Appenders of "x" and root.
    x.y none TRUE A1, A-x1, A-x2 Appenders of "x" and root.
    x.y.z A-xyz1 TRUE A1, A-x1, A-x2, A-xyz1 Appenders in "x.y.z", "x" and root.
    security A-sec FALSE A-sec No appender accumulation since the additivity flag is set to false.
    security.access none TRUE A-sec Only appenders of "security" because the additivity flag in "security" is set to false.
      
      
    3、布局
      布局負責格式化輸出的log信息。log4j的PatternLayout可以讓程序以類似C語言printf的格式化模板來定義格式。

    4、log4j可據(jù)程序員制定的標準自動提供一些log信息,這對那類需要頻繁log的對象的情況很幫助。對象的自動log,具有繼承性

    前面主要記了一些原理,今天是實務。

    1、研究發(fā)現(xiàn),一個系統(tǒng)中4%的代碼是用來作logging的。
    2、Log4J的配置文件(Configuration File)就是用來設置記錄器的級別、存放器和布局的,它可接key=value格式的設置或xml格式的設置信息。通過配置,可以創(chuàng)建出Log4J的運行環(huán)境。
      Log4J運行時,不對環(huán)境做任何假定,尤其是沒有默認的存放器。
    3、有幾種方式可以配置Log4J
    1)在程序中調(diào)用BasicConfigurator.configure()方法;
    2)配置放在文件里,通過命令行參數(shù)傳遞文件名字,通過PropertyConfigurator.configure(args[x])解析并配置;
    3)配置放在文件里,通過環(huán)境變量傳遞文件名等信息,利用log4j默認的初始化過程解析并配置;
    4)配置放在文件里,通過應用服務器配置傳遞文件名等信息,利用一個特殊的servlet來完成配置。
    看下面的例子:

    import com.foo.Bar;
    // Import log4j classes.
    import org.apache.log4j.Logger;
    import org.apache.log4j.BasicConfigurator;
    public class MyApp {
    // Define a static logger variable so that it references the
    // Logger instance named "MyApp".
    static Logger logger = Logger.getLogger(MyApp.class);
    public static void main(String[] args) {
    // Set up a simple configuration that logs on the console.
    BasicConfigurator.configure();
    logger.info("Entering application.");
    Bar bar = new Bar();
    bar.doIt();
    logger.info("Exiting application.");
    }
    }


     

     package com.foo;
    import org.apache.log4j.Logger;

    public class Bar {
    static Logger logger = Logger.getLogger(Bar.class);
    public void doIt() {
    logger.debug("Did it again!");
    }
    }


      BasicConfigurator.configure給根記錄器增加一個ConsoleAppender,輸出格式通過PatternLayout設為"%-4r [%t] %-5p %c %x - %m%n",還有根記錄器的默認級別是Level.DEBUG.
      記錄器之間的關系如下圖:
      

    log4jexample.gif


      輸出結(jié)果如下:

    0 [main] INFO MyApp - Entering application.
    36 [main] DEBUG com.foo.Bar - Did it again!
    51 [main] INFO MyApp - Exiting application.


      下面的代碼結(jié)合配置信息,會得到與上述程序一樣的結(jié)果。

    import com.foo.Bar;
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    public class MyApp {
    static Logger logger = Logger.getLogger(MyApp.class.getName());
    public static void main(String[] args) {
    // BasicConfigurator replaced with PropertyConfigurator.
    PropertyConfigurator.configure(args[0]);
    logger.info("Entering application.");
    Bar bar = new Bar();
    bar.doIt();
    logger.info("Exiting application.");
    }
    }

    配置文件的內(nèi)容如下:

    # Set root logger level to DEBUG and its only appender to A1.
    log4j.rootLogger=DEBUG, A1

    # A1 is set to be a ConsoleAppender.
    log4j.appender.A1=org.apache.log4j.ConsoleAppender

    # A1 uses PatternLayout.
    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
    log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

    利用配置文件,可以很方便地修改配置。如下例

    log4j.rootLogger=debug, stdout, R

    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

    # Pattern to output the caller's file name and line number.
    #log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
    # Print the date in ISO 8601 format
    log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

    log4j.appender.R=org.apache.log4j.RollingFileAppender
    log4j.appender.R.File=example.log

    log4j.appender.R.MaxFileSize=100KB
    # Keep one backup file
    log4j.appender.R.MaxBackupIndex=1

    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

    # Print only messages of level WARN or above in the package com.foo.
    log4j.logger.com.foo=WARN


    對于tomcat4,利用環(huán)境變量傳遞參數(shù)的,可參見以下幾個例子


    unix設置
    export CATALINA_OPTS ="-Dlog4j.configuration=foobar.txt"<===用PropertyConfigurator解析
    export CATALINA_OPTS ="-Dlog4j.debug -Dlog4j.configuration=foobar.xml"<===用DOMConfigurator解析
    以下是windows設置
    set CATALINA_OPTS =-Dlog4j.configuration=foobar.lcf -Dlog4j.configuratorClass=com.foo.BarConfigurator<===用com.foo.BarConfigurator解析
    set CATALINA_OPTS =-Dlog4j.configuration=file:/c:/foobar.lcf

    配置文件位置如果沒有明確指明,則要放在WEB-INF/classes目錄下。
    4、用servlet配置log4j
    以下都是參考冰之火的文章,抄來放在這兒,并做了一些必要的修改。需要說明的是,下面的代碼需要自己寫并發(fā)布,下的jar中沒有這個類。待我以后寫一個,也放上來。我也寫了兩個,在筆記(三)中。
    在Application目錄下的web.xml文件加入以后代碼

      <servlet>
    <servlet-name>log4jlog4j-init</servlet-name>
    <servlet-class>com.apache.jakarta.log4j.Log4jInit</servlet-class>
    <init-param>
    <param-name>log4j</param-name>
    <param-value>/WEB-INF/log4j.properties</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>


    這段代碼的意思是說,在Tomcat啟動時加載com.apache.jakarta.log4j.Log4jInit這個名叫Log4jInit.class這個類文件。
    其中Log4jInit.class的源代碼如下

     
    package com.apache.jakarta.log4j;
    import org.apache.log4j.PropertyConfigurator;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class Log4jInit extends HttpServlet {

    public void init() {
    String prefix = getServletContext().getRealPath("/");
    String file = getInitParameter("log4j");
    // if the log4j-init-file is not set, then no point in trying
    System.out.println("................log4j start");
    if(file != null) {
    PropertyConfigurator.configure(prefix+file);
    }
    }
    public void doGet(HttpServletRequest req, HttpServletResponse res) {
    }
    }


    在加載的過程中,程序會讀取/WEB-INF/log4j.properties這個文件。
    配置文件講解如下:

    # Set root logger level to DEBUG and its only appender to A1
    #log4j中有五級logger
    #FATAL 0
    #ERROR 3
    #WARN 4
    #INFO 6
    #DEBUG 7
    #配置根Logger,其語法為:
    #log4j.rootLogger = [ level ] , appenderName, appenderName, …
    log4j.rootLogger=INFO, A1 ,R
    #這一句設置以為著所有的log都輸出
    #如果為log4j.rootLogger=WARN, 則意味著只有WARN,ERROR,FATAL
    #被輸出,DEBUG,INFO將被屏蔽掉.
    # A1 is set to be a ConsoleAppender.
    #log4j中Appender有幾層如控制臺、文件、GUI組件、甚至是套接口服務器、NT的事件記錄器、UNIX Syslog守護進程等
    #ConsoleAppender輸出到控制臺
    log4j.appender.A1=org.apache.log4j.ConsoleAppender
    # A1 使用的輸出布局,其中l(wèi)og4j提供4種布局. org.apache.log4j.HTMLLayout(以HTML表格形式布局)
    #org.apache.log4j.PatternLayout(可以靈活地指定布局模式),
    #org.apache.log4j.SimpleLayout(包含日志信息的級別和信息字符串),
    #org.apache.log4j.TTCCLayout(包含日志產(chǎn)生的時間、線程、類別等等信息)

    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
    #靈活定義輸出格式 具體查看log4j javadoc org.apache.log4j.PatternLayout
    #d 時間 ....
    log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
    #R 輸出到文件 RollingFileAppender的擴展,可以提供一種日志的備份功能。
    log4j.appender.R=org.apache.log4j.RollingFileAppender
    #日志文件的名稱
    log4j.appender.R.File=log4j.log
    #日志文件的大小
    log4j.appender.R.MaxFileSize=100KB
    # 保存一個備份文件
    log4j.appender.R.MaxBackupIndex=1

    log4j.appender.R.layout=org.apache.log4j.TTCCLayout
    #log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n


    配置根Logger,其語法為:

    log4j.rootLogger = [ level ] , appenderName, appenderName, ...


    level 是日志記錄的優(yōu)先級
    appenderName就是指定日志信息輸出到哪個地方。您可以同時指定多個輸出目的地。

    配置日志信息輸出目的地Appender,其語法為

    log4j.appender.appenderName = fully.qualified.name.of.appender.class
    log4j.appender.appenderName.option1 = value1
    ...
    log4j.appender.appenderName.option = valueN


    Log4j提供的appender有以下幾種:
    org.apache.log4j.ConsoleAppender(控制臺),
    org.apache.log4j.FileAppender(文件),
    org.apache.log4j.DailyRollingFileAppender(每天產(chǎn)生一個日志文件),
    org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產(chǎn)生一個新的文件),
    org.apache.log4j.WriterAppender(將日志信息以流格式發(fā)送到任意指定的地方)

    配置日志信息的格式(布局),其語法為:

    log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
    log4j.appender.appenderName.layout.option1 = value1
    ....
    log4j.appender.appenderName.layout.option = valueN


    Log4j提供的layout有以下幾種:
    org.apache.log4j.HTMLLayout(以HTML表格形式布局),
    org.apache.log4j.PatternLayout(可以靈活地指定布局模式),
    org.apache.log4j.SimpleLayout(包含日志信息的級別和信息字符串),
    org.apache.log4j.TTCCLayout(包含日志產(chǎn)生的時間、線程、類別等等信息)




    簡單的Log4j使用只需要導入下面的包就可以了
    // import log4j packages
    import org.apache.log4j.Logger;

    然后你需要在類的開頭寫上下面一句
    private final static Logger log =
    Logger.getLogger(ClassName.class);//注意這里寫的是當前類的類名。
    這樣你就有了一個日志對象叫做 log,這個log有以下集中用法
    log.info();//一般信息
    log.debug();//調(diào)試信息
    log.error();//錯誤信息
    log.warn();//警告信息
    log.fatal();//致命錯誤信息
    上面列出的就是所謂log4j的輸出級別,log4j建議只使用4個級別,它們從上到下分別為
    ERROR、WARN、INFO、DEBUG,假設你定義的級別是info,那么error和warn的日志可以顯示而比他低的debug信息就不顯示了。
    知道了上面的內(nèi)容還不夠,要想很好的使用log4j你還需要配置log4j的環(huán)境。因為每個log都可以通過配置它的屬性文件來達到控制日志輸出的格式的目的,下面我給出一個在weblogic下使用log4j的配置過程,首先給出這個配置文件的完整信息。

    #log4j.rootLogger=INFO,A1,R //這一句指定了日志輸出的級別為info,A1和R分別代表日志輸出到什么地方。
    log4j.category.hybl_wshabcm=debug,A1,R //這一句指定了日志具體輸出哪個包的信息,以及輸出位置
    log4j.appender.A1=org.apache.log4j.ConsoleAppender //這里指定了日志輸出的第一個位置A1是控制臺ConsoleAppender
    /*
    *其中,Log4j提供的appender有以下幾種:
    *org.apache.log4j.ConsoleAppender(控制臺),
    *org.apache.log4j.FileAppender(文件),
    *org.apache.log4j.DailyRollingFileAppender(每天產(chǎn)生一個日志文件),
    *org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產(chǎn)生一個新的文件),
    *org.apache.log4j.WriterAppender(將日志信息以流格式發(fā)送到任意指定的地方)
    *
    */
    log4j.appender.A1.layout=org.apache.log4j.PatternLayout //指定A1的布局模式

    /*
    *其中,Log4j提供的layout有以下幾種:
    ×org.apache.log4j.HTMLLayout(以HTML表格形式布局),
    *org.apache.log4j.PatternLayout(可以靈活地指定布局模式),
    *org.apache.log4j.SimpleLayout(包含日志信息的級別和信息字符串),
    *org.apache.log4j.TTCCLayout(包含日志產(chǎn)生的時間、線程、類別等等信息)
    */
    log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n //指定日志的輸出格式


    log4j.appender.R=org.apache.log4j.RollingFileAppender //指定以文件的方式輸出日志
    log4j.appender.R.File=c:/sys.html //文件位置
    log4j.appender.R.MaxFileSize=500KB //文件最大尺寸
    log4j.appender.R.MaxBackupIndex=1 //備份數(shù)
    log4j.appender.R.layout=org.apache.log4j.HTMLLayout //文件的格式為Html格式
    #log4j.appender.R.layout=org.apache.log4j.PatternLayout
    log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n


    有了上面的這個文件我們還要在weblogic啟動的時候通過一個類加載這個文件,可以使用下面的方式
    1、加載配置文件的Servlet

    package hybl_wshabcm.servelet;

    import java.io.File;
    import java.io.LineNumberReader;
    import java.io.FileReader;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.Vector;
    import java.sql.Driver;
    import java.sql.DriverManager;

    // import servlet packages
    import javax.servlet.http.HttpServlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;

    // import log4j packages
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    public class SetupServlet extends HttpServlet{

    public void init(ServletConfig config) throws ServletException{

    super.init(config);

    // first thing to do, is to set up the Driver that we might be using
    // in case of JDBCAppender
    try{
    Driver d =
    (Driver)(Class.forName(
    "org.gjt.mm.mysql.Driver").newInstance());
    DriverManager.registerDriver(d);
    //加載JDBC驅(qū)動程序,當準備將日志記錄到數(shù)據(jù)庫的時候可以使用
    }catch(Exception e){ System.err.println(e); }

    // next load up the properties
    //啟動時從web.xml中獲得配置文件的信息
    String props = config.getInitParameter("props");

    if(props == null || props.length() == 0 ||
    !(new File(props)).isFile()){

    System.err.println(
    "ERROR: Cannot read the configuration file. " +
    "Please check the path of the config init param in web.xml");
    throw new ServletException();
    }
    }

    public void destroy(){
    super.destroy();
    }
    }

    2、web.xml文件的部署
    上面的這個Servlet在服務器啟動的時候?qū)⒁恍┏跏蓟畔⒓虞d,那么如何在weblogic啟動的時候?qū)⑦@個類也
    加載呢?看一個例子

    setup
    hybl_wshabcm.servelet.SetupServlet//啟動時裝載的類

    props
    /WEB-INF/log4j.properties//部署文件的位置

    2//這句很重要

    好了,現(xiàn)在你可以象開頭那樣使用log4j來記錄日志了


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    主站蜘蛛池模板: 免费无码H肉动漫在线观看麻豆| 免费看一级一级人妻片| 亚洲欧洲日产国码久在线| 亚洲AV无码专区国产乱码不卡| 国产成人亚洲综合无| 一级美国片免费看| 在线观看肉片AV网站免费| 18未年禁止免费观看| 我要看WWW免费看插插视频| mm1313亚洲精品无码又大又粗| 国产亚洲精品久久久久秋霞| 911精品国产亚洲日本美国韩国| 亚洲中文字幕久久精品无码VA| 天堂亚洲免费视频| 暖暖免费日本在线中文| 久久精品a一国产成人免费网站 | 久久国产乱子伦精品免费不卡| 欧洲一级毛片免费| 免费精品国产自产拍观看| 亚洲一区爱区精品无码| 亚洲最新黄色网址| 美女扒开屁股让男人桶爽免费| 日韩插啊免费视频在线观看 | 亚洲无线一二三四区手机| 亚洲成a人片在线观看无码| 亚洲五月丁香综合视频| 免费无码婬片aaa直播表情| 日本免费大黄在线观看| 狼友av永久网站免费观看| 亚洲狠狠婷婷综合久久久久| 亚洲一区二区三区乱码在线欧洲| 国产va免费观看| 日本在线高清免费爱做网站| 亚洲午夜无码片在线观看影院猛| 亚洲性无码av在线| 一个人看的www在线免费视频 | 国产一级高青免费| 动漫黄网站免费永久在线观看| 久久精品国产亚洲7777| 亚洲中文字幕久在线| 拍拍拍无挡免费视频网站|