.NET 日志记录和跟踪

可以检测代码以生成日志,该日志用作程序运行时发生的有趣事件的记录。 若要了解应用程序的行为,可以查看日志。 日志记录和跟踪都封装了此方法。 .NET 在其历史记录中积累了多个不同的日志记录 API,本文将帮助你了解可用的选项。

术语“日志记录”和“跟踪”通常是同义的。 区别在于,日志记录输出预计会一直收集,因此它的开销应该很低。 跟踪通常更具侵入性,从应用程序和 .NET 运行时的更深层部分收集更多信息。 它可以在诊断特定问题时使用,也可以作为更深入的性能分析系统的一部分在短时间内自动使用。

跟踪术语的另一个核心是分布式跟踪。 分布式跟踪为基于请求的系统收集概要活动和计时数据,并将各服务中的请求联系起来,提供一个展示整个系统如何处理每个请求的视图。

日志记录 API 中的关键区别

结构化日志记录

日志记录 API 可以是结构化的,也可以是非结构化的:

  • 非结构化:日志条目具有自由格式文本内容,供人类查看。
  • 结构化:日志条目具有定义明确的架构,可以采用不同的二进制和文本格式进行编码。 这些日志专为机器翻译和查询而设计,因此人类和自动化系统都可以轻松操作。

如果不常用,更推荐支持结构化日志记录的 API。 它们能提供更多功能、灵活性和性能,可用性方面的差异不大。

配置

对于简单用例,你可能想要使用直接将消息写入控制台或文件的 API。 但是,大多数软件项目会发现配置所记录日志事件以及进行持久保存非常有用。 例如,在本地开发环境中运行时,可能需要将纯文本输出到控制台,以便轻松读取。 然后,将应用程序部署到生产环境中时,可以切换到将日志存储在专用数据库或一组滚动文件中。 通过具有良好配置选项的 API,可以轻松实现此类转换,而配置较少的选项需要随时随地更新检测代码才能进行更改。

接收器

大多数日志记录 API 允许将日志消息发送到称为接收器的不同目标。 某些 API 具有大量的预制接收器,而其他 API 则只有少许几个接收器。 如果没有预制接收器,通常会提供一个扩展性 API,用于创作自定义接收器,不过这需要编写更多的代码。

.NET 日志记录 API

ILogger

在大多数情况下,无论是将日志记录添加到现有项目还是创建新项目,ILogger 基础结构都是一个很好的默认选择。 ILogger 支持快速的结构化日志记录、灵活配置和包括控制台在内的一系列常见接收器,运行 ASP.NET 应用时应能看到该控制台。 此外,ILogger 接口还可以用作许多第三方日志记录实现的外观,用于提供更丰富的功能和可扩展性。

ILogger 为 .NET 的 OpenTelemetry 实现提供了日志记录案例,允许将日志从应用程序流出到各种 APM 系统以进行进一步分析。

EventSource

EventSource 是一个较旧的高性能跟踪 API,提供结构化日志记录。 最初旨在与 Windows 事件跟踪 (ETW) 有效集成,但后来扩展为支持 EventPipe 跨平台跟踪和自定义接收器的 EventListener。 相比 ILoggerEventSource 的预制日志记录接收器相对较少,也不提供通过单独的配置文件进行配置的内置支持。 如果想要更严格地控制 ETWEventPipe 集成,EventSource 将非常有用,但对于常规用途日志记录,ILogger 更灵活且更易于使用。

跟踪

System.Diagnostics.TraceSystem.Diagnostics.Debug .NET 最早的日志记录 API。 这些类具有灵活的配置 API 和大型接收器生态系统,但仅支持非结构化日志记录。 在 .NET Framework 上,可以通过 app.config 文件进行配置,但在 .NET Core 中,没有基于文件的内置配置机制。 它们通常用于在调试程序下运行时为开发人员生成诊断输出。 出于向后兼容性考虑,.NET 团队继续支持这些 API,但不会添加新功能。 对于已经使用这些 API 的应用程序来说,它们是一个不错的选择。 对于尚未提交到日志记录 API 的较新应用,ILogger 可以提供更好的功能。

专用日志记录 API

控制台

System.Console 类具有 WriteWriteLine 方法,两者可用于简单日志记录场景。 虽然这些 API 很容易上手,但解决方案不会像常规用途日志记录 API 那样灵活。 控制台仅允许非结构化日志记录,并且没有配置支持来选择启用哪些日志消息或重定向到其他接收器。 将 ILogger 或 Trace API 与控制台接收器配合使用不会花费太多额外的精力,还能使日志记录保持可配置状态。

DiagnosticSource

System.Diagnostics.DiagnosticSource 用于记录日志,其中将在进程内对日志信息进行同步分析,而不是将其序列化到任何存储。 这样,源和侦听器就可以将任意 .NET 对象交换为消息,而大多数日志记录 API 则要求日志事件可序列化。 如果有效使用侦听器,此方法还能提速,以数十纳秒的速度处理日志事件。 使用这些 API 的工具通常更类似于进程内探查器,不过 API 不会在此处施加任何约束。

EventLog

System.Diagnostics.EventLog 是一个仅限于 Windows 的 API,用于将消息写入 Windows EventLog。 在许多情况下,在 Windows 上运行时,将 ILogger 与可选的 EventLog 接收器配合使用可能会提供类似的功能,而无需将应用紧密耦合到 Windows 操作系统。