Контекст
Для того, щоб OpenTelemetry працював, він повинен зберігати та передавати важливі дані телеметрії. Наприклад, коли отримано запит і розпочато відрізок, він повинен бути доступний компоненту, який створює його дочірній відрізок. Щоб розвʼязати цю проблему, OpenTelemetry зберігає відрізок у Контексті. Цей документ описує API контексту OpenTelemetry для JavaScript та як його використовувати.
Більше інформації:
Менеджер контексту
API контексту залежить від менеджера контексту для роботи. Приклади в цьому документі припускають, що ви вже налаштували менеджера контексту. Зазвичай менеджер контексту надається вашим SDK, однак його можна зареєструвати безпосередньо ось так:
import * as api from '@opentelemetry/api';
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';
const contextManager = new AsyncHooksContextManager();
contextManager.enable();
api.context.setGlobalContextManager(contextManager);
Кореневий контекст
ROOT_CONTEXT — це порожній контекст. Якщо жоден контекст не активний, активним є ROOT_CONTEXT. Активний контекст пояснюється нижче Активний контекст.
Ключі контексту
Записи контексту є парами ключ-значення. Ключі можна створити, викликавши api.createContextKey(description).
import * as api from '@opentelemetry/api';
const key1 = api.createContextKey('Мій перший ключ');
const key2 = api.createContextKey('Мій другий ключ');
Основні операції
Отримати запис
Записи доступні за допомогою методу context.getValue(key).
import * as api from '@opentelemetry/api';
const key = api.createContextKey('якийсь ключ');
// ROOT_CONTEXT - це порожній контекст
const ctx = api.ROOT_CONTEXT;
const value = ctx.getValue(key);
Встановити запис
Записи створюються за допомогою методу context.setValue(key, value). Встановлення запису контексту створює новий контекст з усіма записами попереднього контексту, але з новим записом. Встановлення запису контексту не змінює попередній контекст.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('якийсь ключ');
const ctx = api.ROOT_CONTEXT;
// додати новий запис
const ctx2 = ctx.setValue(key, 'контекст 2');
// ctx2 містить новий запис
console.log(ctx2.getValue(key)); // "контекст 2"
// ctx не змінено
console.log(ctx.getValue(key)); // undefined
Видалити запис
Записи видаляються за допомогою виклику context.deleteValue(key). Видалення запису контексту створює новий контекст з усіма записами попереднього контексту, але без запису, ідентифікованого ключем. Видалення запису контексту не змінює попередній контекст.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('якийсь ключ');
const ctx = api.ROOT_CONTEXT;
const ctx2 = ctx.setValue(key, 'контекст 2');
// видалити запис
const ctx3 = ctx2.deleteValue(key);
// ctx3 не містить запису
console.log(ctx3.getValue(key)); // undefined
// ctx2 не змінено
console.log(ctx2.getValue(key)); // "контекст 2"
// ctx не змінено
console.log(ctx.getValue(key)); // undefined
Активний контекст
ВАЖЛИВО: Припускаємо, що ви налаштували Менеджер Контексту. Без нього, api.context.active() ЗАВЖДИ поверне ROOT_CONTEXT.
Активний контекст — це контекст, який повертається api.context.active(). Обʼєкт контексту містить записи, які дозволяють компонентам трасування, що обробляють один потік виконання, спілкуватися один з одним і забезпечувати успішне створення трасування. Наприклад, коли створюється відрізок, він може бути доданий до контексту. Пізніше, коли створюється інший відрізок, він може використовувати відрізок з контексту як свій батьківський відрізок. Це досягається за допомогою механізмів, таких як async_hooks або AsyncLocalStorage у Node.js, або zone.js у вебі для передачі контексту через один потік виконання. Якщо жоден контекст не активний, повертається ROOT_CONTEXT, який є просто порожнім обʼєктом контексту.
Отримати активний контекст
Активний контекст — це контекст, який повертається api.context.active().
import * as api from '@opentelemetry/api';
// Повертає активний контекст
// Якщо жоден контекст не активний, повертається ROOT_CONTEXT
const ctx = api.context.active();
Встановити активний контекст
Контекст може бути зроблений активним за допомогою api.context.with(ctx, callback). Під час виконання callback, контекст, переданий до with, буде повернутий context.active.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('Ключ для зберігання значення');
const ctx = api.context.active();
api.context.with(ctx.setValue(key, 'контекст 2'), async () => {
// "контекст 2" активний
console.log(api.context.active().getValue(key)); // "контекст 2"
});
Значення, яке повертається api.context.with(context, callback), є значенням, яке повертається зворотним викликом. Зворотний виклик завжди викликається синхронно.
import * as api from '@opentelemetry/api';
const name = await api.context.with(api.context.active(), async () => {
const row = await db.getSomeValue();
return row['name'];
});
console.log(name); // імʼя, повернене з бази даних
Виконання активного контексту може бути вкладеним.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('Ключ для зберігання значення');
const ctx = api.context.active();
// Жоден контекст не активний
console.log(api.context.active().getValue(key)); // undefined
api.context.with(ctx.setValue(key, 'контекст 2'), () => {
// "контекст 2" активний
console.log(api.context.active().getValue(key)); // "контекст 2"
api.context.with(ctx.setValue(key, 'контекст 3'), () => {
// "контекст 3" активний
console.log(api.context.active().getValue(key)); // "контекст 3"
});
// "контекст 2" активний
console.log(api.context.active().getValue(key)); // "контекст 2"
});
// Жоден контекст не активний
console.log(api.context.active().getValue(key)); // undefined
Приклад
Цей складніший приклад ілюструє, як контекст не змінюється, але створюються нові обʼєкти контексту.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('Ключ для зберігання значення');
const ctx = api.context.active(); // Повертає ROOT_CONTEXT, коли жоден контекст не активний
const ctx2 = ctx.setValue(key, 'контекст 2'); // не змінює ctx
console.log(ctx.getValue(key)); //? undefined
console.log(ctx2.getValue(key)); //? "контекст 2"
const ret = api.context.with(ctx2, () => {
const ctx3 = api.context.active().setValue(key, 'контекст 3');
console.log(api.context.active().getValue(key)); //? "контекст 2"
console.log(ctx.getValue(key)); //? undefined
console.log(ctx2.getValue(key)); //? "контекст 2"
console.log(ctx3.getValue(key)); //? "контекст 3"
api.context.with(ctx3, () => {
console.log(api.context.active().getValue(key)); //? "контекст 3"
});
console.log(api.context.active().getValue(key)); //? "контекст 2"
return 'значення, що повертається';
});
// Значення, яке повертається зворотним викликом, повертається викликачеві
console.log(ret); //? "значення, що повертається"
Відгук
Чи це було корисним?
Дякуємо. Ми цінуємо ваші відгуки!
Будь ласка, дайте нам знати як ми можемо покращити цю сторінку. Ми цінуємо ваші відгуки!