译者 | 李睿
审校 | 孙淑娟
开发人员可以利用ASP.NET Core 6中的跟踪侦听器为其应用程序添加性能和调试工具。
在处理使用ASP.NET Core 6构建的应用程序时,开发人员可能经常希望使用跟踪和日志记录来监控应用程序的性能并诊断错误,还可以在生产环境中使用跟踪来衡量应用程序在运行时的执行情况。
本文讨论如何在ASP.NET Core 6使用跟踪侦听器,研究如何使用跟踪侦听器收集跟踪消息,并使用ILogger将跟踪输出定向到事件日志。
要使用本文中提供的代码示例,应该在系统中安装Visual Studio 2022。
在Visual Studio 2022中创建ASP.NET Core Web API项目
首先,在Visual Studio 2022中创建一个ASP.NET Core项目。按照以下步骤将在Visual Studio 2022中创建一个新的ASP.NET Core 6 Web API项目:
(1)启动Visual Studio 2022 IDE。
(2)点击“创建新项目”。
(3)在“创建新项目”窗口中,从显示的模板列表中选择“ASP.NET Core Web API”。
(4)单击“下一步”。
(5)在“配置新项目”窗口中,指定新项目的名称和位置。
(6)根据偏好,可以选择选中“将解决方案和项目放在同一目录中”复选框。
(7)单击“下一步”。
(8)在接下来显示的“附加信息”窗口中,确保选中“使用控制器...”复选框,因为在这示例中不会使用最少的API。将“身份验证类型”保留为“无”(默认)。
(9)确保未选中“启用Docker”、“为HTTPS配置”和“启用开放API支持”复选框,因为不会在此处使用任何这些功能。
(10)单击创建。
在本文中,将使用这个ASP.NET Core 6 Web API项目来处理跟踪侦听器。
什么是跟踪?
与跟踪主要事件的事件日志相比,跟踪允许更完整地查看正在运行的应用程序及其组件。日志包含结构化或非结构化时间戳数据,这些数据显示应用程序中发生的事件的记录。跟踪提供了对单个请求及其处理方式的更多可见性。
System.Diagnostics命名空间包含跟踪类和调试类。跟踪类用于生产环境,而调试类用于开发时。
跟踪通常涉及以下三个阶段:
- 检测:编写必要的代码来捕获相关信息。
- 跟踪:将跟踪消息写入指定的目标,即事件日志、文本文件、数据库表等。
- 分析:分析从跟踪中收集的信息以确定应用程序中的瓶颈。
什么是跟踪侦听器?为什么需要它们?
跟踪侦听器收集跟踪消息、存储它们,并将它们定向到适当的目标,例如文本文件。.NET提供了几个跟踪侦听器,其中包括:
- ConsoleTraceListener——将跟踪消息发送到控制台窗口。
- DefaultTraceListener——将跟踪消息发送到标准调试输出。
- DelimitedListTraceListener——以分隔格式将跟踪输出发送到流、流编写器或文本编写器。
- EventLogTraceListener——将跟踪消息发送到事件日志。
- TextWriterTraceListener——将跟踪消息发送到文本文件。
- XmlWriterTraceListener——将跟踪消息转换为XML。
System.Diagnostics.Debug和System.Diagnostics.Trace类可以将消息发送到跟踪侦听器,这些侦听器又将消息路由到适当的目标。
在ASP.NET Core 6中使用配置文件创建跟踪侦听器
开发人员可以使用配置文件或编写自定义代码来创建跟踪侦听器。下面显示的代码片段说明了如何使用应用程序配置文件创建跟踪侦听器。
<configuration>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="MyFirstListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="TraceOutput.txt" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
添加到Listeners集合的所有侦听器都将接收跟踪输出。但是,可以使用侦听器而不将其添加到侦听器集合中。在这种情况下,使用侦听器中的Write或WriteLine方法发送输出。
以下的代码演示了一个侦听器,该侦听器未添加到侦听器集合,但仍能够将跟踪消息发送到输出窗口、文件或任何预配置的输出。
TextWriterTraceListener myFirstListener = new
TextWriterTraceListener("Output.txt", "myFirstListener");
myFirstListener.WriteLine("This is a test message.");
myFirstListener.Flush();
- 1.
- 2.
- 3.
- 4.
QQwANV" id="h6e90be6-EkQQwANV">在ASP.NET Core 6中创建自定义跟踪侦听器
在大多数情况下,.NET 6附带的跟踪侦听器将满足要求。但是,如果开发人员想将跟踪消息输出到不同的目的地,可以实现自己的跟踪侦听器。
要构建自定义跟踪侦听器,应该创建一个扩展TraceListener抽象类的类。TraceListener类中有几个虚拟和抽象方法。开发人员至少应该实现Write和WriteLine方法。自定义跟踪侦听器如下所示:
public class CustomTraceListener : TraceListener
{
public CustomTraceListener(ILoggerFactory loggerFactory)
{
}
public override void Write(string? message, string? category)
{
}
public override void Write(string? message)
{
}
public override void WriteLine(string? message)
{
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
因此,自定义跟踪侦听器类必须具有参数构造函数以及Write和WriteLine方法。
开发人员还需要一个表示记录器的ILogger实例、一个创建记录器的ILoggerFactory和一个StringBuilder来存储跟踪消息,然后再将它们发送到日志目标。
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger _iLogger;
private readonly StringBuilder _stringBuilder = new();
- 1.
- 2.
- 3.
开发人员可以利用依赖注入在构造函数中注入ILoggerFactory的实例,然后使用该实例创建ILogger的实例。
public CustomTraceListener(ILoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory;
_iLogger = loggerFactory.CreateLogger(nameof(CustomTraceListener));
}
- 1.
- 2.
- 3.
- 4.
- 5.
下面是Write和WriteLine方法的最小实现:
public override void Write(string? message, string? category)
{
_stringBuilder.Append(message + "-" + category);
}
public override void Write(string? message)
{
_stringBuilder.Append(message);
}
public override void WriteLine(string? message)
{
_stringBuilder.AppendLine(message);
_iLogger.LogInformation(_stringBuilder.ToString());
_stringBuilder.Clear();
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
ASP.NET Core 6中完整的自定义跟踪侦听器示例
以下是自定义跟踪侦听器的最小实现的完整源代码,以供参考。
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Text;
namespace TraceListenerDemo
{
public class CustomTraceListener : TraceListener
{
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger _iLogger;
private readonly StringBuilder _stringBuilder = new();
public CustomTraceListener(ILoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory;
_iLogger =
loggerFactory.CreateLogger(nameof(CustomTraceListener));
}
public override void Write(string? message, string? category)
{
_stringBuilder.Append(message + "-" + category);
}
public override void Write(string? message)
{
_stringBuilder.Append(message);
}
public override void WriteLine(string? message)
{
_stringBuilder.AppendLine(message);
_iLogger.LogInformation(_stringBuilder.ToString());
_stringBuilder.Clear();
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
在Program.cs文件中注册自定义跟踪侦听器
要使用自定义跟踪侦听器,应该使用以下代码将其注册到Listeners集合。
var loggerFactory = app.Services.GetRequiredService<ILoggerFactory>();
Trace.Listeners.Add(new LoggerTraceListener(loggerFactory));
- 1.
- 2.
因为自定义跟踪侦听器已经添加到侦听器集合中,所以它将捕获运行时生成的所有跟踪消息,并将输出发送到记录器。它还将发送在应用程序中显式发送的任何跟踪消息(就像在前面的myFirstListener示例中所做的那样)。
因此,添加到Listeners集合的任何侦听器都可以捕获运行时生成的跟踪以及在应用程序中显式发送的任何跟踪消息。但是,如果未将跟踪侦听器添加到集合中,则它只能发送在应用程序中显式发送的跟踪消息。它不会捕获运行时生成的任何跟踪消息。
使用自定义跟踪侦听器时,必须记住关闭或刷新跟踪侦听器以确保清空输出缓冲区。可以利用StringBuilderCache类来优化使用StringBuilder的代码(在CustomTraceListener类中)。
原文标题:How to work with trace listeners in ASP.NET Core 6,作者:Joydip Kanjilal