1. 程式人生 > >Log4net的配置學習與總結

Log4net的配置學習與總結

 

1 Log4net的結構

       Log4net 有四種主要的元件,分別是logger(記錄器)、Repository(庫)、Appender(附著器)以及Layout(佈局)。

1.1   Logger

Logger是應用程式需要互動的主要元件,它用來產生日誌訊息。產生的日誌訊息並不直接顯示,還要預先經過Layout的格式化出來後才會輸出。

Logger提供了多種方式來記錄一個日誌訊息,你可以在你的應用程式裡建立多個Logger,每個例項化的Logger物件都被log4net框架作為一個命名實體(named entity)來維護。這就意味著為了重用Logger物件,你不必將它在不同的類或物件之間傳遞,只需要用它的名字作為引數呼叫就可以了。Log4net框架使用繼承體系,繼承體系類似於.NET中的名字空間,也就是說,如果哦有兩個logger,分別被定義為a.b.c 和a.b,那麼我就說a.b是a.b.c的祖先。每一個Logger都集成了祖先的屬性。

Logger框架定義了一個ILog介面,所有的logger類都必須實現這個介面。如果哦你想實現一個自定義的logger,你必須首先實現這個介面。

ILog介面的定義如下:

public interface Ilog

      void Debug(object message);

      void Info(object message);

      void Warn(object message);

      void Error(object message);

      void Fatal(object message);

//以上每個方法都有一個過載的方法,用來支援異常處理。過載方法如下所示:

void Debug(object message,Except ex);

void Info(object message,Except ex);

void Warn(object message,Except ex);

void Error(object message,Except ex);

void Fatal(object message,Except ex);

//Boolean屬性用來檢查Logger的日誌級別,如下所示:

bool isDebugEnabled;

bool isInfoEnabled;

bool isWarngEnabled;

bool isErrorEnabled;

bool isFatalEnabled;

Log4net框架定義一個叫LogManager的類,用來管理所有的logger物件。他有一個GetLogger()靜態方法,用我們提供的名字引數來檢索已經存在Logger物件(儲存在配置檔案中)。如果框架裡面不存在該Logger物件,它也會為我們建立一個Logger物件。程式碼如下所示:

Log4net.Ilog log = log4net.LogManager.GetLogger(LoggerName);

通常來說,我們會為類的型別為引數呼叫GetLogger(),以便跟蹤我們在進行日誌記錄的類,傳遞類的型別可以用typeof(ClassName)方法來獲得,或者可以用如下的反射方法來獲得:

System.Reflection.MethodBase.GetCurrentMethod().DeclaringType,儘管符號長了一些,但是後者可以用於一些場合,比如獲去呼叫方法的類的型別。

1.1.1 日誌級別

正如在ILog的介面中看到的一樣,有五中不同的方法可以跟蹤一個應用程式。事實上這五中方法是運作在Logger物件設定的不通日誌優先級別上。這幾種不通的級別是作為常量定義在log4net.spi.Level類中。你可以在程式中使用任何一種方法。但是在最後的釋出中,你也許不想讓所有的程式碼來浪費你的cpu週期,因此,框架提供了7中級別和物件的Boolean屬性來控制日誌的記錄的型別。

表1-1 Logger的日誌級別

級別

允許方法

Boolean屬性

優先級別

OFF

拒絕所有

Height

FATAL

Void Fatal(…);

bool isFatalEnabled

ERROR

VoidError(…);

bool isErrorEnabled

WARN

Void Warn (…);

bool isWarnEnabled

INFO

Void Info(…);

bool is InfoEnabled

DEBUG

VoidDebug(…);

bool isDebugEnabled

ALL

允許所以

Lowest

在log4net框架裡,通過設定配置檔案,每個日誌物件都被分配一個日誌優先級別,如沒有給一個日誌物件顯式地分配一個級別,那麼改物件會試圖從他的祖先繼承一個級別的。

ILog介面的每個方法都有一個預先定義好了的界別。正如表1-1看到的,ILog的Info()方法具有INFO級別。同樣的,以此類推,Error()方法具有ERROR級別。當我們使用以上任何一種方法時,log4net框架會檢查日誌物件logger的級別和方法的級別。只有當方法的級別高於日誌級別時,日誌請求才會被接受並執行。

1.2   Respository

Respository主要用於負責日誌物件組織結構的維護。在log4net的以前版本中,框架僅支援分等級的組織結構(hierarchical organization)。這種等級結構本質上是庫的一個實現,並且定義在log4net.Respository.Hierarchy名字空間中。要實現一個Respository,需要

實現log4net.Respository.ILoggerRespository介面。但是通常並不是直接實現該介面,而是以log4net.Respository.LoggerRespositorySkeleton為基類繼承體系庫(hierarchical respository)則由log4net.Respository.Hierarchy.Hierarchy類實現。

    如果你是log4net框架的使用者,而非擴充套件者,那麼你幾乎不會在你的程式碼中用到Respository的類。相反的,你需要用到LogManager類來自動管理庫和日誌物件。

1.3  Appender

一個好的日誌框架應該能夠產生許多目的地的輸出。如輸出控制檯,儲存檔案,或者存入資料庫等。Log4net能夠很好的滿足這些要求。它是使用一個叫做Appender的元件來定義輸出介質。正如名字所示,這些元件把他們附加到Logger日誌元件上並將輸出傳遞到輸出流中。你可以把多個Appender元件附加到一個日誌物件上。Log4net框架提供了幾個Appender元件。

1.4  Appender Filters

一個Appender物件預設地將所有的日誌時間傳遞到輸出流。Appender的過濾器(Appender Filters)可以按照不同的標準過濾日誌事件。在log4net.Filter的名字控制元件下已經有幾個預定義的過濾器。使用這些過濾器,你可以按照日誌級別範圍過濾日誌時間,或者按照某個特殊的字串進行過濾。你可以在API的幫助檔案中發現更多有關Filter的資訊。

1.5 Layout

Layout元件用於向用戶顯示最後經過格式化的輸出資訊。輸出資訊可以一多種格式顯示,主要依賴與我們採用的layout元件的型別。可以是線性的或者XML檔案。Layout元件和一個Appender元件一起工作哦。API幫助手冊中有關於不通Layout元件的列表。一個Appender物件,只能物件一個Layout物件。要實現你自己的Layout類,你需要從log4net.Layout.LayoutSkeleton類繼承,它實現了ILayout介面。

2           定義配置檔案

配置資訊可以放在如下幾中形式檔案的一種中。

1.在程式的配置檔案裡,如AssemblyName.Config 或 web.config.

2.在自己的檔案裡,檔名可以自取。

Log4net框架會在相對於AppDomain.CurrentDomain.Base.Directory屬性定義的目錄路徑下查詢配置檔案。框架在配置檔案裡要查詢的唯一表示是<log4net>標籤。一個完整的配置檔案(命名為:Log.config)的例子如下:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <configSections>

    <section name ="log4net" type ="log4net.Config.Log4NetConfigurationSectionHandler,log4net-net-1.0"/>

  </configSections>

  <log4net>

    <logger name="ManagerLog">

      <level value="ALL"/>

      <appender-ref ref ="LogFileAppender"/>

      <appender-ref ref ="ADONetAppender"/>

    </logger>

    <!--<root>

      <level value="ALL" />

      <appender-ref ref="ADONetAppender"/>

    </root>-->

    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">

      <file value="log.log"/>

      <appenderToFile value="true"/>

      <rollingstyle value="Date"/>

      <datePattern value="yyyyMMdd"/>

      <encoding value="utf-8"/>

      <param name="MaxSizeRollBackups" value="5" />

      <param name="MaximumFileSize" value="10MB" />

      <layout type="log4net.Layout.PatternLayout">

        <conversionPattern value="%d [%-5level]: %m%n" />

      </layout>

      <!--<filter type="log4net.Filter.LevelRangeFilter">

        <levelMin value ="OFF"/>

        <levelMax value ="ALL"/>

      </filter>-->

    </appender>

    <appender name ="ADONetAppender" type="log4net.Appender.ADONetAppender">

      <bufferSize value ="10"/>

      <connectionType value ="System.Data.SqlClient.SqlConnection,System.Data,Version=1.0.3300.0,Culture=neutral,publicKeyToken=b77a5c561934e089"/>

      <connectionString value="server=SUNLIKE\SQLEXPRESS;database=blank;user id = sa;password = sa;timeout=300;"/>

      <commandText value="INSERT INTO [Log] ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception);"/>

      <parameter>

        <parameterName value="@log_date"/>

        <dbType value ="DateTime"/>

        <layout type ="log4net.Layout.RawTimeStampLayout"/>

      </parameter>

      <parameter>

        <parameterName value="@thread"/>

        <dbType value ="String"/>

        <size value ="255"/>

        <layout type ="log4net.Layout.PatternLayout">

          <conversionPattern value ="%thread"/>

<!--<conversionPattern value ="%t"/>-->

</layout>

      </parameter>

      <parameter>

        <parameterName value="@log_level"/>

        <dbType value ="String"/>

        <size value ="50"/>

        <layout type ="log4net.Layout.PatternLayout">

          <conversionPattern value ="%level"/>

        </layout>

      </parameter>

      <parameter>

        <parameterName value="@logger"/>

        <dbType value ="String"/>

        <size value ="255"/>

        <layout type ="log4net.Layout.PatternLayout">

          <conversionPattern value ="%logger"/>

        </layout>

      </parameter>

      <parameter>

        <parameterName value="@message"/>

        <dbType value ="String"/>

        <size value ="4000"/>

        <layout type ="log4net.Layout.PatternLayout">

          <conversionPattern value ="%message"/>

        </layout>

      </parameter>

      <parameter>

        <parameterName value="@exception"/>

        <dbType value ="String"/>

        <size value ="2000"/>

        <layout type="log4net.Layout.ExceptionLayout"/>

      </parameter>

    </appender>

  </log4net>

</configuration>

如果Log.config存放在debug目錄下,需要在Assembly.cs 末尾新增程式碼:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"Log.config", Watch = true)]

如果Log.config存放在其他目錄下,則需要在Assembly.cs 末尾新增程式碼:

[assembly: log4net.Config.XmlConfigurator(Watch = true)](注:如果在app.config 或者web.config 只要寫這行程式碼即可)

還需要在Program.cs中新增程式碼(確保找到配置檔案):

string path = @" ";//存放Log.config的路徑

FileInfo file = new FileInfo(path+ @"Log.config");

if (File.Exists(file.ToString()))

  {

      log4net.Config.XmlConfigurator.Configure(file);

     }

    else

       {

           throw new Exception("log4net日誌配置檔案未找到");

       }

在程式中自定定義一個類ManagerLog類,對log4net的方法進行重寫。

public class ManageLog

    {

        #region 欄位定義

        private static ILog logEntry = LogManager.GetLogger("ManagerLog");  

       //ManagerLog 與配置檔案中的Logger節中name屬性的值保持一致

    // private static object objectMultx = new object();

        //private static string logname = "log";

        #endregion

        #region 公共介面

        /// <summary>

        /// 輸出程式除錯資訊

        /// </summary>

        /// <param name="message">輸出資訊</param>

        public static void Debug(string message)

        {

            logEntry.Debug(message);

        }

        /// <summary>

        /// 輸出程式錯誤資訊

        /// </summary>

        /// <param name="message">輸出資訊</param>

        public static void Info(string message)

        {

            logEntry.Info(message);

        }

        /// <summary>

        /// 輸出程式錯誤資訊

        /// </summary>

        /// <param name="message">輸出資訊</param>

        public static void Warn(string message)

        {

            logEntry.Warn(message);

        }

        /// <summary>

        /// 輸出程式警告資訊

        /// </summary>

        /// <param name="message">輸出資訊</param>

        public static void Error(string message)

        {

            logEntry.Error(message);

        }

        /// <summary>

        /// 輸出程式致命錯誤資訊

        /// </summary>

        /// <param name="message">輸出資訊</param>

        public static void Fatal(string message)

        {

            logEntry.Fatal(message);

        }

        #endregion

在需要寫日誌的地方加上相應的呼叫語句,如:

ManageLog.Debug("記錄時間……");

2.1 佈局樣式:

Class

Description

ExceptionLayout

只呈現日誌事件中異常的文字資訊

Layout2RawLayoutAdapter

適應於Ilayout介面到IRawLayout

LayoutSkeleton

擴充套件這個抽象類來建立自定義的佈局格式

PatternLayout

可以通過型別字串來配置的佈局

PatternLayout.ConverterInfo

把轉換器名字對映為轉換器型別的包裝類

RawLayoutConverter

IrawLayout介面的型別轉換器

RawPropertyLayout

從日誌事件中提取屬性值

RawTimeStampLayout

從日誌事件中提取日期

RawUtcTimeStampLayout

從日誌事件中提取日期

SimpleLayout

很簡單的佈局

XmlLayout

把日誌事件格式化為XML元素的佈局

XmlLayoutBase

把日誌事件格式化為XML元素的佈局

XmlLayoutSchemalLog4j

把日誌事件格式化為與log4j結構相容的XML元素佈局

2.2  一些說明

(一)log4配置說明

log4net的配置可以放在應用程式的預設配置檔案中(app.config或web.config),也可以再你自己的配置檔案中。(如果log4net的配置不是放在應用程式的配置檔案裡,而是在自己定義的檔案裡,<configSection>節點裡的<section>節點是不需要的。

(二)節點分析

在配置章節中,定義section節點。節點名稱為:須為log4net,且大小寫敏感。

<configSections>

    <section name="log4net"

             type="log4net.Config.Log4NetConfigurationSectionHandler" />

  </configSections>

(三)Log4net章節內容

debug 可選,取值是true或false,預設是false。設定為true,開啟log4net的內部除錯。

update 可選,取值是Merge(合併)或Overwrite(覆蓋),預設值是Merge。設定為Overwrite,在提交配置的時候會重置已經配置過的庫。 

threshold 可選,取值是repository(庫)中註冊的level,預設值是ALL。

支援的子元素:

·appender  0或多個

·logger 0或多個

·renderer 0或多個

·root 最多一個

·param 0或多個

(四)兩個Appenders(輸出源)

定義日誌的輸出方式,只能作為 log4net 的子元素。name屬性必須唯一,type屬性必須指定

支援的屬性:

name 必須的,Appender物件的名稱

type 必須的,Appender物件的輸出型別

支援的子元素:

·appender-ref 0個或多個,允許此appender引用其他appender,並不是所以appender型別都支援。

·filter 0個或多個,定義此app使用的過濾器。

·layout 最多一個。定義appender使用的輸出格式。

·param 0個或多個, 設定Appender類中對應的屬性的值。

·LogFileAppender

節點日誌檔案輸出。type="log4net.Appender.FileAppender"

·ConsoleAppender

節點控制檯輸出。type="log4net.Appender.ConsoleAppender"

(五)一個root

根logger,所有其它logger都預設繼承它。root元素沒有屬性。

支援的子元素:

·appender-ref 0個或多個,要引用的appender的名字。

·level 最多一個。 只有在這個級別或之上的事件才會被記錄。

·param 0個或多個, 設定一些引數。

<root>

      <level value="WARN" />

      <appender-ref ref="LogFileAppender" />

      <appender-ref ref="ConsoleAppender" />

    </root>

(六)Logger

支援的屬性:

name 必須的,logger的名稱

additivity 可選,取值是true或false,預設值是true。設定為false時將阻止父logger中的appender。

支援的子元素:

·appender-ref 0個或多個,要引用的appender的名字。

·level 最多一個。 只有在這個級別或之上的事件才會被記錄。

·param 0個或多個, 設定一些引數。

<logger name="testApp.Logging">

      <level value="DEBUG"/>

    </logger>

(七)Layout

佈局,只能作為<appender>的子元素。

支援的屬性:

type 必須的,Layout的型別

支援的子元素:param 0個或多個, 設定一些引數。

(八)Filter

過濾器,只能作為<appender>的子元素。

支援的屬性:

type 必須的,Filter的型別

支援的子元素:param 0個或多個, 設定一些引數。

(九)Param

<param>元素可以是如何元素的子元素。

支援的屬性:

name 必須的,取值是父物件的引數名。

value 可選的,value和type中,必須有一個屬性被指定。value是一個能被轉化為引數值的字串。

type 可選的,value和type中,必須有一個屬性被指定。type是一個型別名,如果type不是在log4net程式集中定義的,就需要使用全名。

支援的子元素:param 0個或多個, 設定一些引數

2.3  模式轉化

%m(message)輸出日誌訊息

%n(newline)換行

%d(datetime)輸出當前語句執行的時刻

%r(runtime)輸出當前語句的執行時刻

%t(thread id)當前語句所在的執行緒ID

%p(priority)日誌的當前優先級別,DEBUG INFO ……

%c(class)當前日誌物件的名稱

%L 輸出語句所在的行號

%F 輸出語句所在的檔名

%-數字 表示該項的最小長度,如果不夠,用空格填充

結束語

    通過這兩天的學習對log4net元件的配置有了一定的瞭解,能進行簡單的日誌輸出,不僅能夠在console顯示,也可以匯入到文字檔案裡,還可以匯入到資料庫中。方便簡單,在開發中是一個很不錯的助手。在學習的過程中也發現不少問題,比如做一個控制元件,該控制元件有寫日誌的功能,日誌寫入到sql server 2005中,僅當該控制元件銷燬之後,才能一次寫入資料庫,即如果該控制元件還在活動,在資料庫中是查不出剛剛新增的日誌記錄。具體原因不太清楚,也沒有深究,我估計日誌是當成一個事物來處理了。另外還有一個問題,就是目前還沒有找到一種行之有效的方法寫入oracle10g 或oracle 11g的方法。如果有朋友看到該疑問,請幫忙指正和賜教。網上也有很多資料,本篇篇文章寫的比較膚淺,是參照百度文庫的一篇文章和csdn一些n人的部落格,結合自己的實際開發,總結而成,如有文章中有什麼不妥之處,還請指正。不勝感激。

相關推薦

Log4net配置學習總結

  1 Log4net的結構        Log4net 有四種主要的元件,分別是logger(記錄器)、Repository(庫)、Appender(附著器)以及Layout(佈局)。 1.1   Logger Logger是應用程式需要互動的主要元件,它用來產生日誌訊

Java Web 學習總結(二)Servlet核心介面+Servlet3.0配置

  Servlet3.0版本對Servlet配置進行了重大變革,Servlet類不需要再麻煩的去編輯web.xml檔案了,只需要在類上面進行註釋就可以了,獲得了 Java 社群的一片讚譽之聲,以下是新增的註解支援。 @WebServlet @WebServlet 用於將一個類宣告為 Servlet,該註解

Java多執行緒學習總結(Join)

join()方法的用法: join()是主執行緒 等待子執行緒的終止。也就是在子執行緒呼叫了 join() 方法後面的程式碼,只有等到子執行緒結束了才能執行。 例子如下: Java程式碼 p

Java多執行緒學習總結(ThreadGroup)

在Java中每個執行緒都屬於某個執行緒組(ThreadGroup)。例如,如果在main()中產生一個執行緒,則這個執行緒屬於main執行緒組管理的一員,您可以使用下面的指令來獲得目前執行緒所屬的執行緒組名稱: Java程式碼

多執行緒的學習總結

單執行緒:        只有一個順序執行流        例如:單執行緒的程式如同只僱傭一個服務員的餐廳,他必須做完一件事情後才可以做下一件事情; 多執行緒:        可以

Android UI之底部彈框的學習總結

1、簡介 本文將介紹的是從底部彈出窗體以供使用者進行互動的例子,本文將介紹使用Dialog,View和DialogFragment的方式分別來進行實現。也是仿製了58同城的彈出喜好的UI顯示和互動。彈出框真的是很常見的,在安卓中有廣泛的用途,故而有必要對其進行好好的梳理,後

Rxjava2的學習總結

Rxjava2基礎認知 形式正確的有限Observable 呼叫觀察者的onCompleted正好一次或者它的onError正好一次,而且此後不能再呼叫觀察者的任何其它方法。如果onComplete 或者 onError 走任何一個 都會 主動解除訂閱關

nginx 301 302跳轉配置方法 總結

首先看一個完整程式碼示例,關於nginx 301 302跳轉的。 301跳轉設定: server { listen 80; server_name 123.com; rewrite ^/(.*) http://456.com/$1 permanent; access_log

iOS幾種常用執行緒鎖學習總結

開始前,先建立3個執行緒執行的任務。- (void)method1 { NSLog(@"%@", @"執行緒1"); } - (void)method2 { NSLog(@"%@", @"執行緒2"); } - (void)method3 { NS

Hbase學習總結

一.Hbase簡介:      Hbase是bigtable的開源山寨版本。它利用HadoopHDFS作為其檔案儲存系統,利用Hadoop MapReduce來處理HBase中的海量資料,利用Zookeeper作為協同服務。提供高可靠性、高效能、列儲存、可伸縮、實時讀寫的資

Java EE 之 過濾器入門學習總結(1)

ret oct 入門 全局 err throws () XML view 使用Filter技術來配合開發會使得開發變得簡單起來。簡單的一個例子就表現在“亂碼問題”上。不使用Filter的話,我們有可能需要為每一個網頁設置字符編碼集,如request.setCharacte

java中集合的學習總結

集合與陣列:陣列:長度固定,可以儲存基本型別。集合:長度可變,不能儲存基本型別(只能儲存物件)。集合類框架圖: Collection介面是集合類的根介面,Java中沒有提供這個介面的直接的實現類。但是卻讓其被繼承產生了兩個介面,就是Set和List。Set中不能包含重複的元素

Redis學習總結

vnr vid idl master 總結 config 核心 climb www 前言 本文為學習Redis的一個總結,包含了資料的整理,Redis的介紹,常用數據類型,常用命令,多數據庫與事務的特性以及持久化的概述;如何在Linux上部署,以及使用Java客戶端開發工具

log4net配置學習 之 日誌等級

Logger hierarchy(層次級別) Logger都是已經命名的實體。 Logger的名稱區分大小寫並遵循以下規則: 1、如果A logger的名稱如果是B logger名稱的字首(通過“.”連線),則說A logger是B logger的祖父級。 2、如果

字串最小/最大表示法 學習總結

迴圈字串的最小表示法的問題可以這樣描述:對於一個字串S,求S的迴圈的同構字串S’中字典序最小的一個。由於語言能力有限,還是用實際例子來解釋比較容易:設S=bcad,且S’是S的迴圈同構的串。S’可以是bcad或者cadb,adbc,dbca。而且最小表示的S’是adbc。對於

二分圖學習總結筆記

sca 匈牙利 算法 連續 總結 bubuko clu head con 二分圖也就是給定關系,劃分成兩個集合,使得各自集合的元素沒有關系連接! 在這裏不深刻探討如何實現,而是通過算法來進行學習,二分圖是一類非常簡單的問題 但是最重要的還是圖論中匹配模型的構造,要註

MyBatis學習總結(二)——MyBatis核心配置檔案輸入輸出對映

在上一章中我們學習了《MyBatis學習總結(一)——ORM概要與MyBatis快速起步》,這一章主要是介紹MyBatis核心配置檔案、使用介面+XML實現完整資料訪問、輸入引數對映與輸出結果對映等內容。 一、MyBatis配置檔案概要 MyBatis核心配置檔案在初始化時會被引用,在配置檔案中定義了一些

Apache Shiro學習----配置SpringMVC集成)

async 匹配 過濾 -i fig hit http struct 找到 1.web.xml文件中配置 <!--將shiro的配置文件交給Spring監聽器初始化--> <context-param> <param

【前端】react學習階段總結學習react、react-routerredux的這些事兒

行程 clas 目前 webpack body src 控制 return 體驗 前言   借用阮一峰的一句話:真正學會 React 是一個漫長的過程。 這句話在我接觸react深入以後,更有感觸了。整個react體系都是全新的,最初做簡單的應用,僅僅使用react-to

基礎LINUX學習配置

src enable 小寫字母 gcc 中文 conf 個數字 man命令 zxvf 1.別名,內部命令,哈希表,外部命令,運行命令時的優先級別,以pwd為例 1.首先比較別名和內部命令的優先級 運行alias enable=‘pwd‘,enable是一個內部命令,現在我