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。

建议 #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有很多Java Script库,它也有像ULSOnError(msg, url, line)和ULSSendException(ex)这样的函数。

不需要简单地调用这些函数,所以只需要包含额外的调用ULS.enable与“true”值。否则,将什么也得不到。

JavaScript ULS.enable = true; ULSOnError("Hello trace", document.location.href, 0);
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485