GH GambleHub

Distributed Tracing: OpenTelemetry

Distributed Tracing: OpenTelemetry

1) Навіщо OTel і що він дає

OpenTelemetry (OTel) - відкритий стандарт і набір SDK/агентів/колекторів для телеметрії (трейси, метрики, логи) з єдиним протоколом OTLP. Цілі:
  • Наскрізна видимість шляхів запиту (gateway → сервіси → БД/кеш/черги).
  • Швидка RCA/налагодження деградацій і релізів (канарок/blue-green).
  • Зв'язка з SLO і авто-відкатами (операційні рішення на даних).
  • Вендор-агностичність: експорт в будь-який бекенд, без прив'язки до одного APM.

Опорні принципи: standardize, sample smart, secure by default, correlate everything.

2) Основи: контекст, спани, атрибути

Trace - дерево/граф викликів; Span - операція (RPC, SQL, виклик черги).
Span Kind: `SERVER`, `CLIENT`, `PRODUCER`, `CONSUMER`, `INTERNAL`.
W3C Trace Context: заголовки «traceparent», «tracestate»; контекст переноситься міжсервісно.
Attributes - ключ-значення (низька кардинальність!), Events - мітки в часі, Status - код/опис помилки.
Links - зв'язок спанів поза суворої ієрархії (важливо для async/fan-out/fan-in).

Іменування спанів:
  • HTTP: 'HTTP {METHOD}'('GET/withdraw'як атрибут)
  • DB: `DB SELECT` / `DB INSERT`
  • Queue: `QUEUE publish topic=X` / `QUEUE consume topic=X`

3) Семантичні конвенції (semconv)

Використовуйте стабільні схеми атрибутів:
  • HTTP/GRPC: `http. method`, `http. route`, `http. status_code`, `url. full`.
  • DB: `db. system=postgresql`, `db. statement'( тільки безпечна вичавка!),'db. name`.
  • Messaging: `messaging. system=kafka`, `messaging. operation=receive`, `messaging. destination`.
  • Cloud/K8s/Host: `cloud. region`, `k8s. pod. name`, `container. id`.
  • Resource attributes (обов'язково): `service. name`, `service. version`, `deployment. environment`.

Стабільність схеми вказуйте через'schemaUrl'в ресурсах SDK/Collector.

4) Семплінг: head, tail, adaptive

Head-based (в SDK): вирішує заздалегідь, дешево; добре для high-QPS, але може пропустити «цікаві» траси.
Tail-based (в Collector): вирішує після завершення траси; дозволяє правила щодо статусу, латентності, атрибутів.
Adaptive/Динамічний: піднімає частку семпла при помилках/зростанні p95.

Рецепт прод-рівня: Head 1-5% глобально + Tail відбір «важливого»: 'status = ERROR','latency> p95', «грошові маршрути», помилки PSP/KYC.

5) Кореляція: метрики, логи, трейси

Exemplars: мітки з'trace _ id'в гістограмах метрик (швидкий стрибок до траси).
Логи: додавайте'trace _ id '/' span _ id'і перемикайтеся з логів в трасу.
SpanMetrics (processor): агрегує з трас RED-метрики ('requests, errors, duration') для SLO/алертів.

6) Архітектура розгортання

Agent (DaemonSet) на кожному вузлі збирає з додатків (OTLP) і форвардит.
Gateway (Cluster/Region) - центральний Collector (багато реплік) з пайплайнами маршрутизації/семплінгу/збагачення.
OTLP: gRPC `4317`, HTTP `4318`; вмикайте TLS/mTLS.

Плюси «agent + gateway»: ізоляція, буферизація, локальний backpressure, спрощена мережа.

7) OpenTelemetry Collector - базовий шаблон (gateway)

yaml receivers:
otlp:
protocols:
grpc: { endpoint: 0. 0. 0. 0:4317 }
http: { endpoint: 0. 0. 0. 0:4318 }

processors:
memory_limiter: { check_interval: 5s, limit_percentage: 75 }
batch: { timeout: 2s, send_batch_size: 8192 }
attributes:
actions:
- key: deployment. environment action: upsert value: prod resource:
attributes:
- key: service. namespace action: upsert value: core tail_sampling:
decision_wait: 5s policies:
- name: errors type: status_code status_code: { status_codes: [ERROR] }
- name: slow_traces type: latency latency: { threshold_ms: 800 }
- name: important_routes type: string_attribute string_attribute:
key: http. route values: ["/withdraw", "/deposit"]
- name: baseline_prob type: probabilistic probabilistic: { sampling_percentage: 5 }

exporters:
otlp/apm:
endpoint: apm-backend:4317 tls: { insecure: true }
prometheus:
endpoint: 0. 0. 0. 0:9464

extensions:
health_check: {}
pprof: { endpoint: 0. 0. 0. 0:1777 }
zpages: { endpoint: 0. 0. 0. 0:55679 }

service:
extensions: [health_check, pprof, zpages]
pipelines:
traces:  { receivers: [otlp], processors: [memory_limiter,attributes,resource,batch,tail_sampling], exporters: [otlp/apm] }
metrics: { receivers: [otlp], processors: [batch], exporters: [prometheus] }
logs:   { receivers: [otlp], processors: [batch], exporters: [] }

8) SpanMetrics і RED для SLO

Додайте процесор:
yaml processors:
spanmetrics:
metrics_exporter: prometheus histogram:
explicit:
buckets: [50ms,100ms,200ms,400ms,800ms,1600ms,3200ms]
service:
pipelines:
traces: { receivers: [otlp], processors: [spanmetrics,batch,tail_sampling], exporters: [otlp/apm] }
metrics: { receivers: [otlp], processors: [batch], exporters: [prometheus] }

Тепер є'traces _ spanmetrics _ calls {service, route, code}'і'duration _ bucket'для SLO/алертів.

9) K8s: розгортання Collector (DaemonSet + Deployment)

Agent (DaemonSet) фрагмент:
yaml apiVersion: apps/v1 kind: DaemonSet metadata: { name: otel-agent, namespace: observability }
spec:
template:
spec:
containers:
- name: otelcol image: otel/opentelemetry-collector:latest args: ["--config=/conf/agent. yaml"]
ports:
- { containerPort: 4317, name: otlp-grpc }
- { containerPort: 4318, name: otlp-http }

Gateway (Deployment) - кілька реплік, Service ClusterIP/Ingress, HPA по CPU/QPS.

10) Безпека і приватність

TLS/mTLS между SDK → Agent → Gateway → Backend.
Автентифікація (Basic/OAuth/Headers) на вході Gateway; обмежуйте витоки.
Редакція PII: фільтруйте/маскуйте атрибути ('user. email','card.') в процесорі Collector.
Ліміти: в SDK обмежте розмір події/число атрибутів (захист від кардинальності).
RBAC в бекенді + окремі неймспейси проектів/тенантів.

Приклад фільтра в Collector:
yaml processors:
attributes/redact:
actions:
- key: user. email action: delete
- key: payment. card action: delete

11) Інструментування: Швидкі старти

Node. js

js import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-grpc";
import { Resource } from "@opentelemetry/resources";
import { SemanticResourceAttributes as R } from "@opentelemetry/semantic-conventions";

const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({ url: "http://otel-agent. observability:4317" }),
resource: new Resource({
[R.SERVICE_NAME]: "payments-api",
[R.SERVICE_VERSION]: "1. 14. 2",
[R.DEPLOYMENT_ENVIRONMENT]: "prod"
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk. start();

Java (Spring)

java
// Gradle: io. opentelemetry. instrumentation:opentelemetry-spring-boot-starter
// application. yml otel:
service:
name: orders-api exporter:
otlp:
endpoint: http://otel-agent. observability:4317 traces:
sampler: parentbased_traceidratio sampler-arg: 0. 05

Python (FastAPI)

python from opentelemetry import trace from opentelemetry. sdk. resources import Resource from opentelemetry. exporter. otlp. proto. grpc. trace_exporter import OTLPSpanExporter from opentelemetry. sdk. trace import TracerProvider from opentelemetry. sdk. trace. export import BatchSpanProcessor

provider = TracerProvider(resource=Resource. create({"service. name":"fraud-scoring","deployment. environment":"prod"}))
provider. add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint="http://otel-agent. observability:4317", insecure=True)))
trace. set_tracer_provider(provider)

Go

go exp, _:= otlptracegrpc. New(ctx, otlptracegrpc. WithEndpoint("otel-agent. observability:4317"), otlptracegrpc. WithInsecure())
res:= resource. NewWithAttributes(semconv. SchemaURL, semconv. ServiceNameKey. String("gateway"), semconv. DeploymentEnvironmentKey. String("prod"))
tp:= sdktrace. NewTracerProvider(sdktrace. WithBatcher(exp), sdktrace. WithResource(res), sdktrace. WithSampler(sdktrace. ParentBased(sdktrace. TraceIDRatioBased(0. 05))))
otel. SetTracerProvider(tp)

12) Асинхронщина: черги, шини, cron

PRODUCER/CONSUMER зі зв'язком через'links'( у повідомлень свій життєвий цикл).
Пропагуйте контекст у заголовки повідомлень («traceparent »/« baggage»).
При batch-consume створюйте по спану на повідомлення або агрегуйте з атрибутом'messaging. batch. size`.
Для cron/джобів: новий trace на запуск + links до первинних подій (якщо є).

13) Baggage і таргетинг

Зберігайте мінімум стабільних ключів ('tenant _ id','region','vip _ tier') в baggage; забороняйте PII.
Прокидайте через gateway/gateway-логгер для подальшої агрегації метрик по сегментах.

14) Інтеграція з релізами та SLO-гейтингом

Канарські кроки → перевіряйте'traces _ spanmetrics _'за маршрутами/юз-сегментами.
При деградації (5xx/p95) - авто-стоп і відкат (Argo Rollouts AnalysisTemplate + PromQL).
Екземпляри з метрик ведуть безпосередньо в «погані» траси релізного інтервалу.

15) Ліміти та продуктивність

Обмежуйте: `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT`, `OTEL_SPAN_EVENT_COUNT_LIMIT`, `OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT`.
Семплюйте винятки/stacktrace по ймовірності/частоті.
Batch-процесор в SDK і Collector; тримайте черги, щоб не втрачати траси при сплесках.

16) Сумісність та міграції

Пропагандатори: використовуйте W3C; підтримайте читання B3/X-Ray при міграції (dual-propagation).
Експорт: OTLP → APM (Jaeger/Tempo/Elastic/X-Ray и т. п.).
Стабільні версії semconv - фіксуйте'schemaUrl'і плануйте апгрейди.

17) Анти-патерни

Висока кардинальність атрибутів ('user _ id'в label, динамічні ключі).
Логи без'trace _ id'→ немає кореляції.
Експорт безпосередньо з додатків в інтернет-APM (без gateway, без TLS/mTLS).
Збір «всього» 100% в проді - дорого і безглуздо.
Дампи SQL-запитів з даними користувача в'db. statement`.
Неузгоджене ім'я сервісу/версії - метрики «розсипаються».

18) Чек-лист впровадження (0-45 днів)

0-10 днів

Включити SDK/автоінструментування на 2-3 критичних сервісах.
Налаштувати Agent (DaemonSet) + Gateway (Deployment), OTLP 4317/4318 з TLS.
Додати'service. name`, `service. version`, `deployment. environment'всюди.

11-25 днів

Tail-sampling помилково/латентності/» грошових» маршрутів.
SpanMetrics → Prometheus, включити Exemplars і дашборди RED/SLO.
Пропагувати W3C через API-шлюз/NGINX/mesh; корелювати логи.

26-45 днів

Покрити черги/БД/кеш; links для async.
Політики PII-редакції в Collector; ліміти атрибутів в SDK.
Інтегрувати SLO-гейтинг релізів і авто-відкат.

19) Метрики зрілості

Покриття вхідних запитів трасуванням ≥ 95% (з урахуванням sampling head/tail).
Частка метрик з Exemplars ≥ 80%.
Час RCA «з метрики в трасу» ≤ 2 хв (p50).
0 витоків PII в атрибутах/подіях (сканер).
Всі сервіси мають'service. name/version/environment'і узгоджену семантику.

20) Додатки: Корисні фрагменти

NGINX пропагандація:
nginx proxy_set_header traceparent $http_traceparent;
proxy_set_header tracestate $http_tracestate;
proxy_set_header baggage   $http_baggage;
Prometheus с Exemplars (Grafana):

histogram_quantile(0. 95, sum(rate(traces_spanmetrics_duration_bucket{route="/withdraw"}[5m])) by (le))

Policy: заборона PII-атрибутів (псевдо-лінтер)

yaml forbid_attributes:
- user. email
- payment. card
- personal.

21) Висновок

OpenTelemetry перетворює спостережуваність в стандартизований, керований контур: єдина семантика, безпечна пропагандація, розумний семплінг і сильна кореляція з метриками і логами. Вибудовуйте agent + gateway, додавайте tail-sampling, spanmetrics і Exemplars, стежте за PII і кардинальністю - і трасування стане інструментом не тільки для налагодження, але і для автоматизованих рішень SRE/Release, скорочуючи MTTR і ризики при кожному релізі.

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Telegram
@Gamble_GC
Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.