Поширення контексту
З поширенням контексту сигнали (трейси, метрики, and логи) можуть бути корельовані один з одним, незалежно від того, де вони генеруються. Хоча це не обмежується лише трасуванням, поширення контексту дозволяє трейсам будувати причинно-наслідкову інформацію про систему через сервіси, які довільно розподілені між процесами та межами мереж.
Щоб зрозуміти поширення контексту, вам потрібно зрозуміти дві окремі концепції: контекст і поширення.
Контекст
Контекст — це обʼєкт, який містить інформацію для сервісу відправника та отримувача або одиниці виконання, щоб корелювати один сигнал з іншим.
Коли Service A викликає Service B, він містить ідентифікатор трейсу та ідентифікатор відрізка як частину контексту. Service B використовує ці значення для створення нового відрізка, який належить тому ж самому трейсу, встановлюючи відрізок від Service A в якості батьківського. Це дозволяє відстежувати повний потік запиту через межі сервісів.
Поширення
Поширення — це механізм, який переміщує контекст між сервісами та процесами. Він серіалізує або десеріалізує обʼєкт контексту і надає відповідну інформацію для поширення від одного сервісу до іншого.
Поширення зазвичай обробляється бібліотеками інструментування і є прозорим для користувача. У випадку, якщо вам потрібно вручну поширювати контекст, ви можете використовувати API Поширювачів.
OpenTelemetry підтримує кілька офіційних поширювачів. Стандартний поширювач використовує заголовки, визначені специфікацією W3C TraceContext.
Приклад
Сервіс з назвою Frontend, який надає різні точки доступу HTTP, такі як POST /cart/add та GET /checkout/, звертається до підлеглого сервісу Product Catalog через точку доступу HTTP GET /product, щоб отримати детальну інформацію про товари, які користувач хоче додати до кошика або які є частиною замовлення. Щоб зрозуміти дії в сервісі Product Catalog в контексті запитів, що надходять від Frontend, контекст (тут: Trace ID і Span ID як “Parent ID”) поширюється за допомогою заголовка traceparent, як це визначено в специфікації W3C TraceContext. Це означає, що ідентифікатори вбудовані в поля заголовка:
<version>-<trace-id>-<parent-id>-<trace-flags>
Наприклад:
00-a0892f3577b34da6a3ce929d0e0e4736-f03067aa0ba902b7-01
Трейси
Як уже згадувалося, поширення контексту дозволяє трейсам створювати причинно-наслідкову інформацію між сервісами. У цьому прикладі два виклики до точки доступу HTTP GET /product сервісу Product Catalog можуть бути повʼязані з їхніми викликами в сервісі Frontend шляхом вилучення віддаленого контексту з заголовка traceparent та введення його в локальний контекст для встановлення Trace ID та Parent ID. Завдяки цьому в бекенді, такому як Jaeger, можна побачити два запити як відрізки одного трейсу.
Логи
SDK OpenTelemetry здатні автоматично зіставляти логи з трейсами. Це означає, що вони можуть вставляти контекст (ідентифікатор трейса, ідентифікатор відрізка) у запис логу. Це не тільки дозволяє бачити логи в контексті трейса та відрізка, до яких вони належать, але й дозволяє бачити логи, що належать один до одного, незалежно від меж сервісу чи одиниці виконання.
Метрики
У випадку метрик поширення контексту дозволяє агрегувати вимірювання в цьому контексті. Наприклад, замість того, щоб дивитися тільки на час відгуку всіх запитів GET /product, ви також можете отримати метрики для комбінацій POST /cart/add > GET /product і GET /checkout < GET /product.
| Назва | Викликів в сек | Середній час відповіді |
|---|---|---|
* > GET /product | 370 | 300ms |
POST /card/add > GET /product | 330 | 130ms |
GET /checkout > GET /product | 40 | 1703ms |
Поширення власного контексту
У більшості випадків використання ви знайдете бібліотеки інструментації або інструментацію нативних бібліотек, які обробляють поширення контексту за вас. У деяких випадках така підтримка недоступна, і вам потрібно створити її самостійно. Для цього потрібно скористатися згаданим раніше API Propagators:
- З боку відправника контекст робиться інʼєкція в носій, наприклад, в заголовки HTTP-запиту. В інших випадках вам потрібно знайти місце, де можна зберігати метадані для вашого запиту.
- На стороні одержувача контекст витягується з носія. Знову ж таки, у випадку HTTP він витягується з заголовків. В інших випадках ви вибираєте місце, яке вибрали на стороні відправника для зберігання контексту.
Зверніть увагу, що контекст можна поширювати в протоколах, які не мають спеціального поля для метаданих, але ви повинні переконатися, що на стороні одержувача вони витягуються і видаляються перед обробкою даних, інакше ви можете створити невизначену поведінку.
Для наступних мов існує покроковий підручник для поширення власного контексту:
Найкращі практики безпеки
Поширення передбачає надсилання та отримання даних за межами сервісу, що може мати наслідки для безпеки.
Зовнішні служби
Коли ваша служба взаємодіє із зовнішніми службами (службами, які вам не належать або яким ви не довіряєте), враховуйте наступне:
- Вхідний контекст: будьте обережні, приймаючи контекст із зовнішніх джерел. Зловмисники можуть надсилати підроблені заголовки трасування, щоб маніпулювати вашими даними трасування або потенційно використовувати вразливості в аналізі контексту. Можливо, вам слід ігнорувати або очищати вхідний контекст із ненадійних джерел.
- Вихідний контекст: будьте уважні до того, що ви передаєте зовнішнім службам. Внутрішні ідентифікатори трасування, ідентифікатори відрізків або елементи baggage можуть розкривати конфіденційну інформацію про вашу внутрішню архітектуру або бізнес-логіку. Можливо, вам слід налаштувати свої поширювачі так, щоб вони не надсилали контекст до зовнішніх або загальнодоступних точок доступу.
Baggage
Baggage дозволяє поширювати довільні пари ключ-значення. Оскільки ці дані поширюються за межі служби, уникайте розміщення конфіденційної інформації (такої як облікові дані користувача, ключі API або PII) в baggage, оскільки вона може бути зареєстрована або надіслана ненадійним підлеглими службам.
Підтримка в SDK для мов
Детальну інформацію про підтримку поширення контексту в окремих мовах для OpenTelemetry API та SDK можна знайти на відповідних сторінках документації:
Для мов .NET, Rust та Swift відсутня специфічна для мови документація щодо поширення контексту. Якщо ви знаєте будь-яку з цих мов і бажаєте допомогти, дізнайтеся, як ви можете зробити свій внесок!
Специфікація
Щоб дізнатися більше про Поширення Контексту, дивіться Специфікацію Контексту.
Відгук
Чи це було корисним?
Дякуємо. Ми цінуємо ваші відгуки!
Будь ласка, дайте нам знати як ми можемо покращити цю сторінку. Ми цінуємо ваші відгуки!