我使用下面的代码使System.Net.Http.HttpClient
能够为每个传出的HTTP请求创建一个活动。这在以.NET Core 3.1为目标的ASP.NET Core应用程序中运行良好,但在以.NET Framework 4.7.2为目标的"经典"ASP.NET应用程序中不起作用。
// Using the Subscribe(IObservable<T>, Action<T>) extension method from the System.Reactive package
DiagnosticListener.AllListeners.Subscribe(listener =>
{
if (listener.Name == "HttpHandlerDiagnosticListener")
{
listener.Subscribe(diagnostic =>
{
if (diagnostic.Key == "System.Net.Http.HttpRequestOut.Start")
{
// ...
}
else if (diagnostic.Key == "System.Net.Http.HttpRequestOut.Stop")
{
// ...
}
}
}
}
我能想到的主要区别是,ASP.NET Core应用程序使用.NET Core内置的DiagnosticListener
类型,而"经典"ASP.NET应用程序需要对System.Diagnostics.DiagnosticSource的包引用才能使用该类型。
我尝试使用不同版本的System.Diagnostics.DiagnosticSource包(4.6.0、4.7.0、4.7.1、5.0.0和5.0.1(,在每次升级/降级包后重新构建我的项目,但都无济于事。
我在Azure函数(进程内(应用程序中发现了一个关于类似问题的GitHub问题。他们提到降级到System.Diagnostics.DiagnosticSource 4.7.0是一种变通方法,但在我的测试中,这并不奏效。
在System.Diagnostics.DiagnosticSource包的HttpHandlerDiagnosticListener
摘要中找到答案:
HttpHandlerDiagnosticsListener是.NET 4.6及更高版本的DiagnosticsListener,其中HttpClient没有内置DiagnosticsListener。此类不用于.NET Core,因为.NET Core中的HttpClient已经发出DiagnosticsSource事件。该类弥补了.NET 4.6及更高版本中的不足。HttpHandlerDiagnosticsListener没有公共构造函数。要使用它,应用程序只需要调用DiagnosticListener.AllListeners和DiagnosticListener.AllListener.Observable.Subscribe(IObserver{DiagnosticListener}。
所以我把代码改成了这个,它起作用了:
if (listener.Name == "System.Net.Http.Desktop")
{
listener.Subscribe(diagnostic =>
{
if (diagnostic.Key == "System.Net.Http.Desktop.HttpRequestOut.Start")
{
// ...
}
else if (diagnostic.Key == "System.Net.Http.Desktop.HttpRequestOut.Stop")
{
// ...
}
}
}