ULS 記錄的秘訣
ULS 記錄的秘訣
UPDATE 2-4-2011: 我建議查看這個的更新範例,網址為: https://blogs.msdn.com/b/sharepoint_cht/archive/2011/03/21/uls-2.aspx 。 新範例較佳且更實用
當我將某些 ULS 記錄新增至最近的專案,我注意到一個煩人的副作用。 在 ULS 記錄中,此「區域」會顯示為 "Unknown"。 我知道這個問題的某些層面一直出現在其他地方,但是我就是想要盡快張貼一篇文章,以說明我找到可處理此問題的最權宜方法 (絕對比其他某些我已說明的解決方案輕鬆許多)。 有一件事值得提出的是,如果您根本不想這樣做,我相信最佳作法團隊在 CodePlex 上發佈的 Logging Framework 會自行處理這個問題。 但是我通常會撰寫自己的程式碼,因此我將在這裡簡短地說明解決方案。
第一件要注意的事是大部分的 SDK 文件是根據建立新 SPDiagnosticsCategory 的概念來操作。 此類別之新執行個體的建構函式可讓您提供「類別」名稱,而且當您這樣做時,您一定會看到要使用的任何自訂「類別」名稱出現在 ULS 記錄的「類別」欄中。 在大多數情況下,如果您要設計自己的自訂記錄,您可能也會想要有一個自訂「區域」,以搭配自訂「類別」。 不幸的是,SDK 讓您必須經歷相當複雜的練習,才能完成此作業,因為您無法使用簡單的建構函式,來建立新的「區域」並使用它,您必須撰寫自己從 SPDiagnosticsServiceBase 衍生的類別。
我選擇實作這一切的方法是建立一個 CS 檔案,以包含我的記錄類別與診斷服務基礎類別。 我將先從診斷基礎類別開始,我在下方貼上整個類別,然後我會逐步解說值得提出的要點﹕
public class SteveDiagnosticService : SPDiagnosticsServiceBase
{
private const string LOG_AREA = "Steve Area";
public enum LogCategories
{
SteveCategory
}
public SteveDiagnosticService()
: base("Steve Diagnostics Service", SPFarm.Local)
{
}
public SteveDiagnosticService(string name, SPFarm parent)
: base(name, parent)
{
}
protected override bool HasAdditionalUpdateAccess()
{
return true;
}
public static SteveDiagnosticService Local
{
get
{
return SPDiagnosticsServiceBase.GetLocal<SteveDiagnosticService>
}
}
public void LogMessage(ushort id, LogCategories LogCategory, TraceSeverity traceSeverity,
string message, params object[] data)
{
if (traceSeverity != TraceSeverity.None)
{
SPDiagnosticsCategory category
= Local.Areas[LOG_AREA].Categories[LogCategory.ToString()];
Local.WriteTrace(id, category, traceSeverity, message, data);
}
}
protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
{
List<SPDiagnosticsCategory> categories = new List<SPDiagnosticsCategory>();
categories.Add(new SPDiagnosticsCategory(
LogCategories.SteveCategory.ToString(),
TraceSeverity.Medium, EventSeverity.Information));
SPDiagnosticsArea area = new SPDiagnosticsArea(
LOG_AREA, 0, 0, false, categories);
List<SPDiagnosticsArea> areas = new List<SPDiagnosticsArea>();
areas.Add(area);
return areas;
}
}
現在讓我們看看有趣的部分:
private const string LOG_AREA = "Steve Area";
以下是我定義要寫入 ULS 記錄的「區域」名稱之位置。
public enum LogCategories
{
SteveCategory
}
這是我要加入自訂「區域」的「類別」清單。 在此例中,我只有一個要與此「區域」搭配使用的類別,但是如果您需要數個類別,只要展開此列舉的內容即可。
public void LogMessage(ushort id, LogCategories LogCategory, TraceSeverity traceSeverity,
string message, params object[] data)
{
if (traceSeverity != TraceSeverity.None)
{
SPDiagnosticsCategory category
= Local.Areas[LOG_AREA].Categories[LogCategory.ToString()];
Local.WriteTrace(id, category, traceSeverity, message, data);
}
}
這是我們實作的兩個重要方法之一,它是我們實際寫入 ULS 記錄的位置。 第一行是我取得 SPDiagnosticCategory 的位置,而當我這麼做時,我參照它所屬的「區域」。 在第二行,我只是呼叫區域 SPDiagnosticsServiceBase 類別上的基礎類別方法,以寫入 ULS 記錄,其中包括傳遞與「區域」關聯的「類別」。
protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
{
List<SPDiagnosticsCategory> theCategories = new List<SPDiagnosticsCategory>();
theCategories.Add(new SPDiagnosticsCategory(
LogCategories.SteveCategory.ToString(),
TraceSeverity.Medium, EventSeverity.Information));
SPDiagnosticsArea theArea = new SPDiagnosticsArea(
LOG_AREA, 0, 0, false, theCategories);
List<SPDiagnosticsArea> theArea = new List<SPDiagnosticsArea>();
theArea.Add(area);
return theArea;
}
在這個 override 中,我返回所有自訂「區域」的 SharePoint。 在此例子中,我將使用一個「區域」,因此也只會傳回一個「區域」。 另外,如上所述,我只會使用一個自訂「類別」與「區域」搭配。 如果我要使用多個自訂「類別」,我會 1) 將它們加入前面所述的列舉,並且 2) 將每個「類別」加入在我此方法中定義的 theCategories List 執行個體。
那是加入自訂「區域」並使其出現在 ULS 記錄中適當欄位背後的真正主要魔法。 記錄類別實作也非常簡單,我將在這裡貼上記錄類別實作的主要類別,並稍做解說:
public class Log
{
private const int LOG_ID = 11100;
public static void WriteLog(string Message, TraceSeverity TraceLogSeverity)
{
try
{
//in this simple example, I’m always using the same category
//you could of course pass that in as a method parameter too
//and use it when you call SteveDiagnosticService
SteveDiagnosticService.Local.LogMessage(LOG_ID,
SteveDiagnosticService.LogCategories.SteveCategory,
TraceLogSeverity, Message, null);
}
catch (Exception writeEx)
{
//ignore
Debug.WriteLine(writeEx.Message);
}
}
}
這樣便可以從參照此程式碼的方法來實作程式碼。 因為 WriteLog 是靜態方法,所以我的程式碼只是 Log.WriteLog(“This is my error message”, TraceSeverity.Medium); 。 在此範例的 ULS 記錄中,它會在 "Steve Area" 區域以及 "SteveCategory" 類別中,以 "This is my error message" 訊息建立一個項目。
這是翻譯後的部落格文章。英文原文請參閱 Tips for ULS Logging