c# - System.Diagnostics.Activity 在 aspnet core 2.1 中为空

标签 c# asp.net-core .net-core

我们刚刚将一个 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/

相关文章:

c# - .NET/甲骨文 : How to execute a script with DDL statements programmatically

c# - 如何使用正则表达式在 <span> 和 </span> 以及 </span> 和 <span> 之间创建任何内容的数组?

c# - 来自 C# 的 MS Access SQL LIKE 查询

c# - 带有 SQL 查询的 Crystal 报表

views - 我应该将 asp-append-version ="true"附加到 asp.net MVC6 中的所有图像吗?

asp.net-core - Fluent 验证在 Bootstrap 4 Modal 中不起作用

.net - .NET Core == .NET Framework 5 吗?

c# - FileStream 慢速,快速读取方式读取许多文件的几个字节

c# - 约束引用 'string'无法解析为类型。 (netcoreapp3.0)

c# - 在 .NET Standard 2 中禁用传递项目引用