Для чего нужен trace request?
Что проверяют
Понимаете ли вы, как проследить один запрос через несколько сервисов и чем трассировка отличается от логов. Если интервьюер имел в виду HTTP-метод TRACE, уточните это сразу: сервер возвращает клиенту полученный запрос для диагностики, и на проде метод обычно отключают из-за атаки Cross-Site Tracing.
Как отвечать
В .NET под трассировкой запроса понимают распределённую трассировку:
- trace и span: trace это весь путь запроса, span это отдельная операция в нём (обработка в контроллере, SQL-запрос, вызов соседнего сервиса) с временем начала, длительностью и атрибутами;
Activity: встроенная реализация span изSystem.Diagnostics. ASP.NET Core создаётActivityна каждый входящий запрос,HttpClientсоздаёт дочернюю на исходящий и сам добавляет заголовок;- W3C Trace Context: формат по умолчанию начиная с .NET 5. Контекст едет в заголовке
traceparent, поэтому идентификатор сохраняется между сервисами на разных языках; - OpenTelemetry: пакет
OpenTelemetry.Extensions.Hostingи инструментации для ASP.NET Core,HttpClient, EF Core. Экспорт по OTLP в Jaeger, Grafana Tempo или облачный бэкенд; - связь с логами:
TraceIdиSpanIdпопадают в scopeILoggerчерезActivityTrackingOptions, и по одному идентификатору вы находите и логи, и трассу. Свои операции оборачивают вActivitySource.StartActivity.
Зачем всё это: увидеть, в каком звене теряется время, найти причину ошибки на стыке сервисов и вернуть пользователю traceId в ответе с ошибкой, чтобы поддержка нашла запрос.
Где спотыкаются
Отвечают «подключим Serilog». Serilog и NLog пишут логи, а трассу со спанами и их вложенностью строит OpenTelemetry. Они дополняют друг друга, но не заменяют.
Теряют контекст на асинхронных границах: сообщение ушло в Kafka или RabbitMQ без traceparent в заголовках, и трасса обрывается на продюсере.
Под высокой нагрузкой пишут каждый запрос и складывают в атрибуты тела запросов. Нужны сэмплирование и фильтр персональных данных.