2011-05-31 48 views
17

我目前正在運行一個windows服務,它創建一個類的多個實例。類別的每個實例的唯一日誌文件

在服務類,並在我的解決方案所有其他類的頂部,我有這樣的事情:

private static readonly ILog _log = LogManager.GetLogger(typeof(SomeClassTypeHere)); 

在我的App.config,我log4net的配置爲單個文件:

<log4net debug="true"> 
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> 
     <file value="Logs\SomeLogFileName.xml" /> 
     <appendToFile value="true" /> 
     <rollingStyle value="Size" /> 
     <countDirection value="1" /> 
     <maxSizeRollBackups value="30" /> 
     <maximumFileSize value="10MB" /> 
     <staticLogFileName value="true" /> 
     <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> 
     <layout type="log4net.Layout.XmlLayoutSchemaLog4j"> 
     <locationInfo value="true" /> 
     </layout> 
    </appender> 

    <root> 
     <level value="INFO" /> 
     <appender-ref ref="RollingFileAppender" /> 
    </root> 
    </log4net> 

這在大多數方面效果很好,並且所有內容都記錄到單個文件中。但是,我真的想爲我的服務創建的特定類的每個實例創建一個單獨的日誌文件。
這是一個我們經常需要監視支持的類,我們可以同時運行少數幾個實例。
我們不知道在給定的時間將運行哪些實例,所以它使得在配置中創建靜態文件有點痛苦。

我試圖起飛只讀修改和設置在類的構造函數如下:

_log = LogManager.GetLogger("DataCollectionClass_" + deviceName + "_" + DateTime.Now.ToString("MMddyyyy"), typeof(SomeClassTypeHere)); 

但是,這需要我在配置手動定義附加目的地,這將是繁瑣,很難跟上。

在L4N中做這件事的任何想法?我已經看到鏈接here,但不知道這個框架是否必要。

回答

14

下面的代碼顯示瞭如何在不使用配置文件的情況下以編程方式配置log4Net以實現所需的效果。基本上,它只涉及創建一個命名記錄器並添加到層次結構中。我使用here作爲答案的起點之一。

using log4net; 
using log4net.Appender; 
using log4net.Layout; 
using log4net.Repository.Hierarchy; 

namespace LoggerTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      DeviceConnection dev1 = new DeviceConnection("Device1"); 
      DeviceConnection dev2 = new DeviceConnection("Device2"); 

      dev1.DoSomething(); 
      dev2.DoSomething(); 
     } 
    } 

    public class DeviceConnection 
    { 
     private string name; 
     private readonly ILog logger; 

     public DeviceConnection(string _name) 
     { 
      name = _name; 

      logger = TestLogger.AddNamedLogger(name); 

      logger.Info("---- Begin Logging for DeviceConnection: " + name); 
     } 

     public void DoSomething() 
     { 
      logger.Info("Doing something for device connection " + name); 
     } 
    } 

    public static class TestLogger 
    { 
     private static PatternLayout _layout = new PatternLayout(); 
     private const string LOG_PATTERN = "%d [%t] %-5p %m%n"; 

     public static string DefaultPattern 
     { 
      get { return LOG_PATTERN; } 
     } 

     static TestLogger() 
     { 
      _layout.ConversionPattern = DefaultPattern; 
      _layout.ActivateOptions(); 

      Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository(); 
      hierarchy.Configured = true; 
     } 

     public static PatternLayout DefaultLayout 
     { 
      get { return _layout; } 
     } 

     public static ILog AddNamedLogger(string name) 
     { 
      Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository(); 
      Logger newLogger = hierarchy.GetLogger(name) as Logger; 

      PatternLayout patternLayout = new PatternLayout(); 
      patternLayout.ConversionPattern = LOG_PATTERN; 
      patternLayout.ActivateOptions(); 

      RollingFileAppender roller = new RollingFileAppender(); 
      roller.Layout = patternLayout; 
      roller.AppendToFile = true; 
      roller.RollingStyle = RollingFileAppender.RollingMode.Size; 
      roller.MaxSizeRollBackups = 4; 
      roller.MaximumFileSize = "100KB"; 
      roller.StaticLogFileName = true; 
      roller.File = name + ".log"; 
      roller.ActivateOptions(); 

      newLogger.AddAppender(roller); 

      return LogManager.GetLogger(name); 
     } 
    } 
} 
+0

In如果代碼不明顯,名爲dev1的實例總是記錄到Device1.log,並且名爲dev2的實例記錄到Device2.log。代碼已經過測試,您應該可以將其複製到program.cs中一個新的控制檯項目文件來嘗試它 – dhochee 2011-06-01 16:09:31

+0

這有幫助,謝謝! – Killnine 2011-06-07 13:18:10

1

使用ADO.Net appender並登錄到SQL Server數據庫並只查詢所需的信息。

另一種替代方法是log4net儀表板:http://www.l4ndash.com/。它在整合來自不同來源的日誌方面做得相當不錯,然後以不同的方式對它們進行切片和切片。價格也合理。

+0

這聽起來像一個很好的計劃;然而,在我的公司。環境中,我們沒有一個數據庫可以專注於此服務的日誌記錄。也許團隊最終會遷移到這一點,但現在每個團隊都需要使用平面文件(或其集合)。 > =( – Killnine 2011-05-31 18:42:58

+0

@ AdminK9:看到我修正的答案, – 2011-05-31 18:46:07

1

log4net有一個概念稱爲記錄器層次結構。

記錄程序被認爲是 另一個記錄器的祖先如果 名字後面加一個點是 後代記錄器名稱的前綴。記錄器 被稱爲是小孩的父母 記錄器,如果其自身與 記錄器之間沒有先輩 。與.NET中的名稱空間和 類層次結構相同,該層次結構的工作原理非常類似於 。這很方便,因爲我們很快就會看到。

所以你真的應該創建與.字符而不是_字符的實例特定記錄器。

_log = LogManager.GetLogger("DataCollectionClass." + deviceName + "." + DateTime.Now.ToString("MMddyyyy"), typeof(SomeClassTypeHere)); 

然後在配置文件中引用記錄器層次結構,如下所示。

<log4net> 
    <!-- Other log4net configuration omitted for brevity --> 
    <logger name="DataCollectionClass"> 
    <!-- Put your appender-ref entries here --> 
    </logger> 
</log4net> 

請注意記錄器名稱引用不包含代碼中使用的完全限定名稱。它只引用名稱的根。想想它,就像你想到命名空間一樣。

+0

+1這個方法,我和OP有相同的要求,看起來像'層次結構'非常適合這個要求,我更喜歡使用配置文件來編程方法(儘管我想app.config可以在那裏工作)我會進一步調查這個選項 – SleepyBoBos 2012-11-02 04:09:39

+2

嗨,我不確定每個實例是如何創建一個不同的文件的,appender是在控制文件名的權利嗎 – uriDium 2013-05-08 11:53:57

0

我有一篇文章,可能會幫助:

http://horth.com/blog/?p=165

這是關於在運行時更改的日誌文件。你可以做的是將每個實例的文件名傳入你的log4net文件。這樣你可以爲你的類的每個實例創建一個日誌文件。這樣你的配置文件很簡單,但你可以靈活地爲每個類實例創建一個新的日誌文件。

上面已經提到您可以登錄數據庫以及每個實例的指標。如果您不想購買任何東西,請使用允許使用10GB數據庫的SQL Express。您甚至可以直接寫入MDF文件而不是安裝SQL。

相關問題