2009-01-13 28 views
5

我通常在聲明每類下面:關於指定記錄器的log4net策略?

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(
      System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

,並使用靜態成員每個類中的日誌在不同層面(信息,調試等)

我看到的地方,並已如果我想解決生產問題和不能解決生產問題,推理說該設置足夠靈活以幫助我通過命名空間進行過濾並記錄單個類型。

但我很少必須使用精細日誌的「級別」。所以,我想看看別人在用什麼。你是否使用了上述內容,因爲我有這種感覺,或者你創建了諸如「debug」,「trace」,「error」,「moduleA」等命名的記錄器,並且將記錄器共享到不同類型,組件?

回答

-1

最近,我創造了這樣的事情:

public static class Logger 
{ 
    private static bool isLoaded = false;  

    public static ILog Log 
    { 
     get 
     { 
      System.Reflection.MethodBase method; 
      method = new System.Diagnostics.StackTrace().GetFrame(1).GetMethod(); 
      StringBuilder loggerName = new StringBuilder(); 
      loggerName.AppendFormat("{0}.{1}(", method.ReflectedType.FullName, method.Name); 

      ParameterInfo[] parameters = method.GetParameters(); 
      string[] parametersStr = new string[parameters.Length]; 

      if (parameters.Length > 0) 
      { 
       for (int i = 0; i < parameters.Length; i++) 
       { 
        parametersStr[i] = parameters[i].ToString(); 
       } 
       loggerName.Append(String.Join(", ", parametersStr)); 
      } 

      loggerName.Append(")"); 

      return GetLogger(loggerName.ToString()); 
     } 
    } 


    private static ILog GetLogger(string loggerName) 
    { 
     if (!isLoaded) 
     { 
      log4net.Config.XmlConfigurator.Configure(); 
     } 
     return LogManager.GetLogger(loggerName); 
    } 
} 

它讓我用log4net的,而不在每一個類創建它的實例,我需要使用它,我仍然得到的類名和方法,其中i記錄的動作。

使用範例:

Logger.Log.DebugFormat("Response [{0}]", xmlResponse); 
+0

非常好。謝謝。 – Chasler 2009-01-23 16:58:02

+2

你在這上面運行過一個profiler嗎?這個野獸的執行速度是巨大的。即使您想要在生產中關閉DEBUG日誌記錄級別,也會產生相同的成本。如果你確實需要記錄器中的方法名稱,但是再次使用方法名稱時,我可以看到這一點。異常發生,你會在異常堆棧跟蹤中得到該名稱... – 2009-05-19 16:28:47

2

做你原來的方式的成本是ILog的實現,它需要運行「System.Reflection.MethodBase.GetCurrentMethod()DeclaringType。」在時間的一個實例啓動。我記得幾年前曾經看過它,我們的啓動成本是每10000級1秒的量級,而每10萬個級別的啓動成本不到1兆。

鑑於如此低廉的成本,我從來沒有回過頭來,因爲log4net提供了無與倫比的靈活性。

注:的getFrame(1).GetMethod(

方法=新System.Diagnostics.StackTrace():我無法對其他的解決辦法在這裏,因爲我是新評..但這一行。 );

昂貴,特別是如果調用每個日誌消息。

0

您可以用於日誌記錄的工具是PostSharp(http://www.postsharp.org/)。有付費和免費(快速)版本。我只用它來記錄方法邊界,但我知道你也可以用它來進行錯誤處理。在這兩者之間,這將會照顧你的大部分日誌記錄需求,而無需在每個類中編寫代碼。

11

我基本上是用

public class MyClass 
{ 
    private static readonly ILog log = Log.Get<MyClass>(); 
} 

其中Log.Get是,基本上做到這一點內部

return LogManager.GetLogger(typeof(T)); 

的啓動成本比反射更小的方式,以及清潔海事組織一類。

更新:鑑於我在後來的依賴注入,單元測試和假貨的經驗,我不能再說我寬恕了上述方法。該方法的問題(包括我的和OP的問題)是代碼具有關於的明確知識,如何創建日誌實例

一方面,這增加了耦合使測試變得更加困難:沒有簡單的方法將ILog實例替換爲假實例。另一方面,對我的Log課程所做的更改會導致所有使用它的課程都會出現波動。

因此,我去的注入ILog情況下,通常是通過構造函數注入的路線,和外包如何構造loggermy DI framework of choice

public class MyClass 
{ 
    readonly ILog _log; 

    public class MyClass(ILog log) 
    { 
     _log = log; 
    } 
} 

這樣就可以適當的去耦。代碼不再需要知道記錄器是如何構造的。大多數依賴注入框架都有查看要注入的類型的方法,然後使用它來構造日誌實例。這是一個approach for log4net and Autofac