首頁 > 軟體

C#使用紀錄檔元件log4net

2022-06-06 22:03:24

一、概述

log4net庫是Apache log4j框架在Microsoft .NET平臺的實現,是一個幫助程式設計師將紀錄檔資訊輸出到各種目標(控制檯、檔案、資料庫等)的工具。

1、下載與版本

Apache log4net ™,最新版本log4net 2.0.8

2、Log4net的結構

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

3、紀錄檔的級別

如果沒有定義LEVEL的值,則預設為DEBUG。

  • OFF 級別最高
  • FATAL
  • RROR
  • WARN
  • INFO
  • DEBUG 預設
  • ALL 級別最低

比如:定義一個紀錄檔物件,設定級別為INFO,表示比INFO級別高(或相等)的紀錄檔將被記錄。即log.Info(“XX”)將記錄,log.Debug(“**”)不記錄

二、建立log4net組態檔

config/log4net.config檔案:

<log4net>
  <root>
    <level value="INFO" />
    <appender-ref ref="RollingFileAppender" />
    <appender-ref ref="ColoredConsoleAppender" />
  </root>
  <logger name="MessageHandler">
    <level value="ERROR" />
    <appender-ref ref="SmtpAppender" />
  </logger>
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="Logpamsdc" />
    <threshold value="INFO" />
    <appendToFile value="true" />
    <rollingStyle value="Composite" />
    <datePattern value="yyyyMMdd" />
    <maxSizeRollBackups value="100"></maxSizeRollBackups>
    <layout type="log4net.Layout.PatternLayout">
      <header value="[Header]" />
      <footer value="[Footer]" />
      <conversionPattern value="%date [%thread] %-5level %logger [%ndc] <%property{auth}> - %message%newline" />
    </layout>
  </appender>
  <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
    <mapping>
      <level value="WARN" />
      <foreColor value="White" />
      <backColor value="Red, HighIntensity" />
    </mapping>
    <layout type="log4net.Layout.PatternLayout">
      <header value="[Header]" />
      <footer value="[Footer]" />
      <conversionPattern value="%date [%thread] %-5level %logger [%ndc] <%property{auth}> - %message%newline" />
    </layout>
  </appender>
  <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender,log4net">
    <to value="" />
    <from value="GPEHZ-MIS@GoldPeak" />
    <subject value="PAMS DC 致命錯誤" />
    <smtpHost value="192.50.6.248" />
    <bufferSize value="32" />
    <lossy value="true" />
    <Authentication value="Basic"/>
    <Username value="GPEHZ-MIS@GoldPeak"/>
    <Password value=""/>
    <evaluator type="log4net.Core.LevelEvaluator,log4net">
      <threshold value="ERROR" />
    </evaluator>
    <layout type="log4net.Layout.PatternLayout,log4net">
      <conversionPattern value="日期:%date 執行緒:[%thread] 級別: %-5level 類:%logger [%ndc] < %property{auth}> - 訊息:%message%newline" />
    </layout>
  </appender>
</log4net>

1、組態檔

設定資訊一般放在單獨的組態檔中,也可以放在在程式的組態檔裡,如app.config 或web.config. 或者任意檔案中。 
log4net框架會在相對於AppDomain.CurrentDomain.BaseDirectory 屬性定義的目錄路徑下查詢組態檔。

框架在組態檔裡要查詢的唯一標識是標籤。一個完整的組態檔的例子如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net"  type="log4net.Config.Log4NetConfigurationSectionHandler,
            log4net-net-1.0" />
  </configSections>

  <log4net>
    ..
  </log4net>
</configuration>

2、Logger

Logger是應用程式需要互動的主要元件,它用來產生紀錄檔訊息。產生的紀錄檔訊息並不直接顯示,還要預先經過Layout的格式化處理後才會輸出。 
Logger提供了多種方式來記錄一個紀錄檔訊息,你可以在你的應用程式裡建立多個Logger,每個範例化的Logger物件都被log4net框架作為命名實體(named entity)來維護。這意味著為了重用Logger物件,你不必將它在不同的類或物件間傳遞,只需要用它的名字為引數呼叫就可以了。

log4net框架使用繼承體系,在框架的體系裡所有的紀錄檔物件都是根紀錄檔(root logger)的後代。也就是說,如果有兩個logger,分別被定義為a.b.c和a.b,那麼我們說a.b是a.b.c的祖先。每一個logger都繼承了祖先的屬性 。這種預設的繼承方式也可以通過顯式地設定標籤的additivity屬性為false而改變。 
Log4net框架定義了一個ILog介面,所有的logger類都必須實現這個介面。如果你想實現一個自定義的logger,你必須首先實現這個介面。

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

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

通常來說,我們會以類(class)的型別(type)為引數來呼叫GetLogger(),以便跟蹤我們正在進行紀錄檔記錄的類。

3、Appender

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

關於log4net提供的Appender元件的完整列表可以在log4net框架的幫助手冊中找到。有了這些現成的Appender元件,一般來說你沒有必要再自己編寫了。但是如果你願意,可以從log4net.Appender.AppenderSkeleton類繼承。

log4net的各種Appender設定範例

http://logging.apache.org/log4net/release/config-examples.html

輸出方式主要包括:

  • AdoNetAppender:將紀錄檔記錄到資料庫中。可以採用SQL和儲存過程兩種方式
  • AspNetTraceAppender:能用ASP.NET中跟蹤的方式檢視記錄的紀錄檔。
  • BufferingForwardingAppender:在輸出到子Appenders之前先快取紀錄檔事件。
  • ColoredConsoleAppender:在終端的視窗寫下高亮度的紀錄檔事件。
  • ConsoleAppender:將紀錄檔輸出到控制檯。
  • EventLogAppender:將紀錄檔寫到Windows作業系統的紀錄檔中去。
  • FileAppender:將紀錄檔寫到檔案中。
  • ForwardingAppender:用來為一個Appender指定一組約束。
  • MemoryAppender:將紀錄檔存到記憶體緩衝區。
  • NetSendAppender:將紀錄檔輸出到Windows Messenger service,這些紀錄檔資訊將在使用者終端的對話方塊中顯示。
  • OutputDebugStringAppender:設定該Appender以向OutputDebugString API寫入紀錄檔。
  • RemotingAppender:通過.NET Remoting將紀錄檔寫到遠端接收端。
  • RollingFileAppender:將紀錄檔以回滾檔案的形式寫到檔案中。
  • SmtpAppender:將紀錄檔寫到郵件中。
  • SmtpPickupDirAppender:設定與SmtpAppender類似,但要把SmtpHost換為PickupDir。
  • TraceAppender:將紀錄檔寫到.NET trace 系統。
  • UdpAppender:將紀錄檔connectionless UDP datagrams的形式送到遠端宿主或以UdpClient的形式廣播。

4、PatternLayout中的轉換模式

  • %F/%file:輸出語句所在的檔名
  • %U/%identity:使用者名稱
  • %l/%location:呼叫者位置
  • %L/%line:輸出語句所在的行號
  • %M/%method:方法
  • %C(class),%class,%type::類名
  • %w/%username:Windows Identity
  • %a/%appdomain:域
  • %t/%thread:當前語句所在的執行緒ID
  • %c(category), %logger::當前紀錄檔物件的名稱
  • %p(priority),%level:紀錄檔的當前優先順序別,即DEBUG、INFO、WARN…等
  • %m/%message:輸出的紀錄檔訊息,如ILog.Debug(…)輸出的一條訊息
  • %exception:異常
  • %d,%date:輸出當前語句執行的時刻,預設格式為ISO8601,也可以在其後指定格式,比如:%d{yyy-MM-dd HH:mm:ss },輸出2015-03-10 14:53:28;也可以%d{ISO8601}輸出2015-03-10 14:51:12,220, %d{DATE}輸出‘10 Mar 2015 14:51:51,318’, %d{ABSOLUTE}輸出14:54:07,943,%d{HH:mm:ss,fff}, %d{dd MM yyyy HH:mm:ss,fff},yyyy年份,MM月份,dd日期,HH小時小時24制,hh小時12小時制,mm分鐘,ss秒,fff毫秒(f為秒的精確位數,幾個f代表精確到小數點後幾位)
  • %r/%timestamp:輸出程式從執行到執行到當前語句時消耗的毫秒數
  • %X/%mdc:輸出(mapped diagnostic context)mdc上下文內容
  • %x/%ndc: 輸出(nested diagnostic context)ndc上下文內容
  • %p/%Proerties{user}:呈現指定屬性
  • %n(newline):換行
  • %-數位:表示該項的最小長度,如果不夠,則用空格填充 。%-10,表示最小長度為10,如果不夠,則用空格右側填充;%.10,表示最大長度為10;可以與%m等其他格式組合使用,範例%10m,%-10m,%10.10m,%-10.10m
  • %%:輸出%

例如,轉換模式為%r [%t]%-5p %c - %m%n 的 PatternLayout 將生成類似於以下內容的輸出: 
176 [main] INFO org.foo.Bar - Located nearest gas station.

三、定義組態檔

當我們建立了上面的組態檔後,我們接下來需要把它和我們的應用聯絡起來。預設的,每個獨立的可執行程式集都會定義它自己的設定。

log4net框架使用 log4net.Config.XmlConfiguratorAttribute在程式集的級別上定義組態檔。

  • ConfigFile:指出了我們的組態檔的路徑及檔名,包括擴充套件名。
  • ConfigFileExtension:如果我們對被編譯程式的程式集使用了不同的副檔名,那麼我們需要定義這個屬性,預設的,程式集的組態檔擴充套件名為”config”。
  • Watch (Boolean屬性): log4net框架用這個屬性來確定是否需要在執行時監視檔案的改變。如果這個屬性為true,那麼FileSystemWatcher將會被用來監視檔案的改變,重新命名,刪除等事件。

1、在Winfrom中,在AssemblyInfo.cs中新增如下程式碼:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]//關聯log4net.config檔案
//或者
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "log4net", Watch = true)]//關鍵到xxx.exe.log4net或xxx.dll.log4net,並監測變化。

2、在asp.net中,在Global.asax檔案中的Application_Start方法中增加:

log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
//或者
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Server.MapPath(@」Config.log4net.config」)))

四、呼叫log4net寫紀錄檔

1、建立或獲取紀錄檔物件

紀錄檔物件會使用在組態檔裡定義的Logger的Name屬性。如果某個紀錄檔物件沒有事先在組態檔裡定義,那麼框架會根據繼承結構獲取祖先節點的屬性,最終的,會從根root紀錄檔獲取屬性。如下所示:

Log4net.ILog log = Log4net.LogManager.GetLogger("MyLogger"); 
//或
Log4net.ILog log = Log4net.LogManager.GetLogger(typeof(_Default));
//或
Log4net.ILog log = Log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

2、輸出紀錄檔資訊

if (log.IsDebugEnabled)
    log.Debug("message"); 
if (log.IsInfoEnabled) 
   log.Info("message); 

log.Logger.Repostory.Shutdown()//關閉紀錄檔

五、更改Appender設定

1、獲取root的Appender

log4net.Repository.Hierarchy.Hierarchy h = (log4net.Repository.Hierarchy.Hierarchy)log4net.LogManager.GetRepository();
log4net.Appender.AppenderCollection ac = h.Root.Appenders;

2、獲取指定Logger的Appender:不包括繼承的Appender

log4net.ILog logger = log4net.LogManager.GetLogger(typeof(_Defaut));
log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logger.Logger).Appenders;

3、更改Appender設定

for (int i = 0; i < ac.Count; i++)
{
    log4net.Appender.RollingFileAppender rfa = ac[i] as log4net.Appender.RollingFileAppender;
    if (rfa != null)
    {
        rfa.File = "xxx.log";//程式執行時動態的設定log紀錄檔的檔名
        rfa.Writer = new System.IO.StreamWriter(rfa.File, rfa.AppendToFile, rfa.Encoding);
    }
 }

六、自定義appender

紀錄檔儲存於記憶體中,到一定閾值之後才將資料post到伺服器,同時可設定伺服器端接受資料的地址

1、定義myMemAppender類

public class MyMemAppender : AppenderSkeleton
{
    private ArrayList eventQueue;

    public string RemoteAddress { get; set; }
    public int QueueSize { get; set; }

    public MyMemAppender() : base()
    {
        eventQueue = new ArrayList();
    }

    protected override void Append(log4net.Core.LoggingEvent loggingEvent)
    {
        lock (eventQueue.SyncRoot)
        {
            eventQueue.Add(loggingEvent);
            if (eventQueue.Count >= QueueSize)
            {
                lock (eventQueue.SyncRoot)
                {
                    SaveToServer();
                    eventQueue.Clear();
                }
            }
        }
    }

    private void SaveToServer()
    {
        lock (eventQueue.SyncRoot)
        {
            List logList = new List();
            foreach (log4net.Core.LoggingEvent evt in eventQueue)
            {
                try
                {
                    LogModel m = Newtonsoft.Json.JsonConvert.DeserializeObject(evt.RenderedMessage);//或者evt.MessageObject as LogModel
                    logList.Add(m);
                }
                catch (Exception ex)
                {
                    Console.Write(ex.ToString());
                    continue;
                }
            }
            //將logList序列化上傳至remoteAddress
        }
    }

    virtual public LoggingEvent[] GetEvents()
    {
        lock (eventQueue.SyncRoot)
        {
            return (LoggingEvent[])eventQueue.ToArray(typeof(LoggingEvent));
        }
    }
}

2、註冊Appender

(1)root根目錄下追加

組態檔方式:

<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
<appender name="myMemAppender" type="LogSystem.Common.MyMemAppender">
    <param name="QueueSize" value="10"/>
    <param name="RemoteAddress" value="http://localhost/PostLogData.aspx"/>
</appender>
<root>
   <level value="ALL"/>
   <appender-ref ref="myMemAppender" />
</root>
</log4net>

程式碼方式:

MyMemAppender appender = new MyMemAppender();
appender.QueueSize = 5;
appender.RemoteAddress = "http://localhost:57427/PostLogData.aspx";
log4net.Config.BasicConfigurator.Configure(appender);
ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

(2)指定Logger名下追加Appender:

MyMemAppender appender = new MyMemAppender();
appender.Name = "MyMemAppender";
appender.QueueSize = 5;
appender.RemoteAddress = "http://localhost:57427/PostLogData.aspx";

Logger logger1 = (Logger)LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
logger1.Level = Level.Info;
IAppender appendered = logger1.GetAppender("MyMemAppender");
if (appendered != null) logger1.RemoveAppender("MyMemAppender");
logger1.AddAppender(appendered);
appender.ActivateOptions();

到此這篇關於C#使用紀錄檔元件log4net的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com