O Deno tem suporte integrado a OpenTelemetry.
OpenTelemetry is a collection of APIs, SDKs, and tools. Use it to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) to help you analyze your software’s performance and behavior.
Essa integração permite monitorar aplicações Deno usando ferramentas de observabilidade OpenTelemetry com instrumentos como logs, métricas e traces.
O Deno fornece os seguintes recursos:
- Exportação de métricas, traces e logs coletados para um servidor usando o protocolo OpenTelemetry.
- Instrumentação automática do runtime Deno com métricas, traces e logs OpenTelemetry.
- Coleta de métricas, traces e logs definidos pelo usuário
criados com o pacote
npm:@opentelemetry/api.
Início rápido
Para ativar a integração OpenTelemetry, defina a variável de ambiente
OTEL_DENO=true:
OTEL_DENO=true deno run my_script.tsIsso coletará e exportará automaticamente dados de observabilidade do runtime
para um endpoint OpenTelemetry em localhost:4318, usando Protobuf sobre HTTP
(http/protobuf).
:::tip
Se quiser ver rapidamente a saída OpenTelemetry sem configurar um collector, você pode usar o console exporter integrado para imprimir spans, logs e métricas diretamente em stderr em formato legível:
OTEL_DENO=true OTEL_EXPORTER_OTLP_PROTOCOL=console deno run my_script.tsSaída de exemplo:
SPAN inner span [00000000000000000000000000000001/0000000000000002] Internal 0.495ms
parent: 0000000000000001
scope: example-tracer
key: value
LOG [INFO] 2025-03-14T13:47:07.235Z "hello from inner"
scope: [email protected]
trace: 00000000000000000000000000000001/0000000000000002:::
:::tip
Se quiser visualizar dados de telemetria em um dashboard, você pode começar com uma stack LGTM local no Docker (Loki (logs), Grafana (dashboard), Tempo (traces) e Prometheus (metrics)) executando o comando:
docker run --name lgtm -p 3000:3000 -p 4317:4317 -p 4318:4318 --rm -ti \
-v "$PWD"/lgtm/grafana:/data/grafana \
-v "$PWD"/lgtm/prometheus:/data/prometheus \
-v "$PWD"/lgtm/loki:/data/loki \
-e GF_PATHS_DATA=/data/grafana \
docker.io/grafana/otel-lgtm:0.8.1Depois você pode acessar o dashboard Grafana em http://localhost:3000 com o
usuário admin e senha admin.
:::
Isso coletará e exportará automaticamente dados de observabilidade do runtime,
como console.log, traces para requisições HTTP e métricas do runtime Deno.
Saiba mais sobre auto instrumentação.
Você também pode criar suas próprias métricas, traces e logs usando o pacote
npm:@opentelemetry/api.
Saiba mais sobre métricas definidas pelo usuário.
Auto instrumentation
O Deno coleta e exporta automaticamente alguns dados de observabilidade para o endpoint OTLP.
Esses dados são exportados no instrumentation scope integrado do runtime Deno.
Esse scope tem o nome deno. A versão do runtime Deno é a versão do
instrumentation scope deno (por exemplo, deno:2.1.4).
Traces
O Deno cria spans automaticamente para várias operações, como:
- Requisições HTTP recebidas servidas com
Deno.serve. - Requisições HTTP de saída feitas com
fetch. - Invocações de jobs
Deno.cron()(adicionado no Deno 2.7).
Deno.serve
Quando você usa Deno.serve para criar um servidor
HTTP, um span é criado para cada requisição recebida. O span termina
automaticamente quando os headers de resposta são enviados (não quando o corpo
da resposta termina de ser enviado).
O nome do span criado é ${method}. O span kind é server.
Os seguintes atributos são adicionados automaticamente ao span na criação:
http.request.method: o método HTTP da requisição.url.full: a URL completa da requisição (como seria reportada porreq.url).url.scheme: o scheme da URL da requisição (por exemplo,httpouhttps).url.path: o caminho da URL da requisição.url.query: a query string da URL da requisição.
Depois que a requisição é tratada, os seguintes atributos são adicionados:
http.response.status_code: o status code da resposta.
O Deno não adiciona automaticamente um atributo http.route ao span, pois a
rota não é conhecida pelo runtime e é determinada pela lógica de roteamento na
função handler do usuário. Se quiser adicionar um atributo http.route ao span,
você pode fazê-lo na sua função handler usando npm:@opentelemetry/api. Nesse
caso, você também deve atualizar o nome do span para incluir a rota.
import { trace } from "npm:@opentelemetry/api@1";
const INDEX_ROUTE = new URLPattern({ pathname: "/" });
const BOOK_ROUTE = new URLPattern({ pathname: "/book/:id" });
Deno.serve(async (req) => {
const span = trace.getActiveSpan();
if (INDEX_ROUTE.test(req.url)) {
span.setAttribute("http.route", "/");
span.updateName(`${req.method} /`);
// handle index route
} else if (BOOK_ROUTE.test(req.url)) {
span.setAttribute("http.route", "/book/:id");
span.updateName(`${req.method} /book/:id`);
// handle book route
} else {
return new Response("Not found", { status: 404 });
}
});fetch
Quando você usa fetch para fazer uma requisição HTTP, um
span é criado para a requisição. O span termina automaticamente quando os
headers da resposta são recebidos.
O nome do span criado é ${method}. O span kind é client.
Os seguintes atributos são adicionados automaticamente ao span na criação:
http.request.method: o método HTTP da requisição.url.full: a URL completa da requisição.url.scheme: o scheme da URL da requisição.url.path: o caminho da URL da requisição.url.query: a query string da URL da requisição.
Depois que a resposta é recebida, os seguintes atributos são adicionados:
http.status_code: o status code da resposta.
Métricas
As seguintes métricas são coletadas e exportadas automaticamente:
Deno.serve / Deno.serveHttp
http.server.request.duration
Um histograma da duração de requisições HTTP recebidas servidas com
Deno.serve ou
Deno.serveHttp. O tempo medido vai do
recebimento da requisição até o envio dos headers de resposta. Isso não inclui o
tempo para enviar o corpo da resposta. A unidade dessa métrica é segundos. Os
buckets do histograma são
[0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0].
Esta métrica é registrada com os seguintes atributos:
http.request.method: o método HTTP da requisição.url.scheme: o scheme da URL da requisição.network.protocol.version: a versão do protocolo HTTP usado na requisição (por exemplo,1.1ou2).server.address: o endereço em que o servidor está escutando.server.port: a porta em que o servidor está escutando.http.response.status_code: o status code da resposta (se a requisição foi tratada sem erro fatal).error.type: o tipo de erro ocorrido (se o tratamento da requisição foi sujeito a erro).
http.server.active_requests
Um gauge do número de requisições ativas sendo tratadas por
Deno.serve ou
Deno.serveHttp em um dado momento. Este é o
número de requisições recebidas mas ainda não respondidas (quando os headers de
resposta ainda não foram enviados). Esta métrica é registrada com os seguintes
atributos:
http.request.method: o método HTTP da requisição.url.scheme: o scheme da URL da requisição.server.address: o endereço em que o servidor está escutando.server.port: a porta em que o servidor está escutando.
http.server.request.body.size
Um histograma do tamanho do corpo da requisição em requisições HTTP recebidas
servidas com Deno.serve ou
Deno.serveHttp. A unidade dessa métrica é bytes.
Os buckets do histograma são
[0, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000].
Esta métrica é registrada com os seguintes atributos:
http.request.method: o método HTTP da requisição.url.scheme: o scheme da URL da requisição.network.protocol.version: a versão do protocolo HTTP usado na requisição (por exemplo,1.1ou2).server.address: o endereço em que o servidor está escutando.server.port: a porta em que o servidor está escutando.http.response.status_code: o status code da resposta (se a requisição foi tratada sem erro fatal).error.type: o tipo de erro ocorrido (se o tratamento da requisição foi sujeito a erro).
http.server.response.body.size
Um histograma do tamanho do corpo da resposta em requisições HTTP recebidas
servidas com Deno.serve ou
Deno.serveHttp. A unidade dessa métrica é bytes.
Os buckets do histograma são
[0, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000].
Esta métrica é registrada com os mesmos atributos de
http.server.request.body.size.
Logs
Os seguintes logs são coletados e exportados automaticamente:
- Qualquer log criado com métodos
console.*, comoconsole.logeconsole.error. - Qualquer log criado pelo runtime Deno, como logs de debug, logs
Downloadinge similares. - Qualquer erro que faça o runtime Deno sair (tanto de código do usuário quanto do próprio runtime).
Logs emitidos por código JavaScript serão exportados com o contexto de span relevante, se o log ocorreu dentro de um span ativo.
A auto instrumentação de console pode ser configurada com a variável de
ambiente OTEL_DENO_CONSOLE:
capture: logs são emitidos para stdout/stderr e também exportados com OpenTelemetry (padrão).replace: logs são apenas exportados com OpenTelemetry, não emitidos para stdout/stderr.ignore: logs são emitidos apenas para stdout/stderr e não serão exportados com OpenTelemetry.
Auditoria de permissões
O Deno pode rotear o log de auditoria de permissões para o exporter
OpenTelemetry junto do restante dos seus traces, métricas e logs. Defina
DENO_AUDIT_PERMISSIONS=otel (em vez de um caminho de arquivo) e cada acesso a
permissão — permitido ou negado — será emitido como um registro de log
OpenTelemetry com estes atributos:
deno.permission.type— o nome da permissão (read,net,env, …).deno.permission.value— o valor específico sendo verificado (um caminho, host, nome de variável etc.).deno.permission.stack— os frames de stack JavaScript no local de acesso, presente apenas quandoDENO_TRACE_PERMISSIONStambém está definido.
OTEL_DENO=true DENO_AUDIT_PERMISSIONS=otel deno run -A main.tsIsso é útil quando você já coleta dados OpenTelemetry: a auditoria chega ao mesmo backend dos traces de requisição, então você pode correlacionar qual requisição acionou qual acesso de permissão. Veja auditoria de permissões para o conjunto completo de atributos e o modo JSONL com caminho de arquivo.
Métricas do usuário
Além dos dados de telemetria coletados automaticamente, você também pode criar
suas próprias métricas e traces usando o pacote npm:@opentelemetry/api.
Você não precisa configurar o pacote npm:@opentelemetry/api para usá-lo com o
Deno. O Deno configura o pacote automaticamente. Não é necessário chamar
metrics.setGlobalMeterProvider(), trace.setGlobalTracerProvider() ou
context.setGlobalContextManager(). Toda configuração de resources, exporter
settings etc. é feita por variáveis de ambiente.
O Deno funciona com a versão 1.x do pacote npm:@opentelemetry/api. Você pode
importar diretamente de npm:@opentelemetry/api@1 ou instalar o pacote
localmente com deno add e importar de @opentelemetry/api.
deno add npm:@opentelemetry/api@1Tanto para traces quanto para métricas, você precisa definir nomes para o tracer
e o meter. Se está instrumentando uma biblioteca, nomeie o tracer ou meter a
partir da biblioteca (como my-awesome-lib). Se está instrumentando uma
aplicação, use o nome da aplicação (como my-app). A versão do tracer ou meter
deve ser definida como a versão da biblioteca ou aplicação.
Traces
Para criar um novo span, primeiro importe o objeto trace de
npm:@opentelemetry/api e crie um novo tracer:
import { trace } from "npm:@opentelemetry/api@1";
const tracer = trace.getTracer("my-app", "1.0.0");Depois, crie um novo span usando tracer.startActiveSpan e passe uma função
callback. Você precisa encerrar manualmente o span chamando end no objeto span
retornado por startActiveSpan.
function myFunction() {
return tracer.startActiveSpan("myFunction", (span) => {
try {
// do myFunction's work
} catch (error) {
span.recordException(error);
span.setStatus({
code: trace.SpanStatusCode.ERROR,
message: (error as Error).message,
});
throw error;
} finally {
span.end();
}
});
}span.end() deve ser chamado em um bloco finally para garantir que o span
termine mesmo se ocorrer erro. span.recordException e span.setStatus também
devem ser chamados em um bloco catch, para registrar erros ocorridos.
Dentro do callback, o span criado é o "active span". Você pode obtê-lo com
trace.getActiveSpan(). O "active span" será usado como parent span para spans
criados (manualmente ou automaticamente pelo runtime) dentro do callback (ou em
funções chamadas a partir dele).
Saiba mais sobre propagação de contexto.
O método startActiveSpan retorna o valor de retorno do callback.
Spans podem receber atributos durante sua vida. Atributos são pares chave-valor
que representam metadados estruturados sobre o span. Eles podem ser adicionados
com setAttribute e setAttributes.
span.setAttribute("key", "value");
span.setAttributes({ success: true, "bar.count": 42n, "foo.duration": 123.45 });Valores de atributo podem ser strings, números (floats), bigints (limitados a u64), booleans ou arrays desses tipos. Outros valores são ignorados.
O nome de um span pode ser atualizado com updateName.
span.updateName("new name");O status de um span pode ser definido com setStatus. recordException
registra uma exceção ocorrida durante a vida do span, criando um evento com
stack trace e nome da exceção e anexando-o ao span. recordException não
define o status do span como ERROR; você deve fazer isso manualmente.
import { SpanStatusCode } from "npm:@opentelemetry/api@1";
span.setStatus({
code: SpanStatusCode.ERROR,
message: "An error occurred",
});
span.recordException(new Error("An error occurred"));
// or
span.setStatus({
code: SpanStatusCode.OK,
});Spans também podem ter events e links adicionados. Events são pontos no tempo associados ao span. Links são referências a outros spans.
// Add an event to the span
span.addEvent("button_clicked", {
id: "submit-button",
action: "submit",
});
// Add an event with a timestamp
span.addEvent("process_completed", { status: "success" }, Date.now());Events podem incluir atributos opcionais semelhantes a spans. Eles são úteis para marcar momentos significativos dentro da vida do span sem criar spans separados.
Spans também podem ser criados manualmente com tracer.startSpan, que retorna
um objeto span. Esse método não define o span criado como active span, então ele
não será usado automaticamente como parent span para spans criados depois, nem
para chamadas console.log. Um span pode ser definido manualmente como active
span para um callback usando a
API de propagação de contexto.
Tanto tracer.startActiveSpan quanto tracer.startSpan podem receber um objeto
de opções opcional contendo:
kind: o tipo do span. Pode serSpanKind.CLIENT,SpanKind.SERVER,SpanKind.PRODUCER,SpanKind.CONSUMERouSpanKind.INTERNAL. O padrão éSpanKind.INTERNAL.startTime: um objetoDaterepresentando o início do span, ou um número em milissegundos desde Unix epoch. Se omitido, usa o horário atual.attributes: objeto com atributos para adicionar ao span.links: array de links para adicionar ao span.root: boolean indicando se o span deve ser root. Setrue, o span não terá parent span (mesmo se houver um active span).
Depois do objeto de opções, ambos também podem receber um objeto context da
API de propagação de contexto.
Saiba mais sobre a API completa de tracing na documentação da API OpenTelemetry JS.
Métricas
Para criar uma métrica, primeiro importe o objeto metrics de
npm:@opentelemetry/api e crie um novo meter:
import { metrics } from "npm:@opentelemetry/api@1";
const meter = metrics.getMeter("my-app", "1.0.0");Depois, um instrumento pode ser criado a partir do meter e usado para registrar valores:
const counter = meter.createCounter("my_counter", {
description: "A simple counter",
unit: "1",
});
counter.add(1);
counter.add(2);Cada registro também pode ter atributos associados:
counter.add(1, { color: "red" });
counter.add(2, { color: "blue" });:::tip
Em OpenTelemetry, atributos de métricas geralmente devem ter baixa cardinalidade. Isso significa que não devem existir combinações únicas demais de valores de atributos. Por exemplo, provavelmente tudo bem ter um atributo para o continente do usuário, mas seria cardinalidade alta demais ter latitude e longitude exatas. Atributos de alta cardinalidade podem causar problemas de armazenamento e exportação de métricas e devem ser evitados. Use spans e logs para dados de alta cardinalidade.
:::
Há vários tipos de instrumentos que podem ser criados com um meter:
- Counter: valor monotonicamente crescente. Counters só podem ser positivos e servem para valores que sempre aumentam, como número de requisições tratadas.
- UpDownCounter: valor que pode aumentar e diminuir, como número de conexões ativas ou requisições em andamento.
- Gauge: valor que pode ser definido para qualquer valor, usado para coisas que não "acumulam" ao longo do tempo, mas têm um valor específico em dado momento, como temperatura atual.
- Histogram: valor registrado como distribuição. Histogramas servem para
valores como tempo de resposta de uma requisição em milissegundos e podem
calcular percentis, médias e outras estatísticas. Eles têm limites de buckets
predefinidos; por padrão:
[0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0].
Também existem instrumentos observáveis. Eles não têm método síncrono de registro; em vez disso, retornam um callback chamado quando o SDK OpenTelemetry está pronto para registrar um valor, por exemplo logo antes de exportar.
const counter = meter.createObservableCounter("my_counter", {
description: "A simple counter",
unit: "1",
});
counter.addCallback((res) => {
res.observe(1);
// or
res.observe(1, { color: "red" });
});Há três tipos de instrumentos observáveis:
- ObservableCounter: counter observado assincronamente, útil para valores que sempre aumentam.
- ObservableUpDownCounter: valor que pode aumentar e diminuir e ser observado assincronamente.
- ObservableGauge: valor observado assincronamente que pode assumir qualquer valor em dado momento.
Saiba mais sobre a API completa de métricas na documentação da API OpenTelemetry JS.
Exemplos práticos
Para exemplos práticos de implementação de OpenTelemetry em aplicações Deno, veja nossos tutoriais:
- Tutorial básico de OpenTelemetry - Um servidor HTTP simples com métricas e traces customizados
- Tutorial de Distributed Tracing - Técnicas avançadas para tracing através de fronteiras de serviço
Propagação de contexto
Em OpenTelemetry, propagação de contexto é o processo de passar informações de contexto (como o span atual) de uma parte da aplicação para outra, sem precisar passá-las explicitamente como argumento para toda função.
No Deno, a propagação de contexto usa as regras de AsyncContext, a proposta
TC39 para propagação de contexto assíncrono. A API AsyncContext ainda não é
exposta a usuários no Deno, mas é usada internamente para propagar o active span
e outras informações de contexto através de fronteiras assíncronas.
Resumo rápido de como a propagação AsyncContext funciona:
- Quando uma nova task assíncrona é iniciada (como uma promise ou timer), o contexto atual é salvo.
- Então outro código pode executar concorrentemente com a task assíncrona, em um contexto diferente.
- Quando a task assíncrona termina, o contexto salvo é restaurado.
Isso significa que a propagação de contexto assíncrono se comporta essencialmente como uma variável global escopada à task assíncrona atual, e é copiada automaticamente para novas tasks assíncronas iniciadas a partir dela.
A API context de npm:@opentelemetry/api@1 expõe essa funcionalidade:
import { context } from "npm:@opentelemetry/api@1";
// Get the currently active context
const currentContext = context.active();
// You can add create a new context with a value added to it
const newContext = currentContext.setValue("id", 1);
// The current context is not changed by calling setValue
console.log(currentContext.getValue("id")); // undefined
// You can run a function inside a new context
context.with(newContext, () => {
// Any code in this block will run with the new context
console.log(context.active().getValue("id")); // 1
// The context is also available in any functions called from this block
function myFunction() {
return context.active().getValue("id");
}
console.log(myFunction()); // 1
// And it is also available in any asynchronous callbacks scheduled from here
setTimeout(() => {
console.log(context.active().getValue("id")); // 1
}, 10);
});
// Outside, the context is still the same
console.log(context.active().getValue("id")); // undefinedA API de contexto também integra com spans. Para rodar uma função no contexto de um span específico, o span pode ser adicionado a um contexto, e então a função pode rodar nesse contexto:
import { context, trace } from "npm:@opentelemetry/api@1";
const tracer = trace.getTracer("my-app", "1.0.0");
const span = tracer.startSpan("myFunction");
const contextWithSpan = trace.setSpan(context.active(), span);
context.with(contextWithSpan, () => {
const activeSpan = trace.getActiveSpan();
console.log(activeSpan === span); // true
});
// Don't forget to end the span!
span.end();Saiba mais sobre a API completa de contexto na documentação da API OpenTelemetry JS.
Configuração
A integração OpenTelemetry pode ser ativada definindo a variável de ambiente
OTEL_DENO=true.
O endpoint e protocolo do OTLP exporter podem ser configurados com as variáveis
OTEL_EXPORTER_OTLP_ENDPOINT e OTEL_EXPORTER_OTLP_PROTOCOL. Valores aceitos
para OTEL_EXPORTER_OTLP_PROTOCOL:
http/protobuf(padrão): exporta usando Protobuf sobre HTTP para o endpoint configurado.http/json: exporta usando JSON sobre HTTP para o endpoint configurado.grpc: exporta usando gRPC (Protobuf sobre HTTP/2). Disponível no Deno 2.8+. Útil para collectors que aceitam apenas gRPC, como o agente OpenTelemetry gerenciado do Azure Container Apps. A porta OTLP gRPC padrão é4317, então você normalmente também defineOTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317.console: imprime spans, logs e métricas em stderr em formato de texto legível. Útil para depurar e testar instrumentação sem rodar um collector OTLP. Ao usarconsole, nenhuma configuração de endpoint é necessária.
Se o endpoint exigir autenticação, headers podem ser configurados com
OTEL_EXPORTER_OTLP_HEADERS.
Endpoints também podem ser sobrescritos individualmente para métricas, traces e logs usando variáveis específicas, como:
OTEL_EXPORTER_OTLP_METRICS_ENDPOINTOTEL_EXPORTER_OTLP_TRACES_ENDPOINTOTEL_EXPORTER_OTLP_LOGS_ENDPOINT
Para mais informações sobre headers que podem configurar o OTLP exporter, veja o site OpenTelemetry.
O resource associado aos dados de telemetria pode ser configurado com
OTEL_SERVICE_NAME e OTEL_RESOURCE_ATTRIBUTES. Além dos atributos definidos
via OTEL_RESOURCE_ATTRIBUTES, os seguintes são definidos automaticamente:
service.name: seOTEL_SERVICE_NAMEnão estiver definido, o valor é<unknown_service>.process.runtime.name:denoprocess.runtime.version: a versão do runtime Deno.telemetry.sdk.name:deno-opentelemetrytelemetry.sdk.language:deno-rusttelemetry.sdk.version: a versão do runtime Deno mais a versão do crate Rustopentelemetryusado pelo Deno, separadas por-.
Propagators podem ser configurados com OTEL_PROPAGATORS. O padrão é
tracecontext,baggage. Múltiplos propagators podem ser separados por vírgula.
Atualmente são aceitos:
tracecontext: formato W3C Trace Contextbaggage: formato W3C Baggage
A frequência de coleta de métricas pode ser configurada com
OTEL_METRIC_EXPORT_INTERVAL. O padrão é 60000 milissegundos (60 segundos).
Batching do span exporter e do log exporter pode ser configurado pelas variáveis descritas na especificação OpenTelemetry e na seção de batch log record processor.
Propagators
O Deno oferece suporte a propagators de contexto, que permitem propagação automática de contexto de trace entre limites de processo para distributed tracing, permitindo acompanhar requisições enquanto fluem por serviços diferentes.
Propagators são responsáveis por codificar e decodificar informações de contexto (como trace e span IDs) para e de formatos carrier (como headers HTTP). Isso permite manter o contexto de trace através de fronteiras de serviço.
Por padrão, o Deno oferece suporte a:
tracecontext: formato W3C Trace Context, o padrão para propagar contexto de trace via headers HTTP.baggage: formato W3C Baggage, que permite passar pares chave-valor através de fronteiras de serviço.
:::note
Esses propagators funcionam automaticamente com a API
fetch do Deno e Deno.serve,
habilitando tracing ponta a ponta em requisições HTTP sem gerenciamento manual
de contexto.
:::
Você pode acessar a API de propagação pelo pacote @opentelemetry/api:
import { context, propagation, trace } from "npm:@opentelemetry/api@1";
// Extract context from incoming headers
function extractContextFromHeaders(headers: Headers) {
const ctx = context.active();
return propagation.extract(ctx, headers);
}
// Inject context into outgoing headers
function injectContextIntoHeaders(headers: Headers) {
const ctx = context.active();
propagation.inject(ctx, headers);
return headers;
}
// Example: Making a fetch request that propagates trace context
async function tracedFetch(url: string) {
const headers = new Headers();
injectContextIntoHeaders(headers);
return await fetch(url, { headers });
}Limitações
Enquanto a integração OpenTelemetry para Deno está em desenvolvimento, há algumas limitações importantes:
- Traces são sempre amostrados (ou seja,
OTEL_TRACE_SAMPLER=parentbased_always_on). - Traces só aceitam links sem atributos.
- Metric exemplars não têm suporte.
- Streams de log customizados (por exemplo, logs que não sejam
console.logeconsole.error) não têm suporte. - Os exporters aceitos são OTLP (
http/protobuf,http/json,grpc) econsole. Outros formatos de exporter não têm suporte. - Métricas de meters observáveis (assíncronos) não são coletadas em exit/crash do processo, então o último valor pode não ser exportado. Métricas síncronas são exportadas em exit/crash.
- Os limites especificados nas variáveis
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT,OTEL_ATTRIBUTE_COUNT_LIMIT,OTEL_SPAN_EVENT_COUNT_LIMIT,OTEL_SPAN_LINK_COUNT_LIMIT,OTEL_EVENT_ATTRIBUTE_COUNT_LIMITeOTEL_LINK_ATTRIBUTE_COUNT_LIMITnão são respeitados para trace spans. - A variável
OTEL_METRIC_EXPORT_TIMEOUTnão é respeitada. - Métodos HTTP desconhecidos não são normalizados para
_OTHERno atributohttp.request.method, conforme as convenções semânticas OpenTelemetry. - O span de servidor HTTP para
Deno.servenão tem um status OpenTelemetry definido; se o handler lança erro (ou seja,onErroré invocado), o span não terá status de erro e o erro não será anexado ao span por evento. - Não há mecanismo para adicionar atributo
http.routeao span cliente HTTP defetch, nem para atualizar o nome do span para incluir a rota.