Короткий ответ
Схема должна передавать context через W3C Trace Context заголовки между всеми сервисами и применять sampling — например, 100% для ошибок и медленных запросов, но лишь небольшой процент для обычных успешных; точный процент зависит от объёма трафика и бюджета на хранение.
Как это работает подробнее
OpenTelemetry SDK создаёт spans в каждом сервисе; context propagation передаёт trace id и флаг сэмплирования в заголовках следующего вызова — решение принимается либо один раз на входе (head-based), либо коллектором после сбора всех spans (tail-based, требующий буферизации).
Пример кода
config.yaml
processors:
tail_sampling:
policies:
- name: errors-always
type: status_code
status_code: { status_codes: [ERROR] }
- name: slow-requests
type: latency
latency: { threshold_ms: 500 }
- name: baseline-rate
type: probabilistic
probabilistic: { sampling_percentage: 5 }Что использовать на практике
- Рекомендация. head-based проще и дешевле, но может не засэмплировать редкую важную ошибку; tail-based через Collector с политикой «сохранить трассу при ошибке или высокой latency» даёт лучшую видимость, но требует дополнительной инфраструктуры.
- Компромисс. высокий процент сэмплирования даёт полную видимость, но дорог в хранении; низкий процент дешевле, но рискует упустить редкие инциденты без tail-based правил. Выбор между head- и tail-based зависит от готовности держать отдельный Collector-слой и бюджета на инфраструктуру.
Подводные камни
- Риск. включить 100% сэмплирование «чтобы видеть всё» без расчёта объёма хранения — быстро становится неподъёмным; не передавать context через асинхронные брокеры сообщений, разрывая трассировку на границе очереди.