.NET中记录和跟踪的最佳实践


53

我已经阅读了很多有关跟踪和日志记录的内容,试图为该问题的最佳实践找到一些黄金法则,但是没有任何东西。人们说好的程序员会产生良好的跟踪,但是要这样说,它必须来自经验。

我也在这里和通过互联网阅读了类似的问题,它们并不是我要问的一样,或者我的回答不令人满意,也许是因为这些问题缺乏细节。

因此,人们说,在无法附加调试器的情况下,跟踪应可以复制调试应用程序的经验。它应该提供足够的上下文,以便您可以看到应用程序中每个控制点采用的路径。

更深入地讲,您甚至可以区分跟踪和事件日志记录,因为“事件日志记录与跟踪的不同之处在于它捕获主要状态而不是详细的控制流”。

现在,说我想仅使用标准.NET类(System.Diagnostics名称空间中的类)进行跟踪和记录。我认为TraceSource类比静态Trace类更适合这项工作,因为我想在跟踪级别之间进行区分,并且使用TraceSource类可以传递用于通知事件类型的参数,而在使用Trace类时我必须使用Trace.WriteLineIf然后验证类似SourceSwitch.TraceInformation和的东西SourceSwitch.TraceErrors,它甚至没有类似TraceVerbose或的属性TraceStart

考虑到所有这些,您是否可以考虑按以下方式进行操作:

  • 开始方法时,跟踪“开始”事件,该事件应表示单个逻辑操作或管道,以及传递给方法的参数值的字符串表示。
  • 将项目插入数据库时​​,跟踪“信息”事件。
  • 在重要的if / else语句中采用一条路径或另一条路径时,跟踪“信息”事件。
  • 在catch块中跟踪“严重”或“错误”,具体取决于它是否是可恢复的错误。
  • 完成该方法的执行时,跟踪“停止”事件。

另外,请说明何时最好跟踪“详细”和“警告”事件类型。如果您的示例代码具有良好的跟踪/记录功能并且愿意共享,那将是极好的选择。

注意:我在这里找到了一些很好的信息,但仍然不是我想要的信息:http : //msdn.microsoft.com/zh-cn/magazine/ff714589.aspx


也许首选路-的日志记录,在净部署到蔚蓝的计算器也是有帮助的。
k3b

是否有任何使用良好模式进行日志记录的完整源代码示例应用程序?
Kiquenet

老实说...如果我使用的是.NET,我可能会安装New Relic之类的东西并称其完成。(尽管在发布时可能不是一个好的选择)
svidgen

Answers:


17

必须选择跟踪类型的重要性,而不是因为跟踪在代码中的位置,而是因为跟踪的消息或多或少地重要。例:

在启动方法时跟踪“启动”事件,该事件应表示单个逻辑操作或管道,以及传递给该方法的参数值的字符串表示形式。

启动逻辑操作时,请使用启动类型。这并不意味着开始跟踪必须在方法的开始,也不意味着方法必须具有开始跟踪。

这就是说,在大多数情况下,逻辑运算实际上将在方法的开头开始。否则,您应该问自己代码是否正确重构。

跟踪参数也可能不是一个好主意。您必须逐案考虑要追踪的内容。例如,跟踪方法的参数确实很不好void Authenticate(string userName, string plainPassword)

将项目插入数据库时​​,跟踪“信息”事件。

这取决于。必须跟踪某些项目,但不是每个项目。

  • 例如,假设您实际上是在将日志项插入数据库。您会跟踪日志吗?然后记录痕迹?然后跟踪跟踪记录?
  • 另一个例子:您正在插入敏感数据。这需要审核。既然您审核了插入,为什么要跟踪它?

在重要的if / else语句中采用一条路径或另一条路径时,跟踪“信息”事件。

再次,这取决于。

根据天气在捕获块中跟踪“严重”或“错误”,这是可恢复的错误。

发生不可恢复的错误后采取的措施可能不仅仅是跟踪。例如,在服务器端,您希望将异常存储在数据库中以进行进一步分析。此外,某些异常不如其他异常重要,并且不需要跟踪。

完成该方法的执行时,跟踪“停止”事件。

参见第一点。

请说明何时最好跟踪“详细”和“警告”事件类型。

详细:

详细信息用于在出现实际错误时跟踪需要跟踪的内容。这意味着在大多数情况下,您将禁用对详细消息的跟踪,但是有时,您必须调试代码的某些部分以了解为什么在极端情况下某些操作失败。

通常,您会有很多冗长的消息,可以使您很好地理解应用程序流程。这也意味着必须在大多数时间禁用这些消息,因为:

  • 否则,日志会非常快地增长,
  • 您通常不需要它们,
  • 它们可能包含有关应用程序流的敏感数据。

当您无法访问调试器时,请将冗长的工具视为必须使用的工具。

警告:

当发生错误和重要事件时,将使用警告类型跟踪,但并不是很重要,不能将其视为错误。例如,低内存可能会发出警告,但是没有理由跟踪错误,因为您的应用程序可以继续运行,即使运行速度比平常慢。

例子:

  • 示例1:应用程序无法打开用户请求打开的文件。该文件存在且未在使用中,权限设置正确,但是有一些阻止打开文件。在这种情况下,您将跟踪一个错误,因为您的应用程序无法管理这种情况,并且无法继续按用户期望的方式工作(即实际读取文件)。

  • 示例2:在检查了第一个示例中的错误之后,您发现该错误是由文件路径长于259个字符的事实引起的。因此,您可以重构代码以进行捕获PathTooLongException。下次用户尝试打开同一文件时,新版本的应用程序将显示一条消息,说明文件太长,必须将其移至另一个文件夹以缩短完整路径才能在其中打开该文件。这个应用程序。您还跟踪一条消息

  • 示例3:您的应用程序花了20秒打开和解析一个小文件,而大多数文件需要10到100毫秒来打开和解析。您使用相关信息跟踪警告:文件实际所在的磁盘类型,文件系统,文件大小,确切花费的时间,计算机打开的时间等。当用户抱怨要花20个磁盘时在打开文件的几秒钟内,您便进行了跟踪以查找发生了什么。例如,您发现在计算机刚启动时从网络共享中加载文件需要花费很长时间。您向用户说明延迟是由于网络造成的,与您的应用程序无关。

  • 示例4:打开的文件显示不正确。您可以启用详细跟踪,从那里实际看到如何从文件中加载数据,然后逐步解析。


我们工作的一种模式是将“ KnownErrors”记录为警告,将“ UnknownErrors”记录为错误。可能不适合您,具体取决于您的基础结构及其如何处理警告,但它对我们来说效果很好。
安德鲁·皮利斯

5
 > say I want to do my tracing and logging using only the standard .NET classes

System.Diagnostics 很棒,因为您可以配置将跟踪信息放到哪里(文件,事件日志,数据库等)。

不幸的是,如果要使用System.Diagnostics,必须事先(在设计时)知道哪些跟踪流应该可以遵循。(在示例文章中,这些是Transfer,Resume,Suspend等)。可以将它们配置为“禁用”,“调试级别”或“错误级别”。

我更喜欢有一个日志记录系统,可以在运行时在classlevel / namespacelevel上决定日志记录的详细程度。例如,所有Debug及更高版本均来自,MyNamespace.Business.*但不来自MyNamespace.Business.Calculations

如果您使用的是log4net(或Common.logging),则每个类都有其自己的记录器,因此您可以轻松确定哪个类在哪个级别上记录。

由于数据库操作在单独的类中,因此不再需要单独的规则

Trace an "Information" event when inserting an item into the database.

相反,我更喜欢以下准则:

  • Tracelevel应该显示基本的工作流程
  • Debuglevel应该显示工作流中的详细数据和处理,包括程序流中的决策以及原因(创建新项,因为该项在数据库中不存在)
  • 用于启动/停止服务的信息级别,每个启动的工作流/ GUI操作都有一个条目

我知道,这是很好的信息,谢谢!但是,正如我在最初的问题中所问的那样,您能否阐明“详细”和“警告”事件类型的用法?而且,我要求其他人以他们的观点做出贡献,因为这个话题比我在互联网上看到的更值得深入探讨。
莱维达德2011年

4

您可以试用Story框架,它具有一种独特的日志记录方法,因为它“使”您在上下文中编写所有日志(并添加其他相关信息),因此当您以后需要阅读它时,您将获得所需的一切。

它将自动添加“开始”和“停止”概念作为故事的开始和结束。

借助基于规则的系统,您可以根据其拥有的信息来控制每个故事(上下文)的处理方式,例如打印出所有有错误或来自“ admin”用户的故事。

此博客文章上还有更多信息



1
有关更多信息的更新答案
Amit Apple
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.