TelemetryProcessor - 多个实例覆盖自定义属性

问题描述 投票:0回答:1

我有一个非常基本的http-POST触发api,它创建了一个TelemetryClient。我需要在这个遥测中为每个单独的请求提供一个自定义属性,所以我实现了TelemtryProcessor

但是,当处理后续POST请求并创建一个似乎干扰第一个请求的新TelemetryClient时。我最终在App Insights中看到可能包含第一个customPropertyId的十几个条目,而第二个条目接近500条,实际上数字应该均匀分割。似乎第二个TelemetryClient的创建以某种方式干扰了第一个。

基本代码如下,如果有人有任何见解(没有双关语),为什么会发生这种情况,我将不胜感激。

处理POST请求的ApiController:

public class TestApiController : ApiController
{
    public HttpResponseMessage Post([FromBody]RequestInput request)
    {
        try
        {
            Task.Run(() => ProcessRequest(request));
            return Request.CreateResponse(HttpStatusCode.OK);
        }
        catch (Exception)
        {
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, Constants.GenericErrorMessage);
        }
    }

    private async void ProcessRequest(RequestInput request)
    {
        string customPropertyId = request.customPropertyId;

        //trace handler creates the TelemetryClient for custom property
        CustomTelemetryProcessor handler = new CustomTelemetryProcessor(customPropertyId);

        //etc.....
    }
}

CustomTelemetryProcessor,它创建TelemetryClient:

public class CustomTelemetryProcessor
{
    private readonly string _customPropertyId;
    private readonly TelemetryClient _telemetryClient;

    public CustomTelemetryProcessor(string customPropertyId)
    {
        _customPropertyId = customPropertyId;

        var builder = TelemetryConfiguration.Active.TelemetryProcessorChainBuilder;
        builder.Use((next) => new TelemetryProcessor(next, _customPropertyId));

        builder.Build();

        _telemetryClient = new TelemetryClient();
    }
}

TelemetryProcessor:

public class TelemetryProcessor : ITelemetryProcessor
{
    private string CustomPropertyId { get; }
    private ITelemetryProcessor Next { get; set; }

    // Link processors to each other in a chain.
    public TelemetryProcessor(ITelemetryProcessor next, string customPropertyId)
    {
        CustomPropertyId = customPropertyId;
        Next = next;
    }
    public void Process(ITelemetry item)
    {
        if (!item.Context.Properties.ContainsKey("CustomPropertyId"))
        {
            item.Context.Properties.Add("CustomPropertyId", CustomPropertyId);
        }
        else
        {
            item.Context.Properties["CustomPropertyId"] = CustomPropertyId;
        }

        Next.Process(item);
    }
}
azure-application-insights
1个回答
1
投票

最好避免为每个请求创建遥测客户端,而不是重复使用单个静态遥测客户端实例。遥测处理器和/或遥测初始化器通常也应仅针对遥测管道注册一次,而不是针对每个请求注册。 TelemetryConfiguration.Active是静态的,并且通过在每个请求中添加新处理器,处理器的队列只会增长。

适当的设置是将Telemetry Initializer(遥测处理器通常用于过滤和用于数据丰富的初始化器)添加到遥测管道中,例如,虽然在ApplicationInsights.config文件中添加了一个条目(如果存在),或者通过Global.asax中某处的TelemetryConfiguration.Active上的代码添加了一个条目,例如Application_Start

TelemetryConfiguration.Active.TelemetryInitializers.Add(new MyTelemetryInitializer());

初始化器在相同的上下文/线程中执行,其中调用了Track..(..) / telemetry,因此它们可以访问线程本地存储和/或本地对象以从中读取参数/值。

© www.soinside.com 2019 - 2024. All rights reserved.