2013-05-06 48 views
1

目前我有LogWrapper類,它初始化NLog併發送給它Info/Debug/Warning等等。NLog namespace.name從其他類

private static readonly Logger s_log = LogManager.GetCurrentClassLogger(); 

public static void Informational(string fmt, Exception exception) 
{ 
    s_log.Info("{0} {1}",fmt, exception.ToString()); 
} 

問題是,由於調用類是比一個訪問日誌包裝日誌不同總是顯示namespace.methodname:

所以在其他類中的每個方法從

LogWrapper.Informational(string.Format(" {0} starts {1}", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name)); 

當LogWrapper開始的LogWrapper,所以對MethodBase進行無用的調用。

有沒有什麼辦法可以從不同類實際訪問NLog的類調用函數?

感謝

+1

http://stackoverflow.com/questions/8331466/retrieve-methodinfo-of-the-method-that-is-before-the-active-one-on-the-calling-s – 2013-05-06 11:04:26

回答

3

如果你的主要興趣在使用NLOG包裝,但仍能夠保持調用點的信息,請參閱我的回答前面一個問題在這裏:

Nlog Callsite is wrong when wrapper is used

簡單地說,你可以使用NLog Log方法並傳遞包裝類型。然後,如果您使用NLog callsite LayoutRenderer,NLog將能夠計算出現場信息,而無需自己弄清楚。

所以,你可能LogWrapper有這樣一種方法:

public static void Informational(string fmt, Exception exception) 
{ 
    LogEventInfo le = new LogEventInfo(LogLevel.Info, logger.Name, null, fmt, exception.ToString()); 
    logger.Log(typeof(LogWrapper), le); 
} 

的關鍵是通過你的包裝(typeof(LogWrapper))作爲第一個參數Logger.Log的類型。 NLog使用該值遍歷調用堆棧,直到它看到該類型爲當前MethodInfo的DeclaringType。 NLog將堆棧幀視爲實際調用站點之前的最後一個堆棧幀,因此NLog在查看它之後再上升一級。

你應該知道NLog也有一個Exception LayoutRenderer,所以你不必自己使用exception.ToString()。

雖然Daniel Hilgarth在他的評論中提到的問題有一些有趣的代碼,但我認爲你應該非常小心地添加一堆代碼來確定NLog可以爲你「免費」獲取的信息。如果您只是爲了記錄目的而需要它,我會建議讓NLog爲您解決問題。如果您需要其他用途,那麼您可能別無選擇,只能自己解決。

在一個側面說明,我也建議不要使用這種風格讓你的通話記錄:

LogWrapper.Informational(string.Format(" {0} starts {1}", 
    MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name)); 

如果您LogWrapper.Informational方法委派給NLOG的Logger.Info,那麼你正在做一些額外的工作在日誌未打開的情況下或日誌記錄級別小於Info(例如警告,錯誤,致命)的情況下。如果由於當前的日誌級別設置,語句實際上不會被記錄,您仍在格式化字符串,並且您正在進行兩個相對昂貴的調用以獲取調用站點信息。