2013-12-10 23 views
1

假設我有擴展到ILog。目前,當我在buisness邏輯中使用ILog擴展時,我將%method %location %class屬性看作我的擴展類。我希望他能成爲我的業務邏輯的參考。有沒有在log4net屬性使ILog擴展隱藏?如何通過log4net在日誌鏈中隱藏方法?

例如

using log4net; 

namespace Helpers { 
    public class MyObject {} 
    public static class LoggerExtensions { 
     public static void Debug(this ILog log, MyObject obj, string format, params object[] arguments) { 
      log.DebugFormat(format, arguments); 
     } 
    } 
} 

這個<conversionPattern value="%type %method %m%n" />將返回類似:LoggerExtensions Debug message和log4net的會不會從它被調用其中在意。

我需要一些屬性才能使此擴展對於log4net stackTrace檢查器透明。有沒有或如何創建一個?

+0

你能展示你的擴展代碼嗎? – stuartd

回答

2

你應該能夠做這樣的事情(請注意,我沒有時間,現在來測試這個)...

using log4net; 

namespace Helpers 
{ 
    public class MyObject {} 
    public static class LoggerExtensions 
    { 
    public static void Debug(this ILog log, MyObject obj, string format, params object[] arguments) 
    { 
     if (!log.IsDebugEnabled) return; 

     log.Logger.Log(typeof(LoggerExtensions), LogLevel.Debug, string.Format(format, arguments)); 
    } 
    } 
} 

的關鍵在於找到合適的調用點登錄(即其中你調用你的擴展方法,而不是擴展方法本身)就是使用「Log」方法,將實現日誌擴展的對象類型傳遞給它。 Log4net將遍歷堆棧,直到達到與傳遞給Log的類型相同的類型。有些將此類型稱爲邊界類型。堆棧中的下一個條目將成爲「真實」代碼中的實際調用站點,而不是您的日誌代碼。

另請注意,我檢查是否啓用了調試日誌記錄,如果沒有,則返回提前。 Log方法沒有采用格式和參數參數的簽名,因此在調用Log之前必須格式化消息。我們不想花費成本來格式化消息,除非它實際上會被記錄。

正如我前面所說的,我沒有測試過這個,但是這個技術在包裝log4net記錄器(例如在Common.Logging.Net中)時使用,以確保呼叫站點得到維護。如果您在SO上查找lot4net包裝器(或NLog包裝器),絕大多數不會寫成維護呼叫站點,所以要小心。如果你想在一個擴展方法後面包裝或隱藏log4net,你不能簡單地委託給Debug,Info等方法。您必須使用Log方法,以便您可以傳遞邊界類型。

祝你好運!