我们刚刚将一个 aspnet core 2.0 应用程序更新到 2.1,但在使用/依赖 System.Diagnostics.Activity
时遇到了问题。
背景
我们希望跨服务边界传递一致的“关联 ID”,以便我们可以关联每个请求的日志条目。
我们采用的方法是:
将诊断监听器添加到
Microsoft.AspNetCore.Hosting.HttpRequestIn.Start
的中间件管道
调用此监听器时,检查 context.request 中是否有名为“Request-Id”的 header ,如果没有,则添加一个值为
Activity.Current 的 header 。编号
另一个中间件负责将“Request-Id” header 值推送到日志上下文中
这在 2.0 中工作得很好,Activity.Current.Id
的分层性质意味着我们可以关联不同服务和层的日志条目。在 2.1 中,我们现在遇到异常,因为 Activity.Current
在请求的入口点(即命中的第一个服务,在本例中为 API)似乎始终为 null。
我没有设法找到任何信息表明事件不再在 HttpRequest 进入时自动启动,但这似乎正在发生。是否有人能够阐明发生了什么变化和/或我们做错了什么?
一些代码
启动配置方法...
public void Configure(IApplicationBuilder app, IHostingEnvironment env, DiagnosticListener diagnosticListener)
{
diagnosticListener.SubscribeWithAdapter(new HttpRequestInDiagnosticListener());
app.UseMiddleware<SetRequestIdHeaderForHttpRequestInMiddleware>();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseStatusCodePages();
app.UseSecurityHeaders(Headers.AddSecurityHeaders());
app.UseMvc();
}
...以及涉及的自定义类
public class HttpRequestInDiagnosticListener
{
[DiagnosticName("Microsoft.AspNetCore.Hosting.HttpRequestIn.Start")]
public virtual void OnMiddlewareStarting(HttpContext httpContext)
{
Console.WriteLine($"Middleware Starting, path: {httpContext.Request.Path}");
}
}
public class SetRequestIdHeaderForHttpRequestInMiddleware
{
private readonly RequestDelegate _next;
private readonly DiagnosticSource _diagnostics;
public SetRequestIdHeaderForHttpRequestInMiddleware(RequestDelegate next, DiagnosticSource diagnosticSource)
{
_next = next;
_diagnostics = diagnosticSource;
}
public async Task Invoke(HttpContext context)
{
if (_diagnostics.IsEnabled("Microsoft.AspNetCore.Hosting.HttpRequestIn.Start"))
{
if (!context.Request.Headers.Keys.Contains("Request-Id"))
{
context.Request.Headers.Add("Request-Id", Activity.Current.Id);
}
}
await _next.Invoke(context);
}
}
最佳答案
回答我自己的问题,经过几天的调查,但简明扼要地说是:在 2.1 中,事件不再以与在 2.0 中相同的方式启动。 https://github.com/aspnet/Hosting/blob/release/2.1/src/Microsoft.AspNetCore.Hosting/Internal/HostingApplicationDiagnostics.cs#L54-L79
要启动 Activity
,您需要专门观察 Microsoft.AspNetCore.Hosting.HttpRequestIn
,而问题中的代码正在观察 Microsoft.AspNetCore .Hosting.HttpRequestIn.Start
不幸的是,这并不是 2.1 中影响问题代码的唯一更改,仅更改正在观察的事件名称并不能使此代码正常工作,因为 2.1 现在处理 Request-Id
header 和 CorrelationId
以其自己的方式记录属性,这会干扰此中间件代码。
关于c# - System.Diagnostics.Activity 在 aspnet core 2.1 中为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51632031/