通过事件网格的 Application Insights 关联

Application Insights correlation through Event Grid

我有一个由两个 ASP.NET 核心应用程序组成的应用程序,即应用程序 A 和应用程序 B。 应用程序 A 对应用程序 B 进行 HTTP 调用,Application Insights 会自动关联此并将它们显示为单个请求。太棒了!

但是,我现在转向更 event-based 的系统设计,其中应用程序 A 将事件发布到 Azure 事件网格,应用程序 B 设置了一个 webhook 来侦听该事件。

进行该更改后,遥测关联被破坏,不再显示为单个操作。

我已阅读此文档:https://docs.microsoft.com/en-us/azure/azure-monitor/app/correlation 解释了相关理论 headers - 但我如何将其应用于事件网格并使其转发相关性 headers到订阅端点?

最近(10 月 10 日)AEG 中自定义主题的 Header pass-trough 想法没有计划。

但是,headers 可以通过 AEG 模型传递给事件消息的 数据 object 中的订阅者。例如,可以使用 Policies in Azure API Management 来完成此调解。

更新:

以下文档可以帮助使用自定义跟踪操作手动检测 webhook 端点处理程序(订阅者端):

Track custom operations with Application Insights .Net SDK

Application Insights API for custom events and metrics

  1. 为您的所有事件添加两个相关属性:

    public string OperationId { get; set; }
    public string OperationParentId { get; set; }
    
  2. 发布方:创建 Dependency 并填写这些属性。

    private Microsoft.ApplicationInsights.TelemetryClient _telemetryClient;
    
    async Task Publish<TEventData>(TEventData data)
    {
        var @event = new EventGridEvent
        {
            Id = Guid.NewGuid().ToString(),
            EventTime = DateTime.UtcNow,
            EventType = typeof(TEventData).FullName,
            Data = data
        };  
    
        string operationName = "Publish " + @event.EventType;
    
        // StartOperation is a helper method that initializes the telemetry item
        // and allows correlation of this operation with its parent and children.
        var operation =
             _telemetryClient.StartOperation<DependencyTelemetry>(operationName);
        operation.Telemetry.Type = "EventGrid";
        operation.Telemetry.Data = operationName;
    
        // Ideally, the correlation properties should go in the request headers but
        // with the current implementation of EventGrid we have no other way 
        // as to store them in the event Data.
        data.OperationId = operation.Telemetry.Context.Operation.Id,
        data.OperationParentId = operation.Telemetry.Id,
    
        try
        {
            AzureOperationResponse result = await _client
                .PublishEventsWithHttpMessagesAsync(_topic, new[] { @event });
            result.Response.EnsureSuccessStatusCode();
    
            operation.Telemetry.Success = true;
        }
        catch (Exception ex)
        {
            operation.Telemetry.Success = false;
            _telemetryClient.TrackException(ex);
            throw;
        }
        finally
        {
            _telemetryClient.StopOperation(operation);
        }
    }
    
  3. 消费者端:创建请求并恢复关联。

    [FunctionName(nameof(YourEventDataCosumer))]
    void YourEventDataCosumer([EventGridTrigger] EventGridEvent @event)
    {
        var data = (YourEventData)@event.Data;
    
        var operation = _telemetryClient.StartOperation<RequestTelemetry>(
            "Handle " + @event.EventType,
            data.OperationId,
            data.OperationParentId);
        try
        {
            // Do some event processing.
    
            operation.Telemetry.Success = true;
            operation.Telemetry.ResponseCode = "200";
        }
        catch (Exception)
        {
            operation.Telemetry.Success = false;
            operation.Telemetry.ResponseCode = "500";
            throw;
        }
        finally
        {
            _telemetryClient.StopOperation(operation);
        }
    }
    

这可行,但并不理想,因为您需要在每个消费者中重复此代码。此外,一些早期日志消息(例如,由注入服务的构造函数发出)仍然没有正确关联。

更好的方法是创建自定义 EventGridTriggerAttribute(重新创建整个 Microsoft.Azure.WebJobs.Extensions.EventGrid 扩展)并将此代码移至 IAsyncConverter.ConvertAsync() .