首页 > 解决方案 > 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 请求时,我希望在端到端交易详细信息页面中看到这一切。

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

我在事务搜索中寻找 POST 请求: 在此处输入图像描述

并点击它: 在此处输入图像描述

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

现在,如果我搜索事件名称,我不仅会找到发布跟踪,还可以找到更多反映微服务发布的事件的依赖项: 在此处输入图像描述

如果我单击请求上方的那个,那么我可以更全面地了解整个事务: 在此处输入图像描述

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

实际上,所有这些都在 Application Map 中可用: 在此处输入图像描述

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

问题

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

提前致谢

标签: .netazurerabbitmqazure-application-insightsdistributed-tracing

解决方案


好的,所以我找到了。

问题

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

看起来现在你不应该使用这种StartOperation()方法,但TraceDependency()无论如何只能使用一种。

正确的概念

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

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

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

使固定

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

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

微软需要改进很多自己的文档,似乎很不完整而且没有更新。


推荐阅读