# Поширення контексту

> Дізнайтеся про концепцію, яка дозволяє здійснювати Розподілене Трасування.

---

LLMS index: [llms.txt](/llms.txt)

---

З поширенням контексту [сигнали](../signals) ([трейси](../signals/traces/),
[метрики](../signals/metrics/), and [логи](../signals/logs/)) можуть бути корельовані один з одним, незалежно від того, де вони генеруються. Хоча це не обмежується лише трасуванням, поширення контексту дозволяє [трейсам](../signals/traces) будувати причинно-наслідкову інформацію про систему через сервіси, які довільно
розподілені між процесами та межами мереж.

Щоб зрозуміти поширення контексту, вам потрібно зрозуміти дві окремі концепції: контекст і поширення.

## Контекст {#context}

Контекст — це обʼєкт, який містить інформацію для сервісу відправника та отримувача або [одиниці виконання](/docs/specs/otel/glossary/#execution-unit), щоб корелювати один сигнал з іншим.

Коли Service A викликає Service B, він містить ідентифікатор трейсу та ідентифікатор відрізка як частину контексту. Service B використовує ці значення для створення нового відрізка, який належить тому ж самому трейсу, встановлюючи відрізок від Service A в якості батьківського. Це дозволяє відстежувати повний потік запиту через межі сервісів.

## Поширення {#propagation}

Поширення — це механізм, який переміщує контекст між сервісами та процесами. Він серіалізує або десеріалізує обʼєкт контексту і надає відповідну інформацію для поширення від одного сервісу до іншого.

Поширення зазвичай обробляється бібліотеками інструментування і є прозорим для користувача. У випадку, якщо вам потрібно вручну поширювати контекст, ви можете використовувати [API Поширювачів](/docs/specs/otel/context/api-propagators/).

OpenTelemetry підтримує кілька офіційних поширювачів. Стандартний поширювач використовує заголовки, визначені специфікацією [W3C TraceContext](https://www.w3.org/TR/trace-context/).

## Приклад {#example}

Сервіс з назвою `Frontend`, який надає різні точки доступу HTTP, такі як `POST /cart/add` та `GET /checkout/`, звертається до підлеглого сервісу `Product Catalog` через точку доступу HTTP `GET /product`, щоб отримати детальну інформацію про товари, які користувач хоче додати до кошика або які є частиною замовлення. Щоб зрозуміти дії в сервісі `Product Catalog` в контексті запитів, що надходять від `Frontend`, контекст (тут: Trace ID і Span ID як "Parent ID") поширюється за допомогою заголовка `traceparent`, як це визначено в специфікації W3C TraceContext. Це означає, що ідентифікатори вбудовані в поля заголовка:

```text
<version>-<trace-id>-<parent-id>-<trace-flags>
```

Наприклад:

```text
00-a0892f3577b34da6a3ce929d0e0e4736-f03067aa0ba902b7-01
```

### Трейси {#traces}

Як уже згадувалося, поширення контексту дозволяє трейсам створювати причинно-наслідкову інформацію між сервісами. У цьому прикладі два виклики до точки доступу HTTP `GET /product` сервісу `Product Catalog` можуть бути повʼязані з їхніми викликами в сервісі `Frontend` шляхом вилучення віддаленого контексту з заголовка `traceparent` та введення його в локальний контекст для встановлення Trace ID та Parent ID. Завдяки цьому в [бекенді](/ecosystem/vendors), такому як [Jaeger](https://jaegertracing.io), можна побачити два запити як відрізки одного трейсу.

![Приклад поширення контексту, що демонструє кореляцію трейсів між сервісами](context-propagation-example.svg)

### Логи {#logs}

SDK OpenTelemetry здатні автоматично зіставляти логи з трейсами. Це означає, що вони можуть вставляти контекст (ідентифікатор трейса, ідентифікатор відрізка) у запис логу. Це не тільки дозволяє бачити логи в контексті трейса та відрізка, до яких вони належать, але й дозволяє бачити логи, що належать один до одного, незалежно від меж сервісу чи одиниці виконання.

### Метрики {#metrics}

У випадку метрик поширення контексту дозволяє агрегувати вимірювання в цьому контексті. Наприклад, замість того, щоб дивитися тільки на час відгуку всіх запитів `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                 |

## Поширення власного контексту {#custom-context-propagation}

У більшості випадків використання ви знайдете [бібліотеки інструментації або інструментацію нативних бібліотек](/docs/concepts/instrumentation/libraries/), які обробляють поширення контексту за вас. У деяких випадках така підтримка недоступна, і вам потрібно створити її самостійно. Для цього потрібно скористатися згаданим раніше API Propagators:

- З боку відправника контекст [робиться інʼєкція](/docs/specs/otel/context/api-propagators/#inject) в носій, наприклад, в заголовки HTTP-запиту. В інших випадках вам потрібно знайти місце, де можна зберігати метадані для вашого запиту.
- На стороні одержувача контекст [витягується](/docs/specs/otel/context/api-propagators/#extract) з носія. Знову ж таки, у випадку HTTP він витягується з заголовків. В інших випадках ви вибираєте місце, яке вибрали на стороні відправника для зберігання контексту.

Зверніть увагу, що контекст можна поширювати в протоколах, які не мають спеціального поля для метаданих, але ви повинні переконатися, що на стороні одержувача вони витягуються і видаляються перед обробкою даних, інакше ви можете створити невизначену поведінку.

Для наступних мов існує покроковий підручник для поширення власного контексту:

- [Erlang](/docs/languages/erlang/propagation/#manual-context-propagation)
- [JavaScript](/docs/languages/js/propagation/#manual-context-propagation)
- [PHP](/docs/languages/php/propagation/#manual-context-propagation)
- [Python](/docs/languages/python/propagation/#manual-context-propagation)

## Найкращі практики безпеки {#security-best-practices}

Поширення передбачає надсилання та отримання даних за межами сервісу, що може мати наслідки для безпеки.

### Зовнішні служби {#external-services}

Коли ваша служба взаємодіє із зовнішніми службами (службами, які вам не належать або яким ви не довіряєте), враховуйте наступне:

- **Вхідний контекст**: будьте обережні, приймаючи контекст із зовнішніх джерел. Зловмисники можуть надсилати підроблені заголовки трасування, щоб маніпулювати вашими даними трасування або потенційно використовувати вразливості в аналізі контексту. Можливо, вам слід ігнорувати або очищати вхідний контекст із ненадійних джерел.
- **Вихідний контекст**: будьте уважні до того, що ви передаєте зовнішнім службам. Внутрішні ідентифікатори трасування, ідентифікатори відрізків або елементи baggage можуть розкривати конфіденційну інформацію про вашу внутрішню архітектуру або бізнес-логіку. Можливо, вам слід налаштувати свої поширювачі так, щоб вони не надсилали контекст до зовнішніх або загальнодоступних точок доступу.

### Baggage

[Baggage](../signals/baggage/) дозволяє поширювати довільні пари ключ-значення. Оскільки ці дані поширюються за межі служби, уникайте розміщення конфіденційної інформації (такої як облікові дані користувача, ключі API або PII) в baggage, оскільки вона може бути зареєстрована або надіслана ненадійним підлеглими службам.

## Підтримка в SDK для мов {#support-in-language-sdks}

Детальну інформацію про підтримку поширення контексту в окремих мовах для OpenTelemetry API та SDK можна знайти на відповідних сторінках документації:

- [C++](/docs/languages/cpp/instrumentation/#context-propagation)
- .NET
- [Erlang](/docs/languages/erlang/propagation/)
- [Go](/docs/languages/go/instrumentation/#propagators-and-context)
- [Java](/docs/languages/java/api/#context-api)
- [JavaScript](/docs/languages/js/propagation/)
- [PHP](/docs/languages/php/propagation/)
- [Python](/docs/languages/python/propagation/)
- [Ruby](/docs/languages/ruby/instrumentation/#context-propagation)
- Rust
- Swift

> [!IMPORTANT] Потрібна допомога
>
> Для мов .NET, Rust та Swift відсутня специфічна для мови документація щодо поширення контексту. Якщо ви знаєте будь-яку з цих мов і бажаєте допомогти, [дізнайтеся, як ви можете зробити свій внесок](/docs/contributing/)!

## Специфікація {#specification}

Щоб дізнатися більше про Поширення Контексту, дивіться [Специфікацію Контексту](/docs/specs/otel/context/).
