首页 > 解决方案 > 通过 Asp.Net HeaderPropogation 库将新创建的标头添加到遥测

问题描述

services.AddHeaderPropogation(o =>
{
 o.Headers.Add("Id")
 o.Headers.Add("Id", context => {
 return new StringValues(Guid.NewGuid().ToString())
});
});

上面的代码帮助我创建一个名为 id 的标头,如果它不存在新的 guid 并且如果它存在,它将只使用该值。这是使用 Microsoft Header Propogation nuget 包。它有效。但现在我需要将此添加到 Azure 应用程序洞察力,但标准的执行方式仅在传入请求具有标头时才有效。如果创建了新的 GUID,它不会触发 ITelemetryInitializer 调用。

因为为了添加 Telmetry 自定义值,我们有一个继承 ITelemtryInitializer 的类,在里面我确实调用了 Request.Headers,如下所示:

var requestTelemetry = telemetry as RequestTelemetry
if(context.Request.Headers.TryGetValue(id, out var value))
  requestTelemtry.Properties[id] = value.ToString()

但是由于 Request.Headers 从来没有这个 id,所以上面的行永远不会被触发。这个 id 只会在 api 调用下一个服务时由中间件创建。

所以我的问题是,有没有办法从 Startup> ConfigureServices 和 HeaderPropogation 代码中调用遥测类,以便在创建新的 GUID 后立即将其添加到遥测中。所有添加到遥测的示例都来自控制器或 DI。如何从 Startup 本身调用它?还是有更好的方法来实现同样的目标?

标签: .net-coreazure-application-insightsrequest-headerstelemetry

解决方案


让我发布我找到的解决方案。我不需要遥测初始化器类来填充另一个类中的 guid。我希望在我们创建它后立即添加它,所以这就是我在启动时修改服务中的标头传播代码的方式。

services.AddHeaderPropagation(options =>
            {
                var correlationId = "YourId";
                options.Headers.Add(correlationId, context => {
                    var requestTelemetry = context.HttpContext.Features.Get<RequestTelemetry>();
                    if (context.HttpContext.Request.Headers.TryGetValue(correlationId, out var value))
                    {
                        requestTelemetry.Properties[correlationId] = value.ToString();
                        return value.ToString();
                    }
                    else
                    {
                        var guidId = Guid.NewGuid().ToString();
                        requestTelemetry.Properties[correlationId] = guidId;
                        return new StringValues(guidId);
                    }
                });
            });

对我来说,关键是意识到我可以使用这个属性选项在代码中任何我们想要的地方获取 RequestTelemetry。

var requestTelemetry = context.HttpContext.Features.Get<RequestTelemetry>();

推荐阅读