在 SharePoint 中实现更好日志记录的五点建议





5.00/5 (6投票s)
如何为您的应用程序实现更好的日志记录。
引言
为 SharePoint 编写的大部分代码都在高度不可预测的环境中运行。即使您的代码在开发环境中没有产生任何异常,相同的代码在生产环境中也可能莫名其妙地失败。因此,日志记录是您的解决方案和代码中至关重要的一个部分。
通常,日志记录是开发人员中一个相当流行的话题。有些人喜欢“我们自定义的日志系统”,另一些人则使用现有的框架,最后,其余的人可能会依赖本地操作系统提供的服务,例如 Windows API(这可不是开玩笑的!)。
如果您为 SharePoint 编写自定义代码,以下是一些改进您的解决方案的日志记录部分的建议
建议 #0 - 不要使用第三方日志框架
即使您坚持使用 log4net、NLog、EventLog 或 System.Diagnostic.Trace,或者试图发明您自己的轮子,那么**永远不要再使用这些东西**。
SharePoint 有自己的日志系统,称为“统一日志记录系统 (ULS)”。如果您仍然想知道为什么您要使用 ULS 而不是您喜欢的日志框架,那么请考虑以下事实:
- ULS 由 SharePoint 使用,因此如果您使用第三方日志记录,您将需要整合来自几个不同源的日志。
- ULS 可以通过中央管理和 PowerShell 轻松配置。
- ULS 可以在没有提升权限的情况下写入 Windows 事件日志(!)。
- ULS 会缩小硬盘上的文本日志文件(!)。
- ULS 不需要修改 `web.config` 文件(!)。这对于多服务器场来说是一个相当重要的考虑因素。
- SharePoint 可以将来自多个服务器的 ULS 日志(不仅仅是日志……)聚合到日志数据库(使用情况和运行状况数据收集服务应用程序)。
建议 #1 - 最简单的情况不做任何处理
默认情况下,SharePoint 会捕获未处理的异常并将它们报告给 ULS 日志。如果您有未处理的异常,您可以轻松地在 ULS 日志中找到错误及其堆栈跟踪。如果您启用了“VerboseEx
”日志记录级别,您甚至可以看到对数据库的 SQL 查询。
您还可以使用 ULSViewer 来获得更方便的日志查看体验。
与此同时,有一个例外情况——那就是关于 WebParts。如果您的自定义 WebPart 因异常而失败,那么最终用户只会看到默认的错误页面。如果您遇到配置错误的个人 WebPart 属性的错误,您可能会花费更多时间,您将无法跟踪和调试此错误,除非您以该特定用户的身份登录。如果您开发自定义 WebPart,那么更好的方法可能不仅仅是显示错误,还要提供一些关于如何修复该错误的建议。
建议 #2 - 使用 SPMonitoredScope 类
SPMonitoredScope 可以简单地这样使用:
using (new SPMonitoredScope("My Monitored Scope"))
{
// Do Stuff...
}
您将简单地获得进入/退出日志记录,以及用于范围调用的耗时。默认情况下,SPMonitoredScope
的日志记录级别为“Verbose
”。
SPMonitoredScope
还可以帮助记录性能和资源使用/分配情况。
using (new SPMonitoredScope("My Scope Name",1000,
new SPRequestUsageCounter(3),
new SPSqlQueryCounter(10)))
{
//Do Stuff...
}
如果您达到了执行时间(1000 毫秒),或者 SPSite/SPWeb 分配的总数超过 3,或者 SQL 查询的总数超过 10,那么日志记录级别将提升到“High”。此外,您还将获得这些参数的实际值以及创建 SPSite/SPWeb 对象和执行 SQL 查询的实际位置(通过堆栈跟踪)。
也许,关于 SPMonitoredScope
最有趣的事实是,跟踪信息会被推送到 Developer Dashboard。
如果您有以下代码:
using (new SPMonitoredScope("My Monitored Scope"))
{
using (new SPMonitoredScope("My Sub-Monitored Scope"))
{
using (new SPMonitoredScope("My Sub-Sub-Monitored Scope"))
{
}
using (new SPMonitoredScope("Another deep scope"))
{
}
}
}
那么您将在 Developer Dashboard 中看到这张图:
建议 #3 - 使用 SPDiagnosticsService 写入日志
您可以通过 SPDiagnosticsService 类写入 ULS。
这是写入跟踪日志的示例:
SPDiagnosticsService diagSvc = SPDiagnosticsService.Local;
diagSvc.WriteTrace(0,
new SPDiagnosticsCategory("My Category",
TraceSeverity.Monitorable,
EventSeverity.Error),
TraceSeverity.Monitorable,
"An exception occurred: {0}",
new object[] {ex});
对于每个日志记录,ULS 都有“Area”(区域)和“Category”(类别)。默认情况下,“Area”的值为“Unknown”。
此外,您还可以直接写入事件日志:
SPDiagnosticsService diagSvc = SPDiagnosticsService.Local;
diagSvc.WriteEvent(0,
new SPDiagnosticsCategory("My Category",
TraceSeverity.Monitorable,
EventSeverity.Warning),
EventSeverity.Error,
"Exception occured {0}", new object[] {ex});
建议 #4 - 继承 SPDiagnosticsServiceBase 以获得对日志记录过程的更多控制
如果您正在开发一个大型组件或产品,那么创建您自己的“Diagnostics Service”是合理的——它本质上是一个继承自 SPDiagnosticsServiceBase 的新类。您可以定义自己的“Area”和“Category”,以及执行日志记录的更好方法。中央管理和 PowerShell 还可以为每个“Category”或“Area”设置不同的日志记录级别。
这是开始的示例:
public class LoggingService : SPDiagnosticsServiceBase
{
public static string DiagnosticAreaName = "My";
private static LoggingService _Current;
public static LoggingService Current
{
get
{
if (_Current == null)
{
_Current = new LoggingService();
}
return _Current;
}
}
private LoggingService(): base("My Logging Service", SPFarm.Local)
{
}
protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
{
List<SPDiagnosticsArea> areas = new List<SPDiagnosticsArea>
{
new SPDiagnosticsArea(DiagnosticAreaName, new List<SPDiagnosticsCategory>
{
new SPDiagnosticsCategory("WebParts",
TraceSeverity.Unexpected, EventSeverity.Error)
})
};
return areas;
}
public static void LogError(string categoryName, string errorMessage)
{
SPDiagnosticsCategory category =
LoggingService.Current
.Areas[DiagnosticAreaName]
.Categories[categoryName];
LoggingService.Current.WriteTrace(0, category,
TraceSeverity.Unexpected, errorMessage);
}
}
最后,实际调用可以是这样的:
LoggingService.LogError("WebParts", ex.ToString());
建议 #5 - 利用 diagnostics.asmx Web 服务进行客户端应用程序开发
原来 SharePoint 有一个 `/_vti_bin/diagnostics.asmx` Web 服务。它只有一个方法,该方法将日志写入 ULS,类别为“SharePoint Foundation -> Unified Logging Service”,级别为“Verbose”。
如果您正在开发 Silverlight 或 JavaScript 应用程序,那么该 Web 服务可能是唯一可以让开发人员或管理员访问的日志记录方式。其他选项则很难实现。
SharePoint 有很多 JavaScript 库,它还提供了 ULSOnError(msg, url, line)
和 ULSSendException(ex)
等函数。您无法简单地直接调用这些函数,因此您只需要包含一个值为“true
”的额外调用 ULS.enable
。否则,您将什么也得不到。
ULS.enable = true;
ULSOnError("Hello trace", document.location.href, 0);
附注:不要忘记 ULS 是为开发人员和管理员创建的。您可以考虑为最终用户创建一些东西,SharePoint 列表可能是一个不错的选择。
再附注:嗯,实际上有六个建议,但第 6 个建议在帖子标题中会显得很蹩脚。