我這樣做的方法是創建一個NLOG包裝類,這將包裹每個日誌法,obuscate方法名拿走並使用堆棧跟蹤對象獲取方法名。那麼你不必每次都寫下來;調用Logging包裝器方法的方法名稱將自動注入。
它會看起來更乾淨,因爲無處不在{0}和methodName。
您甚至還可以進一步創建一個日誌記錄包裝類,該日誌包含一個Action日誌字符串和一個Action,執行Action並使用StackTrace對象調用日誌對象。
我已經使用它來執行時間操作並記錄它們,在一次調用中完成所有操作並保存重複代碼很方便。我的方法ExecuteTimedAction(字符串logString,Action actionToExecute)使用秒錶,記錄一個起始字符串,啓動秒錶,執行該方法(Action委託),停止秒錶,並且再次記錄具有時間戳記,組件名稱,以及呼叫從中啓動的方法的名稱。
獲取方法的代碼很簡單,使用StackTrace對象並獲取前一個調用的StackFrame。
var stackTrace = new StackTrace();
var callingMethodName = stackTrace.GetFrame(2).GetMethod().Name;
注意我上面有2個硬編碼,但這是因爲一個額外的包裝調用;如果您直接撥打電話,則可能需要使用GetFrame(1)。最好的方法是使用即時窗口並嘗試不同的框架,或使用StackTrace對象的GetFrames()方法循環查看您獲得的內容。
我正在尋找保持字符串格式的參數,併爲日誌封裝添加第一個參數。這是可以做到這樣的事:
public static class LogWrapper
{
private static Logger _logger // where Logger assumes that is the actual NLog logger, not sure if it is the right name but this is for example
public static void Info(string logString, object[] params)
{
// Just prepend the method name and then pass the string and the params to the NLog object
_logger.Info(
string.Concat(
GetMethodName(),
": ",
logString
),
params
);
}
public static void Warn(string logString, object[] params)
{
// _logger.Warn(
// You get the point ;)
//)
}
private static string GetMethodName()
{
var stackTrace = new StackTrace(); // Make sure to add using System.Diagnostics at the top of the file
var callingMethodName = stackTrace.GetFrame(2).GetMethod().Name; // Possibly a different frame may have the correct method, might not be 2, might be 1, etc.
}
}
然後在你的調用代碼,在_logger成員成爲LoggerWrapper,不記錄儀,並調用它完全相同的方式,但你刪除{0}從代碼。你需要檢查是否有空值,也許如果沒有其他參數,那麼只需要調用沒有參數的方法重載;我不確定NLog是否支持,所以你必須檢查這個。
...編輯:
只是爲了興趣點我使用這種類型的代碼在可能被一大堆程序集引用的程序集公共庫類型,所以我可以得到的信息,如調用程序集,方法名稱等,而不需要在我的日誌代碼中對它進行硬編碼或擔心它。它也確保了其他使用代碼的人不必擔心它。他們只是調用Log()或Warn()或其他任何東西,程序集會自動保存在日誌中。
下面是一個例子(我知道你說過分誇大你,但如果你可能需要這樣的東西,可以爲將來思考食物)。在這個例子中,我只記錄程序集,而不是方法名,但它可以很容易地組合。
#region : Execute Timed Action :
public static T ExecuteTimedAction<T>(string actionText, Func<T> executeFunc)
{
return ExecuteTimedAction<T>(actionText, executeFunc, null);
}
/// <summary>
/// Generic method for performing an operation and tracking the time it takes to complete (returns a value)
/// </summary>
/// <typeparam name="T">Generic parameter which can be any Type</typeparam>
/// <param name="actionText">Title for the log entry</param>
/// <param name="func">The action (delegate method) to execute</param>
/// <returns>The generic Type returned from the operation's execution</returns>
public static T ExecuteTimedAction<T>(string actionText, Func<T> executeFunc, Action<string> logAction)
{
string beginText = string.Format("Begin Execute Timed Action: {0}", actionText);
if (null != logAction)
{
logAction(beginText);
}
else
{
LogUtil.Log(beginText);
}
Stopwatch stopWatch = Stopwatch.StartNew();
T t = executeFunc(); // Execute the action
stopWatch.Stop();
string endText = string.Format("End Execute Timed Action: {0}", actionText);
string durationText = string.Format("Total Execution Time (for {0}): {1}", actionText, stopWatch.Elapsed);
if (null != logAction)
{
logAction(endText);
logAction(durationText);
}
else
{
LogUtil.Log(endText);
LogUtil.Log(durationText);
}
return t;
}
public static void ExecuteTimedAction(string actionText, Action executeAction)
{
bool executed = ExecuteTimedAction<bool>(actionText,() => { executeAction(); return true; }, null);
}
/// <summary>
/// Method for performing an operation and tracking the time it takes to complete (does not return a value)
/// </summary>
/// <param name="actionText">Title for the log entry</param>
/// <param name="action">The action (delegate void) to execute</param>
public static void ExecuteTimedAction(string actionText, Action executeAction, Action<string> logAction)
{
bool executed = ExecuteTimedAction<bool>(actionText,() => { executeAction(); return true; }, logAction);
}
#endregion
在這裏,日誌功能看起來是這樣的,你可以看到我的日誌功能是不是硬編碼到ExecuteTimedAction,這樣我就可以通過任何日誌行動吧。
在日誌I類在靜態變量一旦保存條目集名稱,並用它爲所有的日誌...
private static readonly string _entryAssemblyName = Assembly.GetEntryAssembly().GetName().Name;
希望這給你足夠的深思一些重構!
想如果這是最適合的代碼審查堆棧交換:codereview.stackexchange.com .... – Arran 2013-03-05 15:10:35
@Arran,可能但它不是我的本意正好審查 - 但我會動如果詢問 – DiskJunky 2013-03-05 15:14:43