ULS 日志记录提示
ULS 日志记录提示
2011 年 2 月 4 日更新: 我建议看一看 https://blogs.msdn.com/b/sharepoint_chs/archive/2011/03/21/uls-2.aspx 上针对此内容的更新示例。新的示例更好,而且功能更多。
我将部分 ULS 日志记录添加到最近的一个项目时,发现了一个有点令人烦恼的副作用。 在 ULS 日志中,区域 (Area) 显示为未知 (Unknown)。 我知道其他人介绍过这一问题的某些方面,但我只想赶快发一篇文章,介绍我发现的此问题的最佳处理方法(当然比我看到的其他一些解决方法更好)。 值得指出的是,如果您根本不想这样做,我相信最佳实践团队在 CodePlex 上提供的日志记录框架可能会自动执行此操作。 但我通常会尽可能多地编写自己的代码,所以我将在此简单介绍一下解决方法。
首先需要注意,大多数 SDK 文档基于创建一个新 SPDiagnosticsCategory 的思路。 该类的新实例的构造函数允许您提供类别名称,当您这样做时,一定会发现要使用的任何自定义类别名称显示在 ULS 日志的“类别”(Category) 列中。 大多数情况下,如果您执行自己的自定义日志记录,您还需要一个自定义区域与自定义类别配合使用。 遗憾的是,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;
}
在此重写中,我将我所有的自定义区域返回到 SharePoint。 在本例中,我只使用我的一个区域,所以这是我发回的所有内容。 此外,如上所述,我只将一个自定义类别与我的区域一起使用。 如果我想使用多个自定义类别,那么我会:1) 将它们添加到上述枚举中 2) 然后将每个添加到我在此方法中定义的 theCategories 列表实例中。
这实际才是添加自定义区域并将其显示在 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”区域中创建一个条目和包含“This is my error message”消息的“SteveCategory”类别。
这是一篇本地化的博客文章。请访问 Tips for ULS Logging 以查看原文