【发布时间】:2018-08-01 11:22:12
【问题描述】:
我们刚刚将一个 aspnet core 2.0 应用程序更新到 2.1,但在使用/依赖 System.Diagnostics.Activity 时遇到了问题。
背景
我们希望在我们的服务边界上传递一致的“相关 ID”,以便我们可以关联每个请求的日志条目。
我们采取的方法是:
为
Microsoft.AspNetCore.Hosting.HttpRequestIn.Start的中间件管道添加一个诊断侦听器-
调用此监听器时,检查 context.request 中是否有一个名为“Request-Id”的标头,如果没有则添加一个值为
Activity.Current.Id的标头 另一个中间件负责将“Request-Id”标头值推送到日志记录上下文中
这在 2.0 中运行良好,Activity.Current.Id 的分层特性意味着我们可以关联不同服务和层的日志条目。在 2.1 中,我们现在遇到了异常,因为 Activity.Current 在请求的入口点(即第一个被命中的服务,在本例中为 API)似乎总是为空。
我没有找到任何表明每当 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);
}
}
【问题讨论】:
-
如果您使用 Application Insights (SDK 2.1+),他们会设置 Activity.Current,您可以使用 Activity.Current?.Id 或 .RootId 来获取操作 ID/相关 ID
标签: c# asp.net-core .net-core