注銷

          注銷

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            112 隨筆 :: 7 文章 :: 18 評(píng)論 :: 0 Trackbacks

          1 簡介

          1.1 Log4net的優(yōu)點(diǎn):

          幾乎所有的大型應(yīng)用都會(huì)有自己的用于跟蹤調(diào)試的API。因?yàn)橐坏┏绦虮徊渴鹨院螅筒惶赡茉倮脤iT的調(diào)試工具了。然而一個(gè)管理員可能需要有一套強(qiáng)大的日志系統(tǒng)來診斷和修復(fù)配置上的問題。

          經(jīng)驗(yàn)表明,日志記錄往往是軟件開發(fā)周期中的重要組成部分。它具有以下幾個(gè)優(yōu)點(diǎn):它可以提供應(yīng)用程序運(yùn)行時(shí)的精確環(huán)境,可供開發(fā)人員盡快找到應(yīng)用程序中的Bug;一旦在程序中加入了Log 輸出代碼,程序運(yùn)行過程中就能生成并輸出日志信息而無需人工干預(yù)。另外,日志信息可以輸出到不同的地方(控制臺(tái),文件等)以備以后研究之用。

          Log4net就是為這樣一個(gè)目的設(shè)計(jì)的,用于.NET開發(fā)環(huán)境的日志記錄包。

          1.2 Log4net的安裝:

          用戶可以從http://logging.apache.org/log4net/下載log4net的源代碼。解壓軟件包后,在解壓的src目錄下將log4net.sln載入Visual Studio .NET,編譯后可以得到log4net.dll。用戶要在自己的程序里加入日志功能,只需將log4net.dll引入工程即可。??

          2 ?Log4net的結(jié)構(gòu)

          log4net 有四種主要的組件,分別是Logger(記錄器), Repository(庫), Appender(附著器)以及 Layout(布局).

          2.1 Logger

          2.1.1 Logger接口

          Logger是應(yīng)用程序需要交互的主要組件,它用來產(chǎn)生日志消息。產(chǎn)生的日志消息并不直接顯示,還要預(yù)先經(jīng)過Layout的格式化處理后才會(huì)輸出。

          Logger提供了多種方式來記錄一個(gè)日志消息,你可以在你的應(yīng)用程序里創(chuàng)建多個(gè)Logger,每個(gè)實(shí)例化的Logger對象都被log4net框架作為命名實(shí)體(named entity)來維護(hù)。這意味著為了重用Logger對象,你不必將它在不同的類或?qū)ο箝g傳遞,只需要用它的名字為參數(shù)調(diào)用就可以了。log4net框架使用繼承體系,繼承體系類似于.NET中的名字空間。也就是說,如果有兩個(gè)logger,分別被定義為a.b.c和a.b,那么我們說a.b是a.b.c的祖先。每一個(gè)logger都繼承了祖先的屬性

          Log4net框架定義了一個(gè)ILog接口,所有的logger類都必須實(shí)現(xiàn)這個(gè)接口。如果你想實(shí)現(xiàn)一個(gè)自定義的logger,你必須首先實(shí)現(xiàn)這個(gè)接口。你可以參考在/extension目錄下的幾個(gè)例子。

          ILog接口的定義如下:

          public interface ILog

          {

          ? void Debug(object message);

          ? void Info(object message);

          ? void Warn(object message);

          ? void Error(object message);

          ? void Fatal(object message);

          //以上的每一個(gè)方法都有一個(gè)重載的方法,用來支持異常處理。

          //每一個(gè)重載方法都如下所示,有一個(gè)異常類型的附加參數(shù)。

          ? void Debug(object message, Exception ex);

          ? // ...

          //Boolean 屬性用來檢查Logger的日志級(jí)別

          //(我們馬上會(huì)在后面看到日志級(jí)別)

          ? bool isDebugEnabled;
          ? bool isInfoEnabled;

          ? //… 其他方法對應(yīng)的Boolean屬性

          }

          Log4net框架定義了一個(gè)叫做LogManager的類,用來管理所有的logger對象。它有一個(gè)GetLogger()靜態(tài)方法,用我們提供的名字參數(shù)來檢索已經(jīng)存在的Logger對象。如果框架里不存在該Logger對象,它也會(huì)為我們創(chuàng)建一個(gè)Logger對象。代碼如下所示:

          log4net.ILog log = log4net.LogManager.GetLogger("logger-name");

          通常來說,我們會(huì)以類(class)的類型(type)為參數(shù)來調(diào)用GetLogger(),以便跟蹤我們正在進(jìn)行日志記錄的類。傳遞的類(class)的類型(type)可以用typeof(Classname)方法來獲得,或者可以用如下的反射方法來獲得:

          System.Reflection.MethodBase.GetCurrentMethod().DeclaringType

          盡管符號(hào)長了一些,但是后者可以用于一些場合,比如獲取調(diào)用方法的類(class)的類型(type)。

          2.1.2???? 日志的級(jí)別

          正如你在ILog的接口中看到的一樣,有五種不同的方法可以跟蹤一個(gè)應(yīng)用程序。事實(shí)上,這五種方法是運(yùn)作在Logger對象設(shè)置的不同日志優(yōu)先級(jí)別上。這幾種不同的級(jí)別是作為常量定義在log4net.spi.Level類中。你可以在程序中使用任何一種方法。但是在最后的發(fā)布中你也許不想讓所有的代碼來浪費(fèi)你的CPU周期,因此,框架提供了7種級(jí)別和相應(yīng)的Boolean屬性來控制日志記錄的類型。

          ?Level有以下幾種取值

          級(jí)別

          允許的方法

          Boolean 屬性

          優(yōu)先級(jí)別

          OFF

          Highest

          FATAL

          void Fatal(...);

          bool IsFatalEnabled;

          ?

          ?

          RROR

          void Error(...);

          bool IsErrorEnabled;

          ?

          ?

          WARN

          void Warn(...);

          bool IsWarnEnabled;

          ?

          ?

          INFO

          void Info(...);

          bool IsInfoEnabled;

          ?

          ?

          DEBUG

          void Debug(...);

          bool IsDebugEnabled;

          ?

          ?

          ALL

          ?

          ?

          Lowest

          1? Logger 的日志級(jí)別??

          ? 在log4net框架里,通過設(shè)置配置文件,每個(gè)日志對象都被分配了一個(gè)日志優(yōu)先級(jí)別。如果沒有給一個(gè)日志對象顯式地分配一個(gè)級(jí)別,那么該對象會(huì)試圖從他的祖先繼承一個(gè)級(jí)別值。

          ILog接口的每個(gè)方法都有一個(gè)預(yù)先定義好了的級(jí)別值。正如你在表1看到的,ILog的Inof()方法具有INFO級(jí)別。同樣的,以此類推,Error()方法具有ERROR級(jí)別。當(dāng)我們使用以上的任何一種方法時(shí),log4net框架會(huì)檢查日志對象logger的級(jí)別和方法的級(jí)別。只有當(dāng)方法的級(jí)別高于日志級(jí)別時(shí),日志請求才會(huì)被接受并執(zhí)行。

          舉例說明,當(dāng)你創(chuàng)建了一個(gè)日志對象,并且把他的級(jí)別設(shè)置為INFO。于是框架會(huì)設(shè)置日志的每個(gè)Boolean屬性。當(dāng)你調(diào)用相應(yīng)的日志方法時(shí),框架會(huì)檢查相應(yīng)的Boolean屬性,以決定該方法能不能執(zhí)行。如下的代碼:
          ?

          Logger.Info("message");
          Logger.Debug("message");
          Logger.Warn("message");

          對于第一種方法,Info()的級(jí)別等與日志的級(jí)別(INFO),因此日志請求會(huì)被傳遞,我們可以得到輸出結(jié)果”message”。

          對于第二種方法,Debug()的級(jí)別低于日志對象logger的日志級(jí)別(INFO),因此,日志請求被拒絕了,我們得不到任何輸出。同樣的,針對第三行語句,我們可以很容易得出結(jié)論。

          在表1中有兩個(gè)特殊的級(jí)別:ALL和OFF。ALL表示允許所有的日志請求。OFF是拒絕所有的請求。

          你也可以顯式地檢查Logger對象的Boolean屬性,如下所示:

          if (logger.IsDebugEnabled)
          {
          ? Logger.Debug("message");
          }

          2.2? Repository

          Repository主要用于負(fù)責(zé)日志對象組織結(jié)構(gòu)的維護(hù)。在log4net的以前版本中,框架僅支持分等級(jí)的組織結(jié)構(gòu)(hierarchical organization)。這種等級(jí)結(jié)構(gòu)本質(zhì)上是庫的一個(gè)實(shí)現(xiàn),并且定義在log4net.Repository.Hierarchy 名字空間中。要實(shí)現(xiàn)一個(gè)Repository,需要實(shí)現(xiàn)log4net.Repository.ILoggerRepository 接口。但是通常并不是直接實(shí)現(xiàn)該接口,而是以log4net.Repository.LoggerRepositorySkeleton為基類繼承。體系庫 (hierarchical repository )則由log4net.Repository.Hierarchy.Hierarchy類實(shí)現(xiàn)。

          如果你是個(gè)log4net框架的使用者,而非擴(kuò)展者,那么你幾乎不會(huì)在你的代碼里用到Repository的類。相反的,你需要用到LogManager類來自動(dòng)管理庫和日志對象。

          2.3Appender

          一個(gè)好的日志框架應(yīng)該能夠產(chǎn)生多目的地的輸出。比如說輸出到控制臺(tái)或保存到一個(gè)日志文件。log4net 能夠很好的滿足這些要求。它使用一個(gè)叫做Appender的組件來定義輸出介質(zhì)。正如名字所示,這些組件把它們附加到Logger日志組件上并將輸出傳遞到輸出流中。你可以把多個(gè)Appender組件附加到一個(gè)日志對象上。 Log4net框架提供了幾個(gè)Appender組件。關(guān)于log4net提供的Appender組件的完整列表可以在log4net框架的幫助手冊中找到。有了這些現(xiàn)成的Appender組件,一般來說你沒有必要再自己編寫了。但是如果你愿意,可以從log4net.Appender.AppenderSkeleton類繼承。

          2.4 Appender Filters

          一個(gè)Appender 對象缺省地將所有的日志事件傳遞到輸出流。Appender的過濾器(Appender Filters) 可以按照不同的標(biāo)準(zhǔn)過濾日志事件。在log4net.Filter的名字空間下已經(jīng)有幾個(gè)預(yù)定義的過濾器。使用這些過濾器,你可以按照日志級(jí)別范圍過濾日志事件,或者按照某個(gè)特殊的字符串進(jìn)行過濾。你可以在API的幫助文件中發(fā)現(xiàn)更多關(guān)于過濾器的信息。

          2.5 Layout

          Layout 組件用于向用戶顯示最后經(jīng)過格式化的輸出信息。輸出信息可以以多種格式顯示,主要依賴于我們采用的Layout組件類型。可以是線性的或一個(gè)XML文件。Layout組件和一個(gè)Appender組件一起工作。API幫助手冊中有關(guān)于不同Layout組件的列表。一個(gè)Appender對象,只能對應(yīng)一個(gè)Layout對象。要實(shí)現(xiàn)你自己的Layout類,你需要從log4net.Layout.LayoutSkeleton類繼承,它實(shí)現(xiàn)了ILayout接口。

          ? 3 在程序中使用log4net

          ?3.1. 在自己的項(xiàng)目中添加對 log4net.dll 的引用。
          ?3.2. 設(shè)置配置文件App.config

          示例:

          <? xml?version="1.0"?encoding="utf-8"? ?>
          < configuration >
          ????
          <!-- 如果不用App.config作配置文件,則configSections節(jié)不是必須的。 -->
          ????
          < configSections >
          ????????
          <!-- “type”屬性的完整格式為:配置節(jié)處理器類名,程序集名稱,Version=程序集版本號(hào),Culture=區(qū)域信息,PublicKeyToken=公鑰 -->
          ????????
          < section? name ="log4net" ?type ="log4net.Config.Log4NetConfigurationSectionHandler,log4net" ? />
          ????
          </ configSections >
          ????
          < log4net >
          ????????
          <!-- 日志記錄器logger,可以有多個(gè) -->
          ????????
          < logger? name ="AppLogger" >
          ????????????
          < level? value ="INFO" ? />
          ????????????
          < appender-ref? ref ="LogFileAppender" ? />
          ????????????
          < appender-ref? ref ="ConsoleAppender" ? />
          ????????
          </ logger >
          ????????
          < logger? name ="Form1" >
          ????????????
          < level? value ="DEBUG" ? />
          ????????????
          < appender-ref? ref ="LogFileAppender" ? />
          ????????
          </ logger >
          ????????
          <!-- 所有l(wèi)ogger的基,root的設(shè)置在所有l(wèi)ogger中都起作用。
          ????????當(dāng)在root和logger中重復(fù)設(shè)定相同的appender時(shí),你會(huì)發(fā)現(xiàn)同一日志信息將被記錄兩次。
          -->
          ????????
          <!-- <root>
          ????????????<level?value="WARN"?/>
          ????????????<appender-ref?ref="LogFileAppender"?/>
          ????????????<appender-ref?ref="ConsoleAppender"?/>
          ????????</root>
          -->
          ????????
          <!-- 一個(gè)appender可以由多個(gè)logger共用,當(dāng)然一個(gè)logger可以指定多個(gè)appender。 -->
          ????????
          < appender? name ="LogFileAppender" ?type ="log4net.Appender.FileAppender" >
          ????????????
          < param? name ="File" ?value ="App.log" ? />
          ????????????
          < param? name ="AppendToFile" ?value ="true" ? />
          ????????????
          < layout? type ="log4net.Layout.PatternLayout" >
          ????????????????
          < param? name ="Header" ?value ="[Header]\r\n" ? />
          ????????????????
          < param? name ="Footer" ?value ="[Footer]\r\n" ? />
          ????????????????
          < param? name ="ConversionPattern" ?value ="%d?[%t]?%-5p?%c?[%x]?%X{auth}?-?%m%n" ? />
          ????????????
          </ layout >
          ????????????
          < filter? type ="log4net.Filter.LevelRangeFilter" >
          ????????????????
          < param? name ="LevelMin" ?value ="DEBUG" ? />
          ????????????????
          < param? name ="LevelMax" ?value ="FATAL" ? />
          ????????????
          </ filter >
          ????????
          </ appender >
          ????????
          < appender? name ="ConsoleAppender" ?type ="log4net.Appender.ConsoleAppender" >
          ????????????
          < layout? type ="log4net.Layout.PatternLayout" >
          ????????????????
          < param? name ="ConversionPattern" ?value ="%d?[%t]?%-5p?%c?[%x]?%X{auth}?-?%m%n" ? />
          ????????????
          </ layout >
          ????????
          </ appender >
          ????
          </ log4net >
          </ configuration >

          3.3 代碼里實(shí)現(xiàn)?

          ??????????
          ??private void btnLog_Click(object sender, System.EventArgs e)
          ??{
          ???log4net.ILog log = log4net.LogManager.GetLogger("AppLogger");
          ???log.Debug("debug");
          ???log.Info("info");
          ???log.Warn("warn");
          ???log.Error("error");
          ???MessageBox.Show("生成日志成功!");
          ??}


          posted on 2006-11-23 22:04 注銷..... 閱讀(257) 評(píng)論(0)  編輯  收藏

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 云浮市| 临海市| 宁南县| 九寨沟县| 马龙县| 佳木斯市| 千阳县| 林西县| 金坛市| 泾川县| 阜城县| 浙江省| 延吉市| 汶川县| 会同县| 西峡县| 通化市| 定州市| 西宁市| 兴仁县| 滁州市| 体育| 罗江县| 义马市| 华阴市| 威海市| 张家口市| 刚察县| 高邮市| 延长县| 桦南县| 南澳县| 博客| 乐平市| 施秉县| 岳普湖县| 绥棱县| 伊金霍洛旗| 宜兰县| 中阳县| 土默特右旗|