#.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) идентификатора телеметрии? В противном случае я бы сохранил идентификатор в заголовках сообщений, а не в самом теле сообщения.