it-swarm.cn

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

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

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

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

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

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

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

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

另外,请说明何时最好跟踪“详细”和“警告”事件类型。如果您有带有尼斯跟踪/日志记录的代码示例并愿意共享,那将是极好的。

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

53
Levidad

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

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

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

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

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

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

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

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

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

再次,这取决于。

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

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

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

参见第一点。

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

详细:

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

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

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

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

警告:

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

例子:

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

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

  • 示例3:您的应用程序花了20秒打开和解析一个小文件,而大多数文件需要10到一百毫秒才能打开和解析。您跟踪带有相关信息的warning:文件实际所在的磁盘类型,文件系统,文件大小,实际花费的时间,计算机的开启时间等。用户抱怨打开文件需要20秒钟,因此您需要跟踪以查找发生的情况。例如,您发现在计算机刚启动时从网络共享加载文件需要花费很长时间。您向用户说明延迟是由于网络造成的,与您的应用程序无关。

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

17
Arseni Mourzenko
 > 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.

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

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

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

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

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

还提供有关 此博客文章 的更多信息

4
Amit Apple