Коли клієнт каже «вчора о 15:00 оформлення замовлення гальмувало», скільки часу потрібно вашій команді, щоб з'ясувати чому? Коли логи розкидані по сервісах, а метрики — на окремому дашборді, відповідь часто «години, якщо взагалі вдасться». Observability — це здатність ставити нові запитання до працюючої системи без деплою нового коду. OpenTelemetry став стандартним шляхом до цього: одна відкрита специфікація і набір SDK для трейсів, метрик і логів, які підтримують практично всі вендори моніторингу й open-source бекенди. У гайді — як це працює, як інструментувати сервіси на Java і Node.js і як зробити дані корисними та доступними за ціною.
Чому OpenTelemetry
До OpenTelemetry кожен вендор моніторингу мав власні агенти й SDK. Зміна вендора означала переінструментування всього. OpenTelemetry — проєкт CNCF, що виник зі злиття OpenTracing і OpenCensus, — відокремлює інструментування від бекендів (CNCF: OpenTelemetry; документація OpenTelemetry):
- Ви інструментуєте один раз через API, SDK та автоінструментування OpenTelemetry.
- Дані передаються стандартним протоколом OTLP (специфікація OTLP).
- Надсилаєте їх у будь-який бекенд: open-source стеки на кшталт Grafana Tempo, Prometheus чи VictoriaMetrics і Loki або комерційні платформи — і можете змінити рішення пізніше.
Три сигнали (і четвертий)
| Сигнал | Відповідає на запитання | Приклад |
|---|---|---|
| Трейси | Де цей запит витратив час, через усі сервіси? | Checkout → API платежів забрав 2,1 с із 2,4 с |
| Метрики | Як система поводиться загалом? | p95-затримка, частка помилок, глибина черги |
| Логи | Що саме сталося в цей момент? | «Платіж відхилено: недостатньо коштів» |
| Профілі | Який код споживав CPU чи пам'ять? | Найновіший сигнал, ще в розробці |
Сила — у кореляції: рядок логу містить ID трейсу, тож ви переходите з повільного трейсу до точних логів цього запиту, а зі сплеску метрики — до прикладів трейсів (OpenTelemetry: signals).
Зрілість залежить від мови. У Java трейси, метрики й логи стабільні; у JavaScript і Python трейси й метрики стабільні, а логи ще в розробці; профілі в розробці (статус OpenTelemetry). Перш ніж покладатися на сигнал, перевірте статус для свого стеку.
Архітектура: SDK, Collector, бекенди
[Сервіс A] ─┐
[Сервіс B] ─┼── OTLP ──> [OpenTelemetry Collector] ──> трейси → Tempo / Jaeger / вендор
[Сервіс C] ─┘ (прийом, обробка, експорт) ──> метрики → Prometheus / VictoriaMetrics
──> логи → Loki / OpenSearch
Collector — вендор-нейтральний проксі, що приймає телеметрію, обробляє її — пакетує, фільтрує, семплює, прибирає чутливі атрибути — і експортує в один чи кілька бекендів (OpenTelemetry Collector). Запускайте його агентом поруч із сервісами (DaemonSet у Kubernetes) і за потреби — центральним шлюзом. Тоді зміна бекенду — це зміна конфігурації Collector, а не коду застосунку.
# otel-collector.yaml (фрагмент)
receivers:
otlp:
protocols: { grpc: {}, http: {} }
processors:
batch: {}
attributes/scrub:
actions:
- key: http.request.header.authorization
action: delete
tail_sampling:
policies:
- { name: errors, type: status_code, status_code: { status_codes: [ERROR] } }
- { name: slow, type: latency, latency: { threshold_ms: 1000 } }
- { name: baseline, type: probabilistic, probabilistic: { sampling_percentage: 10 } }
exporters:
otlphttp/tempo: { endpoint: http://tempo:4318 }
prometheusremotewrite: { endpoint: http://victoriametrics:8428/api/v1/write }
service:
pipelines:
traces: { receivers: [otlp], processors: [attributes/scrub, tail_sampling, batch], exporters: [otlphttp/tempo] }
metrics: { receivers: [otlp], processors: [batch], exporters: [prometheusremotewrite] }
Інструментування сервісів
Java і Spring Boot
Java-агент OpenTelemetry інструментує поширені бібліотеки — HTTP-сервери й клієнти, JDBC, Kafka, gRPC, Redis — без змін у коді (Java agent):
java -javaagent:opentelemetry-javaagent.jar \
-Dotel.service.name=orders-service \
-Dotel.exporter.otlp.endpoint=http://otel-collector:4318 \
-jar orders-service.jar
Spring Boot 4 також має окремий spring-boot-starter-opentelemetry для застосунків, яким зручніша конфігурація, ніж агент, — про це у статті Spring Boot + Kotlin у 2026. З віртуальними потоками трейси — найшвидший спосіб побачити, де запити насправді чекають, див. Віртуальні потоки в Spring Boot.
Node.js і Next.js
Node.js SDK з автоінструментуванням покриває HTTP, Express, популярні клієнти баз даних тощо (OpenTelemetry JavaScript). У Next.js реєструйте його в instrumentation.ts, щоб він завантажувався до коду застосунку.
Власні span'и й атрибути
Автоінструментування показує «сантехніку»; корисними трейси робить бізнес-контекст. Додавайте span'и навколо важливих операцій і атрибути на кшталт тенанта, суми замовлення чи feature flag, дотримуючись семантичних конвенцій для стандартних назв (семантичні конвенції). Ніколи не кладіть в атрибути персональні дані чи секрети.
Передача контексту
Трейси працюють між сервісами, бо кожен вихідний запит несе контекст трейсу в заголовку W3C traceparent (W3C Trace Context). Переконайтеся, що шлюзи, проксі й брокери повідомлень передають його далі — наприклад, у заголовках Kafka, — інакше трейси розпадаються на непов'язані частини.
Семплінг і контроль витрат
Обсяг телеметрії росте швидко, а з ним і рахунок. Контролюйте його свідомо (OpenTelemetry: sampling):
- Head sampling вирішує на початку трейсу (зберігати 10%). Дешево, але може відкинути найцікавіші трейси.
- Tail sampling у Collector вирішує після завершення трейсу: зберігати всі помилки й повільні запити плюс базовий відсоток звичайного трафіку.
- Метрики замість логів для всього, що ви рахуєте. Лічильник значно дешевший за рядок логу на кожну подію.
- Стежте за кардинальністю. Мітки метрик із необмеженими значеннями — ID користувачів, URL з ідентифікаторами — роздувають сховище.
- Рівні зберігання. Детальні трейси — дні, агреговані метрики — місяці.
Що міряти спершу
Почніть із сигналів, що показують, чи задоволені користувачі, а потім заглиблюйтеся:
- RED для сервісів: частота запитів, помилки й тривалість для кожного ендпоінта.
- USE для ресурсів: використання, насичення й помилки для CPU, пам'яті, дисків, пулів з'єднань.
- Бізнес-метрики: замовлення за хвилину, частка успішних платежів, реєстрації.
- SLO та алерти на симптоми, які відчувають користувачі, — частку помилок, затримку, — а не на кожен сплеск CPU, як радить книга Google SRE (Google SRE: моніторинг розподілених систем).
Бази даних і бекапи заслуговують на таку саму увагу; див. Бекапи PostgreSQL і аварійне відновлення. У модульному моноліті трейси також показують виклики між модулями задовго до того, як ви щось виносите, див. Модульний моноліт зі Spring Modulith. На самокерованому Kubernetes ми запускаємо цей стек із VictoriaMetrics, Grafana і Loki, як описано у статті Kubernetes на Hetzner.
План впровадження
- Розгорніть Collector і по одному бекенду на сигнал.
- Додайте автоінструментування у два-три критичні сервіси; перевірте, що трейси з'єднуються наскрізно.
- Додайте ID трейсів у логи й переведіть логування на структурований JSON.
- Визначте RED-дашборди і два-три алерти на основі SLO.
- Додайте власні span'и для ключових бізнес-операцій.
- Впровадьте tail sampling і ліміти кардинальності до того, як обсяг виросте.
- Розгорніть на решту сервісів зі спільною бібліотекою конфігурації.
Помилки, яких варто уникати
- Інструментувати все, але не мати жодного алерту на те, що відчувають користувачі.
- Логувати тіла запитів із персональними даними в бекенди телеметрії.
- Використовувати ID користувачів чи повні URL як мітки метрик.
- Мати різну конфігурацію SDK у кожному сервісі замість спільної бібліотеки.
- Зберігати 100% трейсів назавжди, а потім урізати observability, коли прийде рахунок.
FAQ
Чи замінює OpenTelemetry Prometheus чи Grafana? Ні. OpenTelemetry відповідає за інструментування і транспорт; Prometheus, Grafana та інші зберігають і візуалізують дані.
Чи достатньо автоінструментування? Для старту — чудово. Додайте власні span'и й атрибути з бізнес-контекстом, інакше трейси показуватимуть лише технічну «сантехніку».
Який оверхед це додає? Зазвичай невеликий для правильно налаштованих SDK з пакетуванням і семплінгом. Міряйте на власних сервісах під навантаженням.
Чи можна використовувати OpenTelemetry з комерційним вендором? Так. Більшість вендорів приймають OTLP напряму або через Collector, що залишає вам свободу змінити вендора пізніше.
Джерела
- OpenTelemetry. Документація, Signals, Status.
- OpenTelemetry. Collector, OTLP, Sampling, Semantic conventions.
- OpenTelemetry. Java agent і JavaScript.
- W3C. Trace Context.
- Google. SRE book: Monitoring distributed systems.
- CNCF. Проєкт OpenTelemetry.