通过事件网格的 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 端点处理程序(订阅者端):
为您的所有事件添加两个相关属性:
public string OperationId { get; set; }
public string OperationParentId { get; set; }
发布方:创建 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);
}
}
消费者端:创建请求并恢复关联。
[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()
.
我有一个由两个 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 端点处理程序(订阅者端):
为您的所有事件添加两个相关属性:
public string OperationId { get; set; } public string OperationParentId { get; set; }
发布方:创建 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); } }
消费者端:创建请求并恢复关联。
[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()
.