首页 > 解决方案 > 如何关联通过 NServiceBus 通信的两个 AppInsights 资源?

问题描述

目前,我在各种机器上托管了数十个 .NET 服务,这些服务在我的 AppInsights 应用程序地图上显示为资源,它还根据它们发出的 HTTP 请求显示它们彼此之间的依赖关系。

但是,没有显示通过 NServiceBus (RabbitMQ) 进行通信的服务之间的关系。现在,我可以显示服务通过调用发送或处理的消息TelemetryClient.TrackXXX(),但不能使用此信息连接地图上的资源。

我什至将 NSB 消息发送方的父操作 ID 附加到消息本身,并将其分配给接收方中的遥测对象,但应用程序映射中的服务之间仍然没有划清界限。

重申一下,这就是我在应用程序地图中得到的:

(NSB Message Sender) --> (Message sent/handled)

这就是我想要的:

(NSB Sender) --> (Receiver)

有问题的服务是 .NET Core 3.1。

我无法提供代码,因为这是我的工作,但任何帮助将不胜感激。我到处搜索过,即使是看起来有帮助的来源,也没有。

标签: .net-coreazure-application-insightsnservicebus

解决方案


(未登录,下班发帖)

好吧,我终于明白了。我使用它们的 NSB 通信关联 AppInsights 资源的方法是模拟 HTTP 遥测关联。

下面是我为 AppInsights 的 TelemetryClient 编写的扩展方法。鉴于我的应用程序使用 RBMQ,我创建了一个名为 RbmqMessage:NServiceBus.IMessage 的子类,并为相关性提供了以下属性(所有设置在发送消息的服务中):

  • parentId:等于 DependencyTelemetry.Id
  • opId:发送者的DependencyTelemetry和接收者的RequestTelemetry中的值相同。等于 telemetry.context.operation.id
  • startTime: DateTime.Now 对我的目的来说已经足够好了

发送 NSB 消息的服务中的代码:

 public static RbmqMessage TrackRbmq(this TelemetryClient client, RbmqMessage message)
  {
          var msg = message;
          // I ran into some issues with Reflection
          var classNameIdx = message.ToString().LastIndexOf('.') + 1;
          var messageClassName = message.ToString().Substring(classNameIdx);
          var telemetry = new DependencyTelemetry
          {   
                  Type = "RabbitMQ", 
                  Data = "SEND "+messageClassName,
                  Name = "SEND "+messageClassName,
                  Timestamp = DateTime.Now,
                  Target = "RECEIVE "+messageClassName  //matches name in the service receiving this message
           };
           client.TrackDependency(telemetry);
           msg.parentId = telemetry.Id;
           msg.opId = telemetry.Context.Operation.Id; //this wont have a value until TrackDependency is called
           msg.startTime = telemetry.Timestamp;
    
      return msg;
 }

您发送 NSB 消息的代码:

 var msg = new MyMessage();   //make your existing messages inherit RbmqMessage
 var correlatedMessage = _telemetryClient.TrackRbmq(msg);
 MessageSession.Publish(correlatedMessage);   //or however the NSB message goes out in your application

NServiceBus消息接收服务中的扩展方法:

   public static void TrackRbmq(this TelemetryClient client, RbmqMessage message)
  {
       var classnameIdx = message.ToString().LastIndexOf('.')+1;
       var telemetry = new RequestTelemetry
       {
             Timestamp = DateTime.Now,
             Name = "RECEIVE "+message.ToString().Substring(classNameIdx)
       };
       telemetry.Context.Operation.ParentId = message.parentId;
       telemetry.Context.Operation.Id = message.opId;
       telemetry.Duration = message.startTime - telemetry.Timestamp;
       client.TrackRequest(telemetry);
 }

最后,只需跟踪并发送消息:

 var msg = new MyMessage();
 _telemetryClient.TrackRbmq(msg);
 MessagePipeline.Send(msg);  //or however its sent in your app

我希望这可以避免我遇到的麻烦。


推荐阅读