JAVA

          人生若只如初見,何事秋風(fēng)悲畫扇。

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            50 隨筆 :: 25 文章 :: 157 評(píng)論 :: 0 Trackbacks

           

             由于自己工作性質(zhì)發(fā)生了些變化,人隨境遷,回首時(shí),發(fā)現(xiàn)真的是歲月如梭,時(shí)光如水。彈指間,從研發(fā)到維護(hù),從總部到出差已經(jīng)是四月有余了。

          在維護(hù)系統(tǒng)時(shí),難免會(huì)時(shí)不時(shí)地跟代碼再次打些交道。今天想再操刀做個(gè)小工具時(shí),居然不太記得了log4j的配置,不得不從apache再重新down了相關(guān)的jarDOC,匆匆看看了一下,快點(diǎn)寫下來(lái),日后肯定還用得著,同時(shí)也希望對(duì)網(wǎng)友們有用。 

          Log4j基本上已經(jīng)是java里的首選日志工具了,它主要由三部分組成:Loggers, AppendersLayouts (注意后面都加了s啦,顧名思義一個(gè)配置中可以分別允許有多個(gè)此類對(duì)象存在,后面將詳細(xì)介紹)
              Loggers
          -用來(lái)定義日志消息的類型及級(jí)別;
             Appenders
          -用來(lái)定義日志消息的輸出終端;
             Layouts
          -用來(lái)定義日志消息的輸出格式。

          Logger

          Loggers層次:  
          對(duì)logger的名字是大小寫敏感。

          規(guī)則-如果類P的名字是另一個(gè)類C的名字的前綴,且PC之間以“.”號(hào)連接起來(lái),那么稱P為祖先層次;如果層次A與其子層次之間沒有任何父層次,則認(rèn)為層次A為父層次。

              例如,org.apache.log4jorg.apache.log4j.Logger的父層次;而org.apacheorg.apache.log4jorg.apache.log4j.Logger的祖先層次。

             
          另外,注意log4j中有個(gè)默認(rèn)的root級(jí)別的logger,在所有logger中,它是最高級(jí)別,其它所有logger均繼承于rootroot有以下二個(gè)特性:
             
          1. 它總是存在的。
              2.
          它不能通過名字直接獲取其實(shí)例(root實(shí)例可以通過類Logger的靜態(tài)方法Logger.getRootLogger獲得,而其它logger則可以直接通過名字來(lái)獲取Logger.getLogger)

              關(guān)于Loggers中的級(jí)別:

              對(duì)每個(gè)logger,可以指定其級(jí)別,在系統(tǒng)org.apache.log4j.Level中,已經(jīng)定義了五個(gè)級(jí)別,分別為debug, info, warn, error, fatal

          規(guī)則-設(shè)當(dāng)前loggerX,從X開始往X的父類方向開始算(包括X本身),直到名為rootlogger,第一個(gè)不為null的級(jí)別值就是X的級(jí)別值。

              日志顯示:  
          級(jí)別的定義是為了過濾性地選擇日志。

          規(guī)則-若當(dāng)前請(qǐng)方式級(jí)別為P,而當(dāng)前的logger的級(jí)別為Q,當(dāng)且僅當(dāng)在P>=Q的情況下,日志信息才能顯示。

             
          關(guān)于日志中級(jí)別的關(guān)系為:DEBUG < INFO < WARN < ERROR < FATAL
              
          關(guān)于此規(guī)則的說(shuō)明,有以下代碼為實(shí)例:

          // 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");

           

          AppendersLayouts

          Appender正如前面所述,是用來(lái)定義日志信息的輸出終端,最覺的輸出終端有consolefile了,另外還有其它如GUI components, JMS, NT Event Loggers, remote socket servers等等。
              Appender
          也有類似繼承的原則,即當(dāng)前loggerappender包括其它父類的appender。這樣就會(huì)出現(xiàn)一個(gè)logger可能擁有多個(gè)appender了,在現(xiàn)實(shí)中看來(lái),就是log4j的日志信息可以同進(jìn)輸出到console, file等等終端了。當(dāng)然,為了不使此appender惡性疊加,可以通過設(shè)置additivity標(biāo)志來(lái)阻止繼承。

          規(guī)則-若當(dāng)前loggerC,則C擁有包括其自己及其父類的所有appender。另外,若C的父loggerP,且Padditivity標(biāo)志已經(jīng)設(shè)置成為false,則C只擁有自己及Pappender了,而P則只能擁有本身的appender


              以下表格可以清晰說(shuō)明此規(guī)則:    

          Logger
          Name

          Added
          Appenders

          Additivity
          Flag

          Output Targets

          Comment

          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.

             
             
           
              
          對(duì)于layout,也正如前面所述,是用來(lái)定義日志信息的輸出格式,它的與C語(yǔ)言中printf函數(shù)的格式定義基本相似,本人對(duì)printf中的格式參數(shù)不太熟悉,總感覺有些復(fù)雜,一般是平時(shí)看到自己認(rèn)為有用的格式就記一下,到時(shí)直接搬過來(lái)。如

          log4j.appender.R.layout.ConversionPattern=--->%-d{yyyy-MM-dd HH:mm:ss} [%5p]%l - %m%n

          時(shí),日志信息格式為:
          --->2008-07-11 01:13:40 [ INFO]com.test.Log4jTest.main(Log4jTest.java:27) - Exiting application.
             
          好啦,現(xiàn)在log4j的理論很膚淺地扯了一下,現(xiàn)在可以開始配置了。

              配置: 

              Log4j
          的配置可以通過加載Javaproperties配置文件或者XML文件來(lái)完成。
              Log4j
          默認(rèn)的配置為,通過讀取系統(tǒng)變量log4j.configuration來(lái)找到配置文件,當(dāng)然變量的默認(rèn)值為log4j.properties,所以若沒有設(shè)置此系統(tǒng)變量,可以直接將配置文件命名為log4j.properties,然后放到類路徑下即可。另外,若想引用通過其它配置文件,則可以通過

              Loader.getResource(java.lang.String)來(lái)讀取指定的配置文件。

              其它:

              1. 由于有了log4j中的級(jí)別繼承機(jī)制,所以可以很方便地過濾信息了,不僅可以很方便地限制日志的輸出量,也可以同時(shí)將日志輸出到不同的終端。
              
          另外,因?yàn)樵?span lang="EN-US">java
          文件中,文件的物理層次關(guān)系也是直接通過“.”符號(hào)來(lái)控制的,且在很在程度上這個(gè)物理層次也決定了文件的邏輯層次,所以我們?cè)诋?dāng)前文件中獲取logger時(shí),可以直接通過當(dāng)前文件的類名來(lái)獲取,如:
              
              static Logger logger = Logger.getLogger(MyApp.class);
              
          這樣,在過濾消息時(shí)就很簡(jiǎn)單了,簡(jiǎn)單示例如下:
              
          在配置文件中有
              log4j.rootLogger=ERROR,stdout,R
              log4j.category.com.db=DEBUG
              log4j.category.com.i18n=INFO
              log4j.category.com.zyx=fatal

              默認(rèn)的root logger的日志級(jí)別為Error,根據(jù)級(jí)別關(guān)系這個(gè)級(jí)別也相當(dāng)高了,這樣可以減少系統(tǒng)中日志的輸出量,但有些地方可能得輸出更詳細(xì)信息,如數(shù)據(jù)庫(kù)部分,所以可以將com.db設(shè)置成了debug。另外,我在com.zyx下,我只想看到類型為fatal的日志,也可以如上所設(shè)。

              2. log4j.rootLogger=ERROR,stdout, ROLLING_FILE這個(gè)定義表示root logger的日志級(jí)別為Error,后面的stdout, ROLLING_FILE表示此root有二個(gè)appender,通常可以通過這樣來(lái)定義日志可以同時(shí)向多個(gè)終端輸出,因?yàn)樽?span lang="EN-US">logger可以繼承所有父loggerappender.

              如我可以通過以下定義將日志同時(shí)往consolefile輸出:

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

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

          log4j.appender.stdout.layout.ConversionPattern=--->%-d{yyyy-MM-dd HH:mm:ss} [%5p]%l - %m%n

           

          log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender

          log4j.appender.ROLLING_FILE.File=myapp.log

          log4j.appender.ROLLING_FILE.Append=true

          log4j.appender.ROLLING_FILE.MaxFileSize=1024KB

          log4j.appender.ROLLING_FILE.MaxBackupIndex=10

          log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout

          log4j.appender.ROLLING_FILE.layout.ConversionPattern==[slf5s.start]%d{DATE}[slf5s.DATE]%n\

             %p[slf5s.PRIORITY]%n%x[slf5s.NDC]%n%t[slf5s.THREAD]%n\

             %c[slf5s.CATEGORY]%n%l[slf5s.LOCATION]%n%m[slf5s.MESSAGE]%n%n

           

             

          實(shí)例

          log4j.properties配置文件:

          #defineroot logger and it's appdenders

          log4j.rootLogger=debug,R,stdout

          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

          log4j.appender.R=org.apache.log4j.RollingFileAppender

          log4j.appender.R.File=myapp.log

          log4j.category.R=error

          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

          log4j.appender.R.layout=org.apache.log4j.PatternLayout

          log4j.appender.R.layout.ConversionPattern=--->%-d{yyyy-MM-ddHH:mm:ss}[%5p]%l-%m%n

          Java測(cè)試文件:

          packagecom.zyx.test;

          importorg.apache.log4j.Logger;

          publicclassLog4jTest {

          staticLoggerlogger= Logger.getLogger(Log4jTest.class.getName());

          publicstaticvoidmain(String[] args) {

          logger.debug("Welcometo by blog blgjava.net/jkallen");

          logger.info("Exitingapplication.");

          System.out.print("over");

          }

          }

          運(yùn)行后控制臺(tái)輸出:

          DEBUG [main](Log4jTest.java:9) - Welcome to by blogblgjava.net/jkallen

           INFO [main] (Log4jTest.java:10) - Exitingapplication.

          over

          運(yùn)行后日志文件輸出:

          --->2008-07-1115:46:24 [DEBUG]com.test.Log4jTest.main(Log4jTest.java:9) - Welcome to by blogblgjava.net/jkallen

           --->2008-07-11 15:46:24 [INFO]com.test.Log4jTest.main(Log4jTest.java:10) - Exitingapplication.



          馬馬虎虎總結(jié)了一下,但也花費(fèi)了近三個(gè)小時(shí),支持下!

              參考:log4j DOC

           

          posted on 2008-07-11 07:42 Jkallen 閱讀(1991) 評(píng)論(2)  編輯  收藏 所屬分類: 其它開源

          評(píng)論

          # re: 再次握手log4j[未登錄] 2008-08-02 01:18 moonandsun
          支持!  回復(fù)  更多評(píng)論
            

          # re: 再次握手log4j[未登錄] 2008-08-21 06:24 ol_l
          值得收藏  回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 洪江市| 右玉县| 安西县| 深圳市| 玉溪市| 乡城县| 莱州市| 城固县| 锡林郭勒盟| 光山县| 浦城县| 乐业县| 兴海县| 获嘉县| 孝感市| 沭阳县| 丹巴县| 汨罗市| 汶上县| 富裕县| 扶风县| 同仁县| 封开县| 长岭县| 原平市| 页游| 库尔勒市| 论坛| 邓州市| 海淀区| 恩施市| 陇南市| 利辛县| 伊通| 铜陵市| 民勤县| 阜阳市| 晴隆县| 棋牌| 霍林郭勒市| 石家庄市|