Трассировка — это метод наблюдения за потоком запросов через распределённую систему, при котором каждый шаг обработки фиксируется в виде отдельного события с меткой времени. По данным OpenTelemetry, 2025, trace объединяет полный путь запроса от точки входа до финального ответа, проходя через все микросервисы и внешние вызовы. Это позволяет разработчикам выявлять узкие места, задержки и сбои в сложных архитектурах мобильных бэкендов.
Главное
Трассировка — это метод распределённого наблюдения, при котором каждый входящий запрос прослеживается через все сервисы и компоненты системы. В отличие от метрик, которые показывают агрегированные значения (среднее время ответа, количество ошибок), трассировка сохраняет полный контекст одного конкретного запроса.
Каждый шаг обработки — вызов базы данных, HTTP-запрос к другому микросервису, выполнение фоновой задачи — фиксируется как отдельная единица с меткой времени, статусом и атрибутами. По данным Google Dapper (оригинальная публикация 2010 года), трассировка позволяет локализовать задержки в распределённых системах с точностью до одного вызова.
Трассировка особенно важна для мобильных приложений, где бэкенд состоит из десятков микросервисов. Пользовательское действие — например, вход в аккаунт — может пройти через API Gateway, сервис аутентификации, базу данных и Push-сервис. Без трассировки определить, какой именно компонент тормозит ответ, практически невозможно.
Основная единица трассировки — span. Каждый span представляет одну логическую операцию: HTTP-запрос, SQL-запрос, вызов gRPC, сериализацию JSON. Span содержит уникальный идентификатор, родительский идентификатор, название операции, время начала, длительность, статус и набор атрибутов.
Все spans, относящиеся к одному корневому запросу, объединяются в trace. Корневой span (root span) представляет точку входа — HTTP-запрос от мобильного клиента к API. Дочерние spans образуют дерево, где каждый span ссылается на родителя через поле parent_span_id.
Длительность trace равна сумме длительностей уникальных временных отрезков всех spans. Если два дочерних span выполняются параллельно, их время не суммируется — это критически важно для правильного анализа задержек, вызванных параллельными вызовами микросервисов.
Каждый span может содержать атрибуты — пары ключ-значение с мета-информацией: URL запроса, ID пользователя, версия API, имя хоста. Атрибуты используются для фильтрации и группировки трасс. Кроме атрибутов, span поддерживает события — временные метки с текстовым описанием, например "кэш-промах" или "повторная попытка соединения".
Distributed tracing решает проблему связывания spans, которые создаются в разных процессах и на разных машинах. Механизм основан на контекстной передаче: при вызове сервиса B из сервиса A в исходящий запрос добавляется заголовок с идентификатором текущего trace и родительского span.
Стандартные протоколы передачи контекста — W3C Trace Context (заголовки traceparent и tracestate) и Zipkin B3 (заголовки X-B3-TraceId, X-B3-SpanId). W3C Trace Context принят как стандарт консорциумом W3C в 2021 году и поддерживается всеми основными провайдерами телеметрии.
При получении запроса сервис B извлекает trace_id из заголовка и создаёт дочерний span с этим trace_id. Таким образом, по завершении запроса все spans из разных сервисов объединяются в один trace на стороне коллектора. Для этого требуется, чтобы каждый сервис был инструментирован одной и той же библиотекой трассировки.
В мобильной разработке контекстная передача охватывает не только бэкенд, но и клиент-серверное взаимодействие. Мобильное приложение может отправлять trace_id в заголовке каждого API-запроса, позволяя связать клиентское действие с серверной обработкой. OpenTelemetry SDK для iOS и Android поддерживает автоматическое создание и передачу trace-контекста через HTTP-клиенты.
import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context
class TracingInterceptor : Interceptor {
private val tracer: Tracer = OpenTelemetry.getTracer("mobile-app")
override fun intercept(chain: Interceptor.Chain): Response {
val span = tracer.spanBuilder("HTTP POST /api/login")
.setParent(Context.current())
.startSpan()
return chain.proceed(chain.request())
.also { span.end() }
}
}
Представленный перехватчик на Kotlin создаёт span для каждого HTTP-запроса к серверу. Родительский контекст передаётся из вызывающего кода через Context.current(), что позволяет связать клиентскую трассировку с серверной.
OpenTelemetry — стандарт де-факто для сбора трассировочных данных. Он предоставляет единый API для генерации spans, автоматическую инструментацию популярных библиотек и гибкий механизм экспорта данных в различные бэкенды: Jaeger, Zipkin, Grafana Tempo, Datadog, New Relic.
OpenTelemetry поддерживает автоматическое создание spans для популярных фреймворков: Spring Boot, Ktor, Flask, Express, gRPC. Разработчику достаточно добавить зависимость в проект, и библиотека самостоятельно перехватывает входящие и исходящие запросы. Auto-instrumentation для Java использует javaagent, который модифицирует байт-код на лету без изменения исходников.
Для мобильных платформ OpenTelemetry предоставляет Swift SDK и Kotlin SDK. Они автоматически создают spans для сетевых запросов (URLSession, OkHttp), работы с базой данных (CoreData, Room) и фоновых задач. Разработчик может добавлять кастомные spans для бизнес-логики.
Собранные spans отправляются в коллектор через протокол OTLP (OpenTelemetry Protocol). Коллектор может буферизировать, фильтровать и перенаправлять данные в одну или несколько систем хранения. По данным документации OpenTelemetry, типичная задержка от генерации span до его отображения в дашборде составляет 2–5 секунд при использовании gRPC-экспорта.
import OpenTelemetryApi
import OpenTelemetrySdk
import URLSessionInstrumentation
let instrumentation = URLSessionInstrumentation()
instrumentation.enable()
let tracer = OpenTelemetry.instance.tracerFactory
.get("mobile-monitoring")
let span = tracer.spanBuilder("fetch-user-profile")
.setAttribute(key: "user.id", value: userId)
.startSpan()
span.end()
Код на Swift активирует автоматическую инструментацию сетевого слоя и создаёт кастомный span для операции получения профиля пользователя. Атрибут user.id позволяет впоследствии фильтровать трассы по конкретному пользователю.
В высоконагруженных системах трассировать каждый запрос невозможно — это создаёт неприемлемую нагрузку на хранилище и сеть. Сэмплирование решает эту проблему, сохраняя только часть трасс. Выбор стратегии напрямую влияет на полноту данных и стоимость инфраструктуры.
Решение о сохранении трассы принимается в момент её создания — в корневом span. Самый простой и распространённый подход: фиксированный процент запросов (например, 5%) сохраняется, остальные отбрасываются. Недостаток — невозможно гарантировать, что редкие ошибки будут захвачены. Probability sampler в OpenTelemetry поддерживает настройку вероятности от 0.0 до 1.0.
Решение откладывается до завершения всех spans трассы. Анализатор оценивает, содержит ли трасса ошибки, превышение времени или интересные атрибуты, и только тогда сохраняет её. Этот подход требует буферизации всех spans в коллекторе, что увеличивает потребление памяти. По данным Grafana Labs, tail-based sampling на 40–60% эффективнее по соотношению "цена за полезные данные" в системах с редкими, но критичными ошибками.
| Стратегия | Плюсы | Минусы |
|---|---|---|
| Fixed probability | Простота, предсказуемая нагрузка | Пропускает редкие события |
| Rate limiting | Гарантированный объём данных | Неравномерное покрытие |
| Tail-based | Захват всех ошибок | Высокое потребление памяти |
| Adaptive | Баланс стоимости и покрытия | Сложность настройки |
Логирование фиксирует отдельные события с уровнем важности (info, warn, error), но не связывает их в контекст одного запроса. Трассировка, напротив, создаёт структурированное дерево операций, принадлежащих одному сквозному запросу. На практике эти два подхода не взаимоисключают, а дополняют друг друга.
Логи эффективны для детального анализа конкретной ошибки: разработчик видит точное сообщение, стектрейс, значение переменных. Трассировка даёт ответ на вопрос "почему запрос выполняется 5 секунд" — показывает, какой именно микросервис или вызов занял больше всего времени. По данным Honeycomb (2024), команды, использующие трассировку совместно с логированием, находят корневую причину инцидентов в 2.3 раза быстрее.
Современный подход — observability — объединяет трассировку, метрики и логи в единую систему. OpenTelemetry поддерживает корреляцию между этими тремя сигналами: каждый span может содержать ссылки на связанные логи, а метрики могут быть размечены по trace_id для перехода к конкретным трассам.
Часто задаваемые вопросы
Мониторинг показывает агрегированные метрики системы — среднее время ответа, количество ошибок в минуту, загрузку CPU. Трассировка показывает путь одного конкретного запроса через все компоненты. Мониторинг отвечает "что происходит", трассировка — "почему это происходит".
Для production-систем достаточно 1–5% запросов при head-based sampling. Если система редко выдаёт ошибки, рекомендуется tail-based sampling с фокусом на захват всех ошибочных трасс. Для staging-окружения допустимо трассировать 100% запросов без ограничений.
Основные инструменты: Jaeger (решение от Uber, открытый исходный код), Grafana Tempo (масштабируемое хранилище трасс), Datadog APM, New Relic Distributed Tracing, AWS X-Ray и Honeycomb. Все они поддерживают стандарт OpenTelemetry для приёма данных.
Да, локальная трассировка работает внутри одного процесса. OpenTelemetry SDK для iOS и Android создаёт spans для локальных операций: чтение из базы данных, обработка изображений, сетевые запросы. Такие трассы не распределённые, но полезны для диагностики производительности клиентской части.
Современные библиотеки трассировки добавляют менее 1% накладных расходов при head-based sampling. OpenTelemetry использует асинхронный экспорт данных, который не блокирует основной поток. Для мобильных устройств рекомендуется ограничить частоту создания spans и использовать стратегию адаптивного сэмплирования.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также