Контекст
OpenTelemetry працює шляхом зберігання та розповсюдження телеметричних даних. Наприклад, коли інструментований застосунок отримує запит і починається відрізок, цей відрізок повинен бути доступним для компонента, який створює дочірні відрізки. Для вирішення цієї потреби, OpenTelemetry зберігає відрізок в активному контексті.
Контекст виконання PHP
API контексту глобально доступне в межах одного контексту виконання PHP, і може бути лише один активний контекст у поточному контексті виконання.
Зберігання
Контекст може зберігати значення (наприклад, Span
), і він використовує Storage
для відстеження збережених значень. Стандартно використовується загальний ContextStorage
. OpenTelemetry для PHP підтримує інші сховища контексту для менш поширених випадків використання, таких як асинхронне або паралельне виконання з fibers
.
Ключі контексту
Значення зберігаються в контексті як пари ключ-значення. Ключі контексту використовуються для зберігання та отримання значень з контексту.
Ключі можна створити, викликавши OpenTelemetry\Context\Context::createKey()
, наприклад:
use OpenTelemetry\Context\Context;
$key1 = Context::createKey('Мій перший ключ');
$key2 = Context::createKey('Мій другий ключ');
Активний контекст
Активний контекст — це контекст, який повертається Context::getCurrent()
. Обʼєкт контексту містить записи, які дозволяють телеметричним компонентам спілкуватися один з одним. Наприклад, коли створюється відрізок, він може бути активованим, що створює новий активний контекст і зберігає відрізок. Пізніше, коли створюється інший відрізок, він може використовувати відрізок з активного контексту як свій батьківський відрізок. Якщо жоден контекст не активний, повертається кореневий контекст, який є просто порожнім обʼєктом контексту.
use OpenTelemetry\Context\Context;
// Повертає активний контекст
// Якщо жоден контекст не активний, повертається кореневий контекст
$context = Context::getCurrent();
Встановлення та отримання значень контексту
Значення зберігаються в Контексті за допомогою методу $context->with($key, $value)
. Встановлення запису контексту створює новий контекст з новим записом у його сховищі, що містить $value
.
Контекст є незмінним. Встановлення запису контексту створює новий контекст з новим записом у його сховищі: $context->with($key, $value)
. Отримуйте значення за допомогою $context->get($key)
, наприклад:
use OpenTelemetry\Context\Context;
$key = Context::createKey(ʼякийсь ключ');
// додати новий запис
$ctx2 = Context::getCurrent()->with($key, 'контекст 2');
// ctx2 містить новий запис
var_dump($ctx2->get($key)); // "контекст 2"
// активний контекст не змінено
var_dump(Context::getCurrent()->get($key)); // NULL
Якщо значення не знайдено в поточному контексті, тоді кожен батьківський контекст перевіряється доки ключ не буде знайдено або не буде досягнуто кореневого контексту.
Активування контексту
Контекст може бути активованим викликом $context->activate()
.
use OpenTelemetry\Context\Context;
$key = Context::createKey('мій-ключ');
$ctx = Context::getCurrent();
$ctx2 = $ctx->with($key, 'контекст 2');
$ctx2->activate();
assert($ctx2 === Context::getCurrent());
Область дії
Повернене значення $context->activate()
є Scope
. Ви повинні detach()
область дії, щоб деактивувати цей контекст, що реактивує попередньо активний контекст.
Повернене значення $scope->detach()
є цілим числом. Значення повернення 0
означає, що область дії була успішно відʼєднана. Ненульове значення означає, що виклик був несподіваним. Це може статися, якщо контекст, повʼязаний з областю дії, був:
- Вже відʼєднаний
- Не є частиною поточного контексту виконання
- Не є активним контекстом
DebugScope
Щоб допомогти розробникам у виявленні проблем з контекстом та областю дії, існує DebugScope
. У середовищі виконання PHP з увімкненими твердженнями, активований Context
обгортається в DebugScope
. DebugScope
відстежує, коли область дії була активована, і має деструктор, який викликає помилку, якщо область дії не була відʼєднана. Вихід помилки містить трасування, яке показує, який код активував контекст.
Наступний код викликав би помилку, скаржачись, що область дії не була відʼєднана, і надаючи трасування, де область дії була створена:
use OpenTelemetry\Context\Context;
$key = Context::createKey('мій-ключ');
$scope = Context::getCurrent()->with($key, 'значення')->activate();
//вихід без відʼєднання $scope
Це може бути проблематичним у деяких ситуаціях, особливо в застарілих застосунках, які можуть використовувати exit
або die
. У такому випадку активні відрізки не завершуються та не експортуються, і DebugScope
голосно скаржиться.
Якщо ви розумієте, чому DebugScope
скаржиться, і приймаєте ризики, то ви можете повністю вимкнути цю функцію, встановивши OTEL_PHP_DEBUG_SCOPES_DISABLED
у значення істини.
Вкладений контекст
Активні виконання контексту можуть бути вкладеними. Це те, як трасування можуть мати вкладені відрізки:
use OpenTelemetry\Context\Context;
$key = Context::createKey('мій-ключ');
var_dump(Context::getCurrent()->get($key)); //NULL
$scope2 = Context::getCurrent()->with($key, 'контекст 2')->activate();
var_dump(Context::getCurrent()->get($key)); //'контекст 2'
$scope3 = Context::getCurrent()->with($key, 'контекст 3')->activate();
var_dump(Context::getCurrent()->get($key)); //'контекст 3'
$scope3->detach(); //контекст 2 активний
$scope2->detach(); //оригінальний контекст активний
var_dump(Context::getCurrent()->get($key)); //NULL
Контекст в асинхронних середовищах
Для асинхронного програмування на PHP, наприклад Swoole
або на основі Fiber Revolt
event loop, може бути кілька активних контекстів, але все одно лише один активний контекст на контекст виконання.
Для реалізацій на основі fiber, Context
асоціюється з активним fiber, і розгалужується, перемикається та знищується відповідно, підключаючись до ініціалізації fiber, розгалуження та обробників знищення PHP.
Для інших асинхронних реалізацій може знадобитися спеціальне сховище контексту для правильної взаємодії. Перевірте реєстр для реалізацій сховища.
Відгук
Чи це було корисним?
Дякуємо. Ми цінуємо ваші відгуки!
Будь ласка, дайте нам знати як ми можемо покращити цю сторінку. Ми цінуємо ваші відгуки!