我有一个非常基本的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);
}
}
最好避免为每个请求创建遥测客户端,而不是重复使用单个静态遥测客户端实例。遥测处理器和/或遥测初始化器通常也应仅针对遥测管道注册一次,而不是针对每个请求注册。 TelemetryConfiguration.Active是静态的,并且通过在每个请求中添加新处理器,处理器的队列只会增长。
适当的设置是将Telemetry Initializer(遥测处理器通常用于过滤和用于数据丰富的初始化器)添加到遥测管道中,例如,虽然在ApplicationInsights.config文件中添加了一个条目(如果存在),或者通过Global.asax中某处的TelemetryConfiguration.Active上的代码添加了一个条目,例如Application_Start
:
TelemetryConfiguration.Active.TelemetryInitializers.Add(new MyTelemetryInitializer());
初始化器在相同的上下文/线程中执行,其中调用了Track..(..)
/ telemetry,因此它们可以访问线程本地存储和/或本地对象以从中读取参数/值。