65.9K
CodeProject 正在变化。 阅读更多。
Home

在 .NET 应用程序的发布版本中实现跟踪功能的考量

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.61/5 (11投票s)

2002年10月20日

9分钟阅读

viewsIcon

114780

在 .NET 应用程序的发布版本中,即当应用程序交付给客户或在生产环境中运行时,生成跟踪输出的最佳技术是什么?本文讨论了标准 .NET 跟踪功能的优缺点,并提出了一些替代方案。

引言

本文是为 挪威 .NET 用户组 的一次演示而编写的。

我曾在之前的 关于自定义 .NET 跟踪监听器的文章 中介绍了各种自定义 .NET 应用程序跟踪输出生成的方法。最初我计划更新那篇文章以包含更高级的自定义功能,但由于几个原因我改变了主意:

  • 内置的 .NET 跟踪功能存在严重的局限性,这些局限性阻碍了 .NET Trace 类成为生产环境跟踪的最佳选择;由于这些局限性,开发人员应该只在一定程度上自定义标准的 Trace 类——超出这个程度,他们就应该考虑其他选项;
  • 自从我写了那篇文章以来,网上已经发布了新的自定义跟踪监听器示例,包括一个基于 SQL 的跟踪监听器(在 15seconds.com 上的文章《.NET 中的跟踪和实现你自己的跟踪监听器》中有所解释),因此我决定使用超链接功能,而不是自己重写相同的内容;
  • 微软最近宣布了 他们对未来 .NET 开发的计划,下一版本的 VS.NET(代号为“Everett”)将包含企业仪器框架,该框架将提供当前 .NET 标准跟踪功能所缺乏的功能。

因此,我决定不编写新的花哨的跟踪监听器,而是调查以下问题:

  • 是否应该在 .NET 应用程序的发布版本中编译 TRACE 选项?
  • 内置的 .NET 跟踪功能是否为生产环境中的跟踪输出生成提供了良好的选择?
  • .NET Trace 类有哪些替代方案?

发布版本:是否跟踪

这当然是一个选择问题,尽管微软已经展示了自己的偏好:新生成的托管 C++ 项目的发布版本未定义 TRACE 符号,但 C# 项目的发布版本定义了 TRACE。这看起来令人困惑,但我认为这是合理的:为应用程序的最终版本提供一个跟踪后门很有用,而且只要没有在配置文件中指定活动的监听器,就不会产生跟踪输出。另一方面,C++ 语言的传统没有默认的跟踪功能,所以 C++ 开发者会接受他们应该记住在发布版本中显式定义 TRACE 符号。

但对此事有不同意见。Richard Grimes 在他的书《使用 Visual Studio.NET 开发应用程序》中批评了在发布版本中启用跟踪的想法。他列出了四点论证:

  • 跟踪消息总是生成(即使未收集),因此会影响性能;
  • 生成跟踪消息的代码占用了二进制文件空间;
  • 如果客户使用了你自己编写的跟踪监听器的版本,并且该版本写得很糟糕,那么你的应用程序将受到它与之无关的代码的影响;
  • 在发布版本中留下跟踪消息意味着你没有完全测试你的代码;你的应用程序应该只在报告给 Windows 事件日志的“异常”情况下出现问题。

我必须说,我只同意第一点:如果你的应用程序详细记录其活动,它将始终影响性能。另一方面,这必须是一个有意识的选择:可以用在循环中的低级例程可能应该限制其在调试版本中的输出,但如果你需要在生产环境中从应用程序获取活动报告,你将不得不承担性能成本。

我不认为跟踪消息会大大增加你的二进制文件大小,以至于你应该仅仅为此原因考虑删除它们。现代技术趋势不太关心磁盘空间消耗。看看 .NET 的 XCOPY 部署!你的应用程序 CD 会有多少空间被跟踪消息占用?只有一小部分。

关于可能影响应用程序执行的自定义跟踪监听器的论点需要你注意:是的,添加跟踪功能为你的应用程序增加了一个新的维度,并对跟踪消费者提出了一定的要求。但这在你将程序交付给客户时需要考虑的一个普遍问题:硬件、操作系统服务包、设备驱动程序——有很多参数你无法控制但必须考虑。同样,我认为你不应该仅仅因为这个原因禁用应用程序跟踪。

最后,我最强烈反对的论点是:在发布版本中留下跟踪消息表明你没有完全测试你的代码。这种说法将我们带回了独立应用程序在独立机器上运行的世界,即如果程序失败,它必须是该程序的责任。现代计算机程序聚合了如此多的外部功能,以至于在发生故障时,通常无法指向单个模块——系统管理员必须收集足够的信息来“跟踪”导致错误的步骤序列。

所以我的个人选择是为应用程序的发布版本增强跟踪功能,无论是通过在编译时定义 TRACE 符号,还是使用自定义报告功能。采取一些预防措施来限制跟踪输出的大小(我在上一篇文章中展示了一种方法),但让用户可以选择生成程序活动报告。

发布版本:.NET Trace 类是正确的选择吗?

既然我已经说服你,你应该在发布版本中启用跟踪或某种替代方案(或者至少我自己又一次说服了自己),让我们看看现有的 .NET Trace 类是否可以作为生产环境中跟踪的基础。与任何 .NET 类一样,你可以覆盖默认的跟踪功能(通过实现自定义监听器,而不是通过继承已封锁的 Trace 类)。但是,标准的 .NET Trace 有两个主要的 त्यामुळे设计限制,可能会迫使你寻找替代方案。我在上一篇文章中描述了它们,但让我在此总结一下:

  • TraceTraceListener 的方法无法定义消息严重性级别——你可以使用条件方法,但使用 BooleanSwitchTraceSwitch 测试的条件不会转发给监听器,也就是说,监听器无法按其 TraceSwitch 级别对传入消息进行分类。因此,跟踪输出将不包含错误级别信息。
  • 在使用标准跟踪功能时,无法为不同的跟踪监听器分配不同的严重性阈值。跟踪输出对所有监听器都相同,尽管你很难将与写入文本文件相同数量的信息发送到 Windows 事件日志。

我认为这些遗漏是设计缺陷:将消息严重性级别排除在 .NET 跟踪实现之外,严重限制了 Trace 类在生产环境中的可用性。我只能想到一个原因,为什么 Trace 被设计成这样:Trace 类在内部几乎是 Debug 类的克隆——它们共享相同的实现,仅在预处理器符号和默认监听器上有所不同。我希望 Trace 拥有更多自己的功能并且更具可扩展性。

但在你决定实现自己的跟踪功能(或使用我在下一节中将提到的功能)之前,请记住,一旦你替换了内置的 .NET Trace 类,你就不再使用统一的跟踪输出了。如果你的应用程序由几个由不同开发人员——甚至供应商——编写的组件组成,你将面临由不同跟踪引擎生成的多个跟踪输出的风险。

那么,应该使用什么标准来选择发布版本的跟踪实现呢?选择当然是你的,但我会考虑以下几点:

  • 如果你开发可重用组件,你不应该添加对自定义跟踪实现的依赖:使用内置的 .NET 类,它们将是最通用的;
  • 对于大多数桌面应用程序,内置的跟踪监听器(调试、文本和事件日志)提供了足够多的选项;如果你对输出格式不满意,你可以随时通过继承监听器本身或相应的基于 Stream 的类来定制它;因此,在这种情况下,你也应该尝试坚持使用标准的 .NET Trace 类;
  • 如果你开发企业级应用程序,特别是如果你的程序需要满足 24x7 的可用性要求,你很可能需要优化跟踪输出的清晰度,以便在发生故障时能够快速定位系统日志中的可疑部分;在这种情况下,你不仅需要按监听器过滤跟踪输出,还需要为每条消息存储严重性级别——这些选项都无法从内置的 .NET 跟踪类中获得,因此你需要寻找替代方案。

面向企业的跟踪

那么,如果你需要更精细地控制跟踪输出,内置的 .NET Trace 类有什么替代方案呢?微软似乎意识到了当前 .NET 跟踪的局限性,并且很快就会帮助我们:下一版本的 Visual Studio.NET(代号为“Everett”)将包含企业仪器框架(EIF),该框架将填补这些空白并提供许多新功能。EIF 将支持可配置的事件过滤和严重性级别,因此开发人员应该能够编写以下代码:

 // Note that the syntax may change when EIF is released

TraceMessageEvent.Raise("My trace message"); 
ErrorMessageEvent.Raise("My error", 1, "CODE");   // message, severity, error code

当然,SQL 数据库可以配置为跟踪事件存储库,这使得 EIF 成为审计目的的绝佳选择。

虽然企业仪器框架满足你“明天”的需求,但如果你更关心“今天”要去哪里,你必须去别处寻找。一个不错的替代方案是挪威公司 Trimanet 开发的 TrimaTrace 解决方案。它比标准的 .NET 跟踪功能强大得多,可以通过 TCP 远程使用,并且性能非常好(在 1 GHz CPU 的 Pentium III 机器上每秒超过 30,000 条消息)。TrimaTrace 无与伦比的可负担性,因为它免费。

在我上传了本文的第一版后,我收到了另一个替代方案的参考——流行的 log4j Java API 的 .NET 实现,它提供了对日志管理和配置的灵活且任意粒度的控制。这个实现也是免费的,由 NeoWorks 在 SourceForge 上托管。

结论

每一个现代设计决策都是复杂的:所有简单的问题都已得到解答,我们剩下的是比较和妥协的必要。调试选项和格式化跟踪输出等主题在面对我们每天必须解决的“真正”问题时似乎并不重要。然而,不要过度简化它们:它们是你开发环境的基础部分,值得妥善安排。

资源

  1. Vagif Abilov. 编写自定义 .NET 跟踪监听器
  2. Richard Grimes. 使用 Visual Studio.NET 开发应用程序
  3. Mansoor Ahmed Siddiqui. .NET 中的跟踪和实现你自己的跟踪监听器
  4. TrimaTrace,由 Trimanet 开发的免费 .NET 跟踪工具。
  5. Log4Net,由 NeoWorks 开发的 Java 日志 API 的免费 .NET 端口。
© . All rights reserved.