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

Azure Application Insights not showing the whole chain of events (in event-driven app), but all telemetry is there

场景

我在 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 请求:

然后点击它:

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

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

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

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

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

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

问题

  1. 我做的每件事都正确吗?
  2. 有没有办法在 End-To-End 中显示完整的事件链?

提前致谢

好的,我找到了。

问题

  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 class 到我自己的包装器,使用方法 StartSendStartReceiveStop。 class 里面的代码是 实际上是 Microsoft.Azure.ServiceBus 自己的复制粘贴 DiagnosticListeners.
  5. 经过一些尝试和错误(调整属性)后,我让它工作了,现在请求正确显示了所有嵌套的依赖项调用。

如您所见,我没有做观察员部分。这是因为我基本上是在复制 Microsoft.Azure.ServicesBus 发布 Activities 的方式。由于 Application Insights 自动跟踪 Microsoft.Azure.ServicesBus,它正在处理我的调用,在 Azure 中它实际上显示为 Azure ServiveBus,即使是“排队时间”部分也是如此。

Git 存储库:https://github.com/JoanComasFdz/dotnet-rabbitmq-client-instrumentation-app-insights

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