Instrumentação
Instrumentação é o ato de adicionar código de observabilidade a uma aplicação por conta própria.
Se você estiver instrumentando uma aplicação, será necessário utilizar o SDK do OpenTelemetry para sua linguagem. Você irá utilizar o SDK para inicializar o OpenTelemetry e a API para instrumentar seu código. Isso passará a emitir dados de telemetria da sua aplicação e de qualquer biblioteca que você tenha instalado que também possua instrumentação.
Se você estiver instrumentando uma biblioteca, instale apenas o pacote da API do OpenTelemetry para sua linguagem. Sua biblioteca não emitirá telemetria por conta própria; ela só emitirá telemetria quando fizer parte de uma aplicação que utiliza o SDK do OpenTelemetry. Para mais informações sobre a instrumentação de bibliotecas, consulte a seção Bibliotecas.
Para mais informações sobre a API e o SDK do OpenTelemetry, consulte a especificação.
Configuração
Primeiro, certifique-se de ter os pacotes da API e SDK:
pip install opentelemetry-api
pip install opentelemetry-sdk
Rastros
Obter um Rastreador
Para começar a rastrear, você precisará inicializar um
TracerProvider
e
opcionalmente defini-lo como o padrão global.
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
BatchSpanProcessor,
ConsoleSpanExporter,
)
provider = TracerProvider()
processor = BatchSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
# Define o provedor global padrão de rastreador
trace.set_tracer_provider(provider)
# Cria um rastreador a partir do provedor global de rastreador
tracer = trace.get_tracer("meu.rastreador.nome")
Criando Trechos
Para criar um trecho, normalmente você vai querer que seja iniciado como o trecho atual.
def fazer_trabalho():
with tracer.start_as_current_span("nome-do-trecho") as span:
# faça algum trabalho que 'span' irá rastrear
print("fazendo algum trabalho...")
# Quando o bloco 'with' sair do escopo, 'span' será fechado para você
Você também pode usar start_span
para criar um trecho sem torná-lo o trecho
atual. Isso geralmente é feito para rastrear operações concorrentes ou
assíncronas.
Criando Trechos Aninhados
Se você tiver uma sub-operação distinta que gostaria de rastrear como parte de outra, você pode criar trechos para representar a relação:
def fazer_trabalho():
with tracer.start_as_current_span("pai") as parent:
# faça algum trabalho que 'pai' rastreia
print("fazendo algum trabalho...")
# Crie um trecho aninhado para rastrear o trabalho aninhado
with tracer.start_as_current_span("filho") as child:
# faça algum trabalho que 'filho' rastreia
print("fazendo algum trabalho aninhado...")
# o trecho aninhado é fechado quando sai do escopo
# Este trecho também é fechado quando sai do escopo
Quando você visualizar trechos em uma ferramenta de visualização de rastros,
filho
será rastreado como um trecho aninhado sob pai
.
Criando Trechos com Decoradores
É comum ter um único trecho rastreando a execução de uma função inteira. Nesse cenário, há um decorador que você pode usar para reduzir o código:
@tracer.start_as_current_span("fazer_trabalho")
def fazer_trabalho():
print("fazendo algum trabalho...")
O uso do decorador é equivalente a criar o trecho dentro de fazer_trabalho()
e
finalizá-lo quando fazer_trabalho()
for concluído.
Para usar o decorador, você deve ter uma instância de tracer
disponível
globalmente para a declaração da sua função.
Obter o Trecho Atual
Às vezes, é útil acessar o trecho atual em um ponto no tempo para que você possa enriquecê-lo com mais informações.
from opentelemetry import trace
current_span = trace.get_current_span()
# enriqueça 'current_span' com algumas informações
Adicionar Atributos em um Trecho
Os Atributos permitem que você anexe pares de chave/valor em um trecho para transportar mais informações sobre a operação que está sendo rastreada.
from opentelemetry import trace
current_span = trace.get_current_span()
current_span.set_attribute("operacao.valor", 1)
current_span.set_attribute("operacao.nome", "Dizendo olá!")
current_span.set_attribute("operacao.outras-coisas", [1, 2, 3])
Adicionar Atributos Semânticos
Os Atributos Semânticos são Atributos predeterminados, que são nomenclaturas bastante conhecidas para tipos comuns de dados. Usar Atributos Semânticos permite que você normalize esse tipo de informação em seus sistemas.
Para usar Atributos Semânticos em Python, certifique-se de ter o pacote de convenções semânticas:
pip install opentelemetry-semantic-conventions
Então você pode usá-lo no código:
from opentelemetry import trace
from opentelemetry.semconv.trace import SpanAttributes
// ...
current_span = trace.get_current_span()
current_span.set_attribute(SpanAttributes.HTTP_METHOD, "GET")
current_span.set_attribute(SpanAttributes.HTTP_URL, "https://opentelemetry.io/")
Adicionando Eventos
Um evento é uma mensagem legível por humanos em um trecho que representa “algo está acontecendo” durante sua vida. Você pode pensar nisso como um log primitivo.
from opentelemetry import trace
current_span = trace.get_current_span()
current_span.add_event("Vou tentar!")
# Faça alguma coisa
current_span.add_event("Consegui!")
Adicionando Links
Um trecho pode ser criado com zero ou mais links de trecho que o vinculam causalmente a outro trecho. Um link precisa de um contexto de trecho para ser criado.
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("trecho-1"):
# Faça algo que 'trecho-1' rastreia.
ctx = trace.get_current_span().get_span_context()
link_from_span_1 = trace.Link(ctx)
with tracer.start_as_current_span("trecho-2", links=[link_from_span_1]):
# Faça algo que 'trecho-2' rastreia.
# O link em 'trecho-2' está causalmente associado ao 'trecho-1',
# mas não é um trecho filho.
pass
Definir Status do Trecho
A Status can be set on a
Span, typically used to specify that a
Span has not completed successfully - Error
. By default, all spans are
Unset
, which means a span completed without error. The Ok
status is reserved
for when you need to explicitly mark a span as successful rather than stick with
the default of Unset
(i.e., “without error”).
The status can be set at any time before the span is finished.
from opentelemetry import trace
from opentelemetry.trace import Status, StatusCode
current_span = trace.get_current_span()
try:
# algo que pode falhar
except:
current_span.set_status(Status(StatusCode.ERROR))
Registrar Exceções em Trechos
Pode ser uma boa ideia registrar exceções quando elas acontecem. Recomenda-se fazer isso em conjunto com a definição do status do trecho.
from opentelemetry import trace
from opentelemetry.trace import Status, StatusCode
current_span = trace.get_current_span()
try:
# algo que pode falhar
# Considere capturar uma exceção mais específica em seu código
except Exception as ex:
current_span.set_status(Status(StatusCode.ERROR))
current_span.record_exception(ex)
Alterar o Formato de Propagação Padrão
Por padrão, o OpenTelemetry Python usará os seguintes formatos de propagação:
- W3C Trace Context
- W3C Baggage
Se você precisar alterar os padrões, pode fazê-lo por meio de variáveis de ambiente ou no código:
Usando Variáveis de Ambiente
Você pode definir a variável de ambiente OTEL_PROPAGATORS
com uma lista
separada por vírgulas. Os valores aceitos são:
"tracecontext"
: W3C Trace Context"baggage"
: W3C Baggage"b3"
: B3 Single"b3multi"
: B3 Multi"jaeger"
: Jaeger"xray"
: AWS X-Ray (terceiros)"ottrace"
: OT Trace (terceiros)"none"
: Nenhum propagador configurado automaticamente.
A configuração padrão é equivalente a OTEL_PROPAGATORS="tracecontext,baggage"
.
Usando APIs do SDK
Como alternativa, você pode alterar o formato no código.
Por exemplo, se você precisar usar o formato de propagação B3 do Zipkin, pode instalar o pacote B3:
pip install opentelemetry-propagator-b3
E então definir o propagador B3 no seu código de inicialização de rastreamento:
from opentelemetry.propagate import set_global_textmap
from opentelemetry.propagators.b3 import B3Format
set_global_textmap(B3Format())
Observe que as variáveis de ambiente substituirão o que está configurado no código.
Leituras Adicionais
- Conceitos de Rastros
- Especificação de Rastros
- Documentação da API de Rastros do Python
- Documentação do SDK de Rastros do Python
Métricas
Para começar a coletar métricas, você precisará inicializar um
MeterProvider
e opcionalmente
defini-lo como o padrão global.
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import (
ConsoleMetricExporter,
PeriodicExportingMetricReader,
)
metric_reader = PeriodicExportingMetricReader(ConsoleMetricExporter())
provider = MeterProvider(metric_readers=[metric_reader])
# Define o provedor global padrão de medidor
metrics.set_meter_provider(provider)
# Cria um medidor a partir do provedor global de medidor
meter = metrics.get_meter("meu.medidor.nome")
Criando e Usando Instrumentos Síncronos
Os instrumentos síncronos são usados para fazer medições do seu aplicativo e são usados em linha com a lógica de processamento de aplicativos/negócios, como ao lidar com uma solicitação ou chamar outro serviço.
Primeiro, crie seu instrumento. Os instrumentos geralmente são criados uma vez no nível do módulo ou da classe e depois usados em linha com a lógica de negócios. Este exemplo usa um instrumento Counter para contar o número de itens de trabalho concluídos:
work_counter = meter.create_counter(
"trabalho.contador", unit="1", description="Conta a quantidade de trabalho feito"
)
Usando a operação de adição do Counter, o código abaixo incrementa a contagem em um, usando o tipo de item de trabalho como um atributo.
def fazer_trabalho(item_trabalho):
# conta o trabalho sendo feito
work_counter.add(1, {"trabalho.tipo": item_trabalho.tipo_trabalho})
print("fazendo algum trabalho...")
Criando e Usando Instrumentos Assíncronos
Instrumentos assíncronos fornecem ao usuário uma maneira de registrar funções de callback, que são invocadas sob demanda para fazer medições. Isso é útil para medir periodicamente um valor que não pode ser instrumentado diretamente. Os instrumentos assíncronos são criados com zero ou mais callbacks que serão invocados durante a coleta de métricas. Cada callback aceita opções do SDK e retorna suas observações.
Este exemplo usa um instrumento Gauge Assíncrono para relatar a versão de configuração atual fornecida por um servidor de configuração, por meio da extração de um endpoint HTTP. Primeiro, escreva um callback para fazer observações:
from typing import Iterable
from opentelemetry.metrics import CallbackOptions, Observation
def raspar_versoes_configuracao(options: CallbackOptions) -> Iterable[Observation]:
r = requests.get(
"http://configserver/version_metadata", timeout=options.timeout_millis / 10**3
)
for metadata in r.json():
yield Observation(
metadata["version_num"], {"config.name": metadata["version_num"]}
)
Observe que o OpenTelemetry passará opções para seu callback contendo um timeout. Os callbacks devem respeitar esse timeout para evitar bloqueios indefinidamente. Por fim, crie o instrumento com o callback para registrá-lo:
meter.create_observable_gauge(
"config.versao",
callbacks=[raspar_versoes_configuracao],
description="A versão de configuração ativa para cada configuração",
)
Leituras Adicionais
- Conceitos de Métricas
- Especificação de Métricas
- Documentação da API de Métricas do Python
- Documentação do SDK de Métricas do Python
Logs
A API e o SDK de logs estão atualmente em desenvolvimento.
Próximos Passos
Você também desejará configurar um exportador apropriado para exportar seus dados de telemetria para um ou mais backends de telemetria.
Feedback
Was this page helpful?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!