Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Grafana Tempo no Node.js

Atualizado em: 12 de setembro de 2026

Rack de servidores processando fluxos de dados no Node.js

O Grafana Tempo no Node.js é uma opção para armazenar e consultar traces distribuídos produzidos por OpenTelemetry. A aplicação instrumentada envia spans por OTLP para um Collector ou Grafana Alloy, que encaminha os dados ao Tempo. No Grafana, a equipe pesquisa traces, analisa o caminho crítico e relaciona erros com logs e métricas.

Tempo foi projetado para alto volume e armazenamento econômico em object storage. Em vez de indexar todos os atributos de forma tradicional, ele combina metadados, blocos compactados e TraceQL para localizar operações. Essa arquitetura reduz custo, mas exige planejamento de retenção, cardinalidade, sampling e capacidade de consulta.

Neste guia, você aprenderá a executar Tempo, enviar traces de uma aplicação Node.js, configurar OpenTelemetry Collector, usar TraceQL, criar métricas a partir de spans e correlacionar Tempo com Loki e Prometheus.

O que é Grafana Tempo?

A documentação oficial do Grafana Tempo descreve o projeto como um backend open source de distributed tracing, integrado ao Grafana, Loki, Prometheus, Mimir e OpenTelemetry. Ele aceita protocolos como OTLP, Jaeger e Zipkin.

Os principais objetivos são:

  • armazenar traces em grande escala;
  • usar object storage;
  • consultar com TraceQL;
  • gerar métricas a partir de spans;
  • correlacionar traces, logs e métricas;
  • reduzir custo operacional.

Arquitetura básica

Um fluxo comum:

  1. a aplicação Node.js cria spans;
  2. o SDK exporta OTLP;
  3. OpenTelemetry Collector recebe e aplica batch;
  4. o Collector envia ao distributor do Tempo;
  5. Tempo grava blocos em object storage;
  6. Grafana consulta por TraceQL ou trace ID.

Consulte OpenTelemetry no Node.js para instrumentação.

Executando localmente

Para desenvolvimento, use Docker Compose com Tempo e Grafana. Uma configuração simplificada:

services:
  tempo:
    image: grafana/tempo:latest
    command: ["-config.file=/etc/tempo.yaml"]
    volumes:
      - ./tempo.yaml:/etc/tempo.yaml
    ports:
      - "3200:3200"
      - "4317:4317"
      - "4318:4318"

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"

Em produção, fixe versões específicas e use armazenamento persistente.

Configuração monolítica mínima

server:
  http_listen_port: 3200

stream_over_http_enabled: true

storage:
  trace:
    backend: local
    local:
      path: /var/tempo/blocks
    wal:
      path: /var/tempo/wal

distributor:
  receivers:
    otlp:
      protocols:
        grpc:
        http:

O backend local serve apenas para desenvolvimento. Produção deve usar S3, Google Cloud Storage, Azure Blob ou outro backend suportado.

Instrumentando Node.js

import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: 'http://otel-collector:4318/v1/traces'
  }),
  instrumentations: [getNodeAutoInstrumentations()]
});

sdk.start();

Inicialize o SDK antes de carregar frameworks e clientes de banco.

Enviando pelo Collector

receivers:
  otlp:
    protocols:
      grpc:
      http:

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 256
  batch:
    timeout: 5s

exporters:
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/tempo]

O artigo OpenTelemetry Collector no Node.js detalha filas, retry e sampling.

Resource attributes

OTEL_SERVICE_NAME=orders-api
OTEL_RESOURCE_ATTRIBUTES=service.version=2.3.0,deployment.environment.name=production

Use atributos estáveis. Evite request ID, user ID ou valores únicos como resource attributes.

Spans manuais

import { trace, SpanStatusCode } from '@opentelemetry/api';

const tracer = trace.getTracer('orders-domain');

export async function createOrder(input) {
  return tracer.startActiveSpan('order.create', async span => {
    try {
      span.setAttribute('order.items_count', input.items.length);
      const order = await service.execute(input);
      return order;
    } catch (error) {
      span.recordException(error);
      span.setStatus({ code: SpanStatusCode.ERROR });
      throw error;
    } finally {
      span.end();
    }
  });
}

Nomeie operações de forma estável. Não coloque IDs no nome do span.

Configurando data source no Grafana

No Grafana, adicione uma fonte Tempo apontando para:

http://tempo:3200

Ative links para Loki e Prometheus quando os sistemas compartilham trace IDs e exemplars.

Pesquisa por trace ID

Quando um log contém trace ID, copie o valor e abra o trace diretamente. Essa é a forma mais precisa de consulta e exige pouco trabalho de busca.

TraceQL

TraceQL permite selecionar traces por atributos e estrutura:

{ resource.service.name = "orders-api" }

Erros:

{ status = error }

Latência:

{ duration > 1s }

Combinando:

{ resource.service.name = "orders-api" && duration > 500ms }

Atributos dedicados

Tempo pode usar dedicated attribute columns para acelerar consultas frequentes. Escolha atributos de baixa ou média cardinalidade:

  • service name;
  • deployment environment;
  • HTTP route;
  • status code;
  • operation type.

Não transforme IDs únicos em colunas sem avaliar custo.

TraceQL metrics

TraceQL metrics gera séries a partir de traces, como contagem, taxa de erros e latência. Isso ajuda a explorar comportamento sem instrumentar toda métrica manualmente.

Para SLOs críticos, métricas explícitas continuam importantes. Consulte Métricas Prometheus no Node.js.

Metrics generator

O metrics-generator pode produzir:

  • span metrics;
  • service graphs;
  • métricas customizadas;
  • exemplars.

Controle cardinalidade. Atributos como URL completa ou user ID criam séries demais.

Service graphs

Service graphs mostram relações entre serviços, taxa, erros e duração. Eles dependem de propagação correta do contexto e nomes de serviço consistentes.

Exemplars

Prometheus exemplars conectam um ponto de métrica a um trace ID. No Grafana, um pico de latência pode abrir um trace representativo.

Correlação com Loki

Inclua trace ID nos logs:

const context = trace.getActiveSpan()?.spanContext();

logger.info({
  traceId: context?.traceId,
  spanId: context?.spanId
}, 'Pedido processado');

Veja Grafana Loki no Node.js.

Sampling

Armazenar todos os traces pode ser caro. Estratégias:

  • probabilístico no SDK;
  • parent-based;
  • tail sampling no Collector;
  • manter erros;
  • manter traces lentos;
  • amostra base do tráfego normal.

Sampling agressivo pode esconder problemas raros. Meça volume e custo antes de reduzir.

Object storage

Produção deve usar armazenamento durável. Configure:

  • bucket separado;
  • criptografia;
  • lifecycle;
  • credenciais mínimas;
  • replicação quando necessário;
  • alertas de capacidade.

Retenção

Defina retenção conforme investigação e custo. Traces detalhados podem ter prazo menor que métricas agregadas. Não mantenha indefinidamente dados sensíveis.

Modos de deployment

Tempo oferece modos monolítico e distribuído. Monolítico é simples para desenvolvimento e pequena escala. Distribuído separa distributor, ingester, querier, compactor e outros componentes para escalar independentemente.

Alta disponibilidade

Em produção:

  • múltiplas réplicas;
  • object storage durável;
  • replicação adequada;
  • zone awareness quando suportado;
  • limits por tenant;
  • monitoramento interno;
  • rollback de versões.

Multi-tenancy

Tempo suporta tenant IDs em arquiteturas apropriadas. O proxy de autenticação deve validar o tenant e impedir que clientes escolham livremente outra organização.

Segurança

  • Use TLS em OTLP.
  • Não exponha ingestão publicamente.
  • Autentique collectors.
  • Restrinja Grafana.
  • Remova dados pessoais.
  • Proteja object storage.
  • Audite consultas.

Monitorando Tempo

Acompanhe:

  • spans recebidos;
  • spans recusados;
  • latência de ingestão;
  • erros de object storage;
  • compactação;
  • fila de consultas;
  • cache hit;
  • memória e CPU;
  • tempo de busca.

Cardinalidade

Mesmo que Tempo seja econômico, atributos excessivos aumentam tamanho e custo de busca. Evite:

  • payload completo;
  • headers sensíveis;
  • SQL com valores;
  • URLs com IDs;
  • mensagens de erro como dimensão;
  • objetos serializados.

Teste de carga

Gere tráfego representativo e observe se o Collector ou Tempo descarta spans. Use Autocannon no Node.js ou k6 e compare volume, latência e custo.

Erros comuns

  • Enviar direto sem Collector: retry fica na aplicação.
  • Sem sampling: custo cresce rapidamente.
  • Sampling excessivo: incidentes desaparecem.
  • Trace ID fora dos logs: correlação fica manual.
  • Atributos com PII: dados sensíveis são armazenados.
  • Backend local em produção: traces são perdidos.
  • Sem métricas internas: ingestão falha silenciosamente.
  • Nomes de serviço inconsistentes: service graph fragmenta.

Conclusão

O Grafana Tempo no Node.js fornece armazenamento escalável para traces OpenTelemetry e integra consultas, service graphs, métricas e correlação com logs.

Envie OTLP por Collector, controle sampling, proteja atributos e use object storage durável. Com TraceQL e links entre Loki, Prometheus e Tempo, a equipe consegue partir de um alerta e chegar ao caminho exato da requisição que apresentou falha.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita