以之前的AppLog以及字串轉列舉為例
//紀錄方法的開始(StartTrace)和結束(EndTrace)時間,再相減(TimeSpan? elapsed)表示呼叫方法所花費的時間
void Example()
{
//視情況從外部帶入,譬如當方法是被迴圈呼叫時
DateTime start = StartTrace();
try
{
//Do something.
}
catch (Exception ex)
{
LogException(start, ex, ex.StackTrace);
}
finally
{
//視情況不紀錄,譬如當方法是被迴圈呼叫時
EndTrace(start, UniqueName);
}
}
//uniqueName是每個物件的唯一識別碼,視專案需求自行設計
void LogTrace(string msg, in string uniqueName, in TimeSpan? elapsed = null, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
if (elapsed.HasValue)
{
msg = string.Format("ts={0}{1}{2}", elapsed.Value.ToString("ss'.'ffffff"), string.IsNullOrWhiteSpace(msg) ? string.Empty : "|", msg);
}
AppendLog(LogLevel.Trace, msg, lineNumber, $"{uniqueName}.{memberName}");
}
void LogTrace(in DateTime startTime, in string msg, in string uniqueName, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
LogTrace(msg, uniqueName, (DateTime.Now - startTime), lineNumber, memberName);
}
DateTime StartTrace()
{
return DateTime.Now;
}
DateTime StartTrace(in string msg, in string uniqueName, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
DateTime now = DateTime.Now;
if (!string.IsNullOrWhiteSpace(msg))
{
LogTrace(msg, uniqueName, null, lineNumber, memberName);
}
return now;
}
void EndTrace(in DateTime startTime, in string uniqueName, in string msg = "", [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
LogTrace(msg, uniqueName, (DateTime.Now - startTime), lineNumber, memberName);
}
void LogWarn(string msg, in string uniqueName, in TimeSpan? elapsed = null, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
if (elapsed.HasValue)
{
msg = string.Format("ts={0}{1}{2}", elapsed.Value.ToString("ss'.'ffffff"), string.IsNullOrWhiteSpace(msg) ? string.Empty : "|", msg);
}
AppendLog(LogLevel.Warn, msg, lineNumber, $"{uniqueName}.{memberName}");
}
void LogWarn(in DateTime startTime, in string msg, in string uniqueName, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
LogWarn(msg, uniqueName, (DateTime.Now - startTime), lineNumber, memberName);
}
void LogError(string msg, in string uniqueName, in TimeSpan? elapsed = null, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
if (elapsed.HasValue)
{
msg = string.Format("ts={0}{1}{2}", elapsed.Value.ToString("ss'.'ffffff"), string.IsNullOrWhiteSpace(msg) ? string.Empty : "|", msg);
}
AppendLog(LogLevel.Error, msg, lineNumber, $"{uniqueName}.{memberName}");
}
void LogError(in DateTime startTime, in string msg, in string uniqueName, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
LogError(msg, uniqueName, (DateTime.Now - startTime), lineNumber, memberName);
}
void LogException(in Exception ex, in string stackTrace, in TimeSpan? elapsed = null, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
string msg = string.Join("|", ex.Message, ex.GetType().Name, $"{Environment.NewLine}{stackTrace}");
if (elapsed.HasValue)
{
msg = string.Format("ts={0}|{1}", elapsed.Value.ToString("ss'.'ffffff"), msg);
}
AppendLog(LogLevel.Error, msg, lineNumber, memberName);
}
void LogException(in DateTime startTime, in Exception ex, in string stackTrace, [CallerLineNumber] in int lineNumber = 0, [CallerMemberName] in string memberName = "")
{
LogException(ex, stackTrace, (DateTime.Now - startTime), lineNumber, memberName);
}
void SelfTest()
{
DateTime start = StartTrace();
try
{
LogTrace(start, $"ProcessPriority={Settings.ProcessPriority}|{Settings.ProcessPriority.ConvertTo<ProcessPriorityClass>()}", "AppCtrl");
LogTrace(start, $"{ProcessPriorityClass.AboveNormal}|{ProcessPriorityClass.AboveNormal.ToString().ConvertTo<ProcessPriorityClass>()}|{((int)ProcessPriorityClass.AboveNormal).ToString().ConvertTo<ProcessPriorityClass>()}", "AppCtrl");
LogTrace(start, $"{ProcessPriorityClass.BelowNormal}|{ProcessPriorityClass.BelowNormal.ToString().ConvertTo<ProcessPriorityClass>()}|{((int)ProcessPriorityClass.BelowNormal).ToString().ConvertTo<ProcessPriorityClass>()}", "AppCtrl");
LogTrace(start, $"{"Sunday".ConvertTo<DayOfWeek>()}", "AppCtrl");
LogTrace(start, $"{"monday".ConvertTo<DayOfWeek>()}", "AppCtrl");
LogTrace(start, $"{"Tue".ConvertTo<DayOfWeek>()}", "AppCtrl");
LogTrace(start, $"{"Wed.".ConvertTo<DayOfWeek>()}", "AppCtrl");
LogTrace(start, $"{"tHURSDAY".ConvertTo<DayOfWeek>()}", "AppCtrl");
LogTrace(start, $"{"f".ConvertTo<DayOfWeek>()}", "AppCtrl");
LogTrace(start, $"{"6".ConvertTo<DayOfWeek>()}", "AppCtrl");
}
catch (Exception ex)
{
LogException(start, ex, ex.StackTrace);
}
finally
{
EndTrace(start, "AppCtrl");
}
}
之後利用SQL或Excel等工具,將關鍵字"ts="撈出來,觀察程式內哪些方法較花費時間,再想辦法改善
程式內也能對LogTrace/LogException等方法做修改,譬如定義0.1秒的閥值,方法的呼叫超過0.1秒時,直接篩選出來,另外監控