.NET 日志记录和跟踪
可以检测代码以生成日志,该日志用作程序运行时发生的有趣事件的记录。 若要了解应用程序的行为,可以查看日志。 .NET 在其历史记录中积累了多个不同的日志记录 API,本文将帮助你了解可用的选项。
注意
有时日志记录也称为“跟踪”,例如在一些较旧的 Windows 和 .NET API 中。 近年来,“跟踪”更常用作分布式跟踪的缩写,但这不是本文的含义。
.NET 日志记录 API
ILogger
在大多数情况下,无论是将日志记录添加到现有项目还是创建新项目,ILogger 基础结构都是一个很好的默认选择。 ILogger
支持快速的结构化日志记录、灵活配置和包括控制台在内的一系列常见接收器,运行 ASP.NET 应用时应能看到该控制台。 此外,ILogger
接口还可以用作许多第三方日志记录实现的外观,用于提供更丰富的功能和可扩展性。
ILogger 为 .NET 的 OpenTelemetry 实现提供了日志记录案例,允许将日志从应用程序流出到各种 APM 系统以进行进一步分析。
EventSource
EventSource 是一个较旧的高性能 API,具有结构化日志记录。 最初旨在与 Windows 事件跟踪 (ETW) 有效集成,但后来扩展为支持 EventPipe 跨平台跟踪和自定义接收器的 EventListener。 相比 ILogger
,EventSource
的预制日志记录接收器相对较少,也不提供通过单独的配置文件进行配置的内置支持。 如果想要更严格地控制 ETW 或 EventPipe 集成,EventSource
将非常有用,但对于常规用途日志记录,ILogger
更灵活且更易于使用。
跟踪
System.Diagnostics.Trace 是 System.Diagnostics.Debug .NET 最早的日志记录 API。 这些类具有灵活的配置 API 和大型接收器生态系统,但仅支持非结构化日志记录。 在 .NET Framework 上,可以通过 app.config 文件进行配置,但在 .NET Core 中,没有基于文件的内置配置机制。 它们通常用于在调试程序下运行时为开发人员生成诊断输出。 出于向后兼容性考虑,.NET 团队继续支持这些 API,但不会添加新功能。 对于已经使用这些 API 的应用程序来说,它们是一个不错的选择。 对于尚未提交到日志记录 API 的较新应用,ILogger
可以提供更好的功能。
专用日志记录 API
控制台
System.Console 类具有 Write 和 WriteLine 方法,两者可用于简单日志记录场景。 虽然这些 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 操作系统。
日志记录术语
结构化和非结构化日志记录
日志记录可以是“结构化”或“非结构化”:
- 非结构化:日志条目编码为人类可以读取的自由格式文本,但很难以编程方式分析和查询。
- 结构化:日志条目具有定义明确的架构,可以采用不同的二进制和文本格式进行编码。 这些日志专为机器翻译和查询而设计,因此人类和自动化系统都可以轻松操作。
良好的结构化日志记录 API 可以提供更多功能和性能,但使用复杂程度略有增加。
接收器
大多数日志记录 API 允许将日志消息发送到称为接收器的不同目标。 某些 API 具有大量的预制接收器,而其他 API 则只有少许几个接收器。 如果没有预制接收器,通常会提供一个扩展性 API,用于创作自定义接收器,不过这需要编写更多的代码。