#.net #azure #rabbitmq #azure-application-insights #distributed-tracing
#.net #azure #rabbitmq #azure-application-insights #распределенная трассировка
Вопрос:
Сценарий
У меня есть контейнерное приложение microservices, управляемое событиями, в ASP .NET Core, только что перенесенное на .NET 5.
Все проекты используют Microsoft.ApplicationInsights 2.16.0, и я проверил, что вся телеметрия отправляется, а выборка не влияет на результаты (по крайней мере, индивидуально для каждой микросервиса).
Все проекты публикуют и подписывают события на RabbitMQ.
У меня есть собственный пакет nuget rabbitmq для облегчения доступа к 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 в поиске транзакций:
Вы можете видеть, как публикуется «событие-один» и как его получает одна микросервисная служба. Но больше ничего.
Теперь, если я ищу имя события, я нахожу не только трассировку публикации, но и другие зависимости, отражающие события, опубликованные микрослужбой:
Если я нажму на запрос над запросом, я получу более полное представление обо всей транзакции:
Но все же здесь многого не хватает: все вызовы SQL, выполненные каждой микросервисом, все действия, которые выполняли микросервисы при получении событий два, три и четыре.
И на самом деле, все это доступно в карте приложений:
Это означает, что вся телеметрия есть правильно!
Вопросы
- Я все делаю правильно?
- Есть ли способ показать полную цепочку событий в сквозном режиме?
Заранее спасибо
Комментарии:
1. Вы исключили возможность задержки в сети, сэр? Ваш вопрос сложно воспроизвести на другой стороне, поэтому его действительно сложно устранить.
2. Да, хороший момент, поэтому сейчас я тестирую его только на своей машине. Обычно требуется от 3 до 5 минут, чтобы телеметрия появилась в AI. Я работал над этой проблемой пару дней, и результаты всегда одни и те же. Кроме того, Карта приложений показывает все вызовы служб. Я добавлю диаграмму к исходному вопросу.
Ответ №1:
Итак, я нашел его.
Проблема
- Я пытался сказать AppInsights выполнять операции в моей собственной маленькой оболочке для клиентской библиотеки rabbitmq.
- Делая это, я неправильно передавал OperationId (родительский элемент не нужен).
Похоже, в наши дни вам все равно следует использовать не этот StartOperation()
метод, а только TraceDependency()
один.
Правильная концепция
Но на самом деле правильный способ сделать это — добавить инструментарий к компоненту, который вы хотите отслеживать. Это инструментирование выполняется через System.Diagnostics
пространство имен ( Activities
и DiagnosticListeners
).
Просто для ясности, клиент RabbitMQ .NET — это библиотека, которую следует использовать, чтобы другие компоненты платформы могли отслеживать, что она делает.
Кроме того, вам понадобится IOBserver
s, чтобы сообщить Application Insights, как отправить их Activities
в Azure.
Исправить
- Я удалил весь код, связанный с Application Insights, в моей собственной оболочке.
- Я скачал исходный код Microsoft.Azure.ServiceBus.
- Я скачал исходный код Microsoft.ApplicationInsights.
- Я добавил
RabbitMQDiagnosticListener
класс в свою собственную оболочку с методамиStartSend
StartReceive
иStop
. Код внутри этого класса был практически копипастом изMicrosoft.Azure.ServiceBus
собственногоDiagnosticListeners
. - После некоторых проб и ошибок (для настройки свойств) я заработал, и теперь запросы правильно отображают все вызовы вложенных зависимостей.
Как вы можете видеть, я не выполнял часть наблюдателей. Это потому, что я в основном копирую способ Microsoft.Azure.ServicesBus
публикации Activities
. Поскольку Application Insights отслеживает автоматически Microsoft.Azure.ServicesBus
, он обрабатывает мои вызовы, и в Azure он фактически отображается как Azure ServiveBus даже с частью «Время, проведенное в очереди».
Репозиторий Git: https://github.com/JoanComasFdz/dotnet-rabbitmq-client-instrumentation-app-insights
Microsoft необходимо значительно улучшить свою собственную документацию, которая кажется очень неполной и не обновляется.