Как соотнести два ресурса AppInsights, которые взаимодействуют через NServiceBus?

#.net-core #azure-application-insights #nservicebus

Вопрос:

В настоящее время у меня есть десятки служб .NET, размещенных на различных компьютерах, которые отображаются в качестве ресурсов на моей карте приложений AppInsights, которая также показывает их зависимости друг от друга на основе HTTP-запросов, которые они делают.

Однако отношения между службами, которые взаимодействуют через NServiceBus (RabbitMQ), не отображаются. Теперь я могу отображать сообщения, которые либо отправляются , либо обрабатываются службой с помощью вызовов TelemetryClient.TrackXXX() , но не подключать ресурсы на карте, используя эту информацию.

Я даже зашел так далеко, что прикрепил идентификатор родительской операции от отправителя сообщения NSB к самому сообщению и назначил его объекту телеметрии в получателе, но на карте приложения все еще нет линии, проведенной между службами.

Повторяю, это то, что я получаю на карте приложения:

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

И это то, чего я хочу:

 (NSB Sender) --> (Receiver)
 

Рассматриваемые службы являются .NET Core 3.1.

Я не могу предоставить код, так как это для моей работы, но буду очень признателен за любую помощь. Я искал везде, и даже источники, которые, казалось, могли бы помочь, не помогли.

Комментарии:

1. Вы смотрели эту серию?

2. Вы можете обратиться к Построение сквозной диагностики: Визуализация с помощью экспортеров и Сопоставьте два ресурса AppInsights на основе связи NServiceBus

3. @deepdave эта вторая ссылка-это вопрос, опубликованный мной на досках сообщества azure…

4. @Sean Я не думаю, что для этого требуется углубляться в материал OpenTelemetry под капотом. Наши услуги автоматически инструментируются с помощью вызова служб. AddApplicationInsightsTelemetry(), с такими вещами, как вызовы NSB, которые обрабатываются вручную

Ответ №1:

(не вошел в систему, отправил с работы)

Ладно, наконец-то я понял. Мой подход к корреляции ресурсов AppInsights с использованием их связи NSB заключается в том, чтобы имитировать корреляцию телеметрии HTTP.

Ниже приведен метод расширения, который я написал для TelemetryClient AppInsights. Я создал подкласс с именем RbmqMessage:NServiceBus.iMessage, учитывая, что мои приложения используют RBMQ, и дал ему следующие свойства для корреляции (все задано в службе, которая отправляет сообщение) :

  • Родитель: равен DependencyTelemetry.Id
  • opId: значение одинаково в параметре зависимости отправителя и в параметре запроса получателя. Равно telemetry.context.operation.id
  • Время начала: дата-время.Сейчас было достаточно хорошо для моих целей

Код в службе, отправляющей сообщение 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
 

Я надеюсь, что это избавит кого-то от неприятностей, через которые я прошел.

Комментарии:

1. Привет, я не знаю, как выглядит идентификатор телеметрии, но NServiceBus хранит идентификатор беседы и идентификатор корреляции внутри каждого отдельного сообщения в заголовках сообщений. Можно ли было бы использовать это вместо создания собственного (или создания клиентской библиотеки appinsights) идентификатора телеметрии? В противном случае я бы сохранил идентификатор в заголовках сообщений, а не в самом теле сообщения.