Contexto
Para que o OpenTelemetry funcione, é necessário que dados importantes de telemetria sejam armazenados e propagados. Por exemplo, quando uma requisição é recebida e um trecho (span) é iniciado, esse trecho deve estar disponível para um componente que cria seu trecho filho. Para resolver este problema, o OpenTelemetry armazena o trecho no Contexto. Este documento descreve a API de contexto do OpenTelemetry para JavaScript e como ela é usada.
Mais informações:
Gerenciador de Contexto
A API de contexto depende de um gerenciador de contexto (context manager) para funcionar. Os exemplos neste documento pressupõem que um gerenciador de contexto já foi configurado. Geralmente, o gerenciador de contexto é fornecido pelo SDK, porém também é possível registrar um diretamente da seguinte maneira:
import * as api from '@opentelemetry/api';
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';
const contextManager = new AsyncHooksContextManager();
contextManager.enable();
api.context.setGlobalContextManager(contextManager);
Contexto raiz (Root Context)
ROOT_CONTEXT é o contexto vazio. Se nenhum contexto estiver ativo, o
ROOT_CONTEXT torna-se o contexto ativo. O funcionamento do contexto ativo é
explicado adiante em Contexto Ativo.
Chaves de Contexto
Entradas de contexto são pares chave-valor. As chaves podem ser criadas chamando
api.createContextKey(description).
import * as api from '@opentelemetry/api';
const key1 = api.createContextKey('Minha primeira chave');
const key2 = api.createContextKey('Minha segunda chave');
Operações básicas
Obter um valor
Os valores podem ser acessados utilizando o método context.getValue(key).
import * as api from '@opentelemetry/api';
const key = api.createContextKey('alguma chave');
// ROOT_CONTEXT é o contexto vazio
const ctx = api.ROOT_CONTEXT;
const value = ctx.getValue(key);
Definir um valor
Entradas são criadas utilizando o método context.setValue(key, value). Definir
uma entrada de contexto cria um novo contexto com todas as entradas do contexto
anterior, mas incluindo a nova entrada. Definir uma entrada de contexto não
modifica o contexto anterior.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('alguma chave');
const ctx = api.ROOT_CONTEXT;
// adiciona uma nova entrada
const ctx2 = ctx.setValue(key, 'contexto 2');
// ctx2 contém a nova entrada
console.log(ctx2.getValue(key)); // "contexto 2"
// ctx não foi modificado
console.log(ctx.getValue(key)); // undefined
Remover um valor
Entradas são removidas utilizando o método context.deleteValue(key). Remover
uma entrada de contexto cria um novo contexto com todas as entradas do contexto
anterior, mas sem a entrada identificada pela chave. Remover uma entrada de
contexto não modifica o contexto anterior.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('alguma chave');
const ctx = api.ROOT_CONTEXT;
const ctx2 = ctx.setValue(key, 'contexto 2');
// remover a entrada
const ctx3 = ctx.deleteValue(key);
// ctx3 não contém a entrada
console.log(ctx3.getValue(key)); // undefined
// ctx2 não foi modificado
console.log(ctx2.getValue(key)); // "contexto 2"
// ctx não foi modificado
console.log(ctx.getValue(key)); // undefined
Contexto ativo
IMPORTANTE: Isso pressupõe que um gerenciador de contexto foi configurado.
Sem um, api.context.active() SEMPRE retornará o ROOT_CONTEXT.
O contexto ativo é o contexto que é retornado por api.context.active(). O
objeto de contexto contém entradas que permitem que os componentes de
rastreamento que acompanham um único fluxo de execução comuniquem-se entre si e
garantam que o rastro seja criado corretamente. Por exemplo, quando um trecho é
criado, ele pode ser adicionado ao contexto. Mais tarde, quando outro trecho for
criado, ele poderá usar o trecho do contexto como seu trecho pai. Isso é
realizado por meio do uso de mecanismos como
async_hooks ou
AsyncLocalStorage
no Node.js, ou
zone.js no
navegador para propagar o contexto através de uma única execução. Se nenhum
contexto estiver ativo, o ROOT_CONTEXT é retornado, que é apenas o objeto de
contexto vazio.
Obter o Contexto ativo
O contexto ativo é o contexto que é retornado por api.context.active().
import * as api from '@opentelemetry/api';
// Retorna o contexto ativo
// Se nenhum contexto estiver ativo, o ROOT_CONTEXT é retornado
const ctx = api.context.active();
Definir o Contexto ativo
Um contexto pode ser tornado ativo usando api.context.with(ctx, callback).
Durante a execução do callback, o contexto passado em with será retornado
por context.active.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('Chave para armazenar um valor');
const ctx = api.context.active();
api.context.with(ctx.setValue(key, 'contexto 2'), async () => {
// "contexto 2" está ativo
console.log(api.context.active().getValue(key)); // "contexto 2"
});
O valor de retorno de api.context.with(context, callback) é o valor de retorno
do callback. O callback é sempre chamado de forma síncrona.
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); // nome retornado pelo banco de dados
Execuções de contexto ativo podem ser aninhadas.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('Chave para armazenar um valor');
const ctx = api.context.active();
// Nenhum contexto está ativo
console.log(api.context.active().getValue(key)); // undefined
api.context.with(ctx.setValue(key, 'contexto 2'), () => {
// "contexto 2" está ativo
console.log(api.context.active().getValue(key)); // "contexto 2"
api.context.with(ctx.setValue(key, 'contexto 3'), () => {
// "contexto 3" está ativo
console.log(api.context.active().getValue(key)); // "contexto 3"
});
// "contexto 2" está ativo
console.log(api.context.active().getValue(key)); // "contexto 2"
});
// Nenhum contexto está ativo
console.log(api.context.active().getValue(key)); // undefined
Exemplo
Este exemplo mais complexo ilustra como o contexto não é modificado, mas novos objetos de contexto são criados.
import * as api from '@opentelemetry/api';
const key = api.createContextKey('Chave para armazenar um valor');
const ctx = api.context.active(); // Retorna ROOT_CONTEXT quando nenhum contexto está ativo
const ctx2 = ctx.setValue(key, 'contexto 2'); // não modifica ctx
console.log(ctx.getValue(key)); //? undefined
console.log(ctx2.getValue(key)); //? "contexto 2"
const ret = api.context.with(ctx2, () => {
const ctx3 = api.context.active().setValue(key, 'contexto 3');
console.log(api.context.active().getValue(key)); //? "contexto 2"
console.log(ctx.getValue(key)); //? undefined
console.log(ctx2.getValue(key)); //? "contexto 2"
console.log(ctx3.getValue(key)); //? "contexto 3"
api.context.with(ctx3, () => {
console.log(api.context.active().getValue(key)); //? "contexto 3"
});
console.log(api.context.active().getValue(key)); //? "contexto 2"
return 'valor de retorno';
});
// O valor retornado pelo callback é retornado ao chamador
console.log(ret); //? "valor de retorno"
Feedback
Esta página foi útil?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!