Azure Application Insights 没有显示整个事件链在事件驱动的应用程序中,但所有遥测都在那里

问题描述

场景

我在 ASP .NET Core 中有一个容器化的、事件驱动的微服务应用,刚刚迁移到 .NET 5。

所有项目都使用 Microsoft.ApplicationInsights 2.16.0,并且我已经检查了所有遥测数据都已发送并且采样不会影响结果(至少对于每个微服务而言是单独的)。

所有项目都向 RabbitMQ 发布和订阅事件。

我有我自己的 rabbitmq nuget 包来简化对 RabbitMQ 的访问(它已经正常工作了一年多)。我添加了此代码以在发布事件时发送遥测标识符:

var operation = _telemetryClient.StartOperation<DependencyTelemetry>($"Publish {theEvent.EventName.Replace(".","-")}");
operation.Telemetry.Type = "Azure Service Bus"; // Just because I like the icon shown in Azure.
operation.Telemetry.Data = JsonConvert.SerializeObject(theEvent);
_basicProperties.Headers["x-telemetry-operationid"] = operation.Telemetry.Context.Operation.Id;
_basicProperties.Headers["x-telemetry-parentOperationId"] = operation.Telemetry.Id;
_channelProvider
     .GetChannel()
     .Basicpublish(_configuration.Exchange,theEvent.EventName,_basicProperties,Encoding.UTF8.GetBytes(payload));

我使用此代码在接收到事件时跟踪依赖项:

var operation = _telemetryClient.StartOperation<RequestTelemetry>($"Received {eventName.Replace(".","-")}");
operation.Telemetry.Context.Operation.Id = basicDeliverEventArgs.BasicProperties.Headers["x-telemetry-operationId"];
operation.Telemetry.Context.Operation.ParentId = basicDeliverEventArgs.BasicProperties.Headers["x-telemetry-operationId"];
// Handle the message...
_telemetryClient.StopOperation(operation);

当微服务收到POST请求时,会触发一个事件。其他几个微服务正在订阅它,它们也可以发布新事件,这将再次影响另一组微服务。当我点击 POST 请求时,我希望在 End-to-end transaction details 页面中看到所有内容

但不幸的是这并没有发生:(

我在交易搜索中查找了 POST 请求:

enter image description here

然后点击它:

enter image description here

您可以看到“event-one”是如何发布的以及one微服务如何接收它。但没有别的。

现在,如果我搜索事件名称,不仅可以找到发布跟踪,还可以找到更多反映微服务发布事件的依赖项:

enter image description here

如果我点击请求上方的那个,我就能更全面地了解整个交易:

enter image description here

但是,这里仍然缺少很多东西:每个微服务执行的所有 sql 调用,微服务在接收事件 2、3 和 4 时执行的所有操作。

实际上,所有内容都可以在应用程序地图中找到:

enter image description here

这意味着所有遥测都正确!

问题

  1. 我做的一切都正确吗?
  2. 有没有办法在端到端中显示完整的事件链?

提前致谢

解决方法

好的,我找到了。

问题

  1. 我试图告诉 AppInsights 在我自己的 rabbitmq 客户端库的小包装器中执行操作。
  2. 这样做时,我没有正确传递 OperationId(不需要父级)。

现在看来您不应该使用 StartOperation() 方法,而应该使用 TraceDependency() 方法。

正确的概念

但实际上,正确的方法是向要跟踪的组件添加检测。此检测是通过 System.Diagnostics 命名空间(ActivitiesDiagnosticListeners)完成的。

需要明确的是,RabbitMQ .NET client 是应该被检测的库,以便框架中的其他组件可以跟踪它在做什么。

此外,您将需要 IOBserver 来告诉 Application Insights 如何将这些 Activities 发送到 Azure。

修复

  1. 我在自己的包装器中删除了所有与 Application Insights 相关的代码。
  2. 我下载了 Microsoft.Azure.ServiceBus 的源代码。
  3. 我下载了 Microsoft.ApplicationInsights 的源代码。
  4. 我在自己的包装器中添加了一个 RabbitMQDiagnosticListener 类,其中包含方法 StartSendStartReceiveStop。该类中的代码是 实际上是从 Microsoft.Azure.ServiceBus 自己的复制粘贴 DiagnosticListeners
  5. 经过反复试验(调整属性)后,我让它工作了,现在请求正确显示了所有嵌套的依赖项调用。

正如你所看到的,我没有做观察者部分。这是因为我基本上是在复制 Microsoft.Azure.ServicesBus 发布 Activities 的方式。由于 Application Insights 自动跟踪 Microsoft.Azure.ServicesBus,它负责处理我的调用,并且在 Azure 中它实际上显示为 Azure ServiveBus,即使包含“队列中的时间花费”部分。

微软需要改进很多自己的文档,好像很不完整,没有更新。