Pular para o conteúdo
← Voltar para o Skalablog

Artigo publicado

OpenTelemetry Grátis: Monitorar Apps TypeScript

Engenharia de Software

OpenTelemetry grátis permite monitorar aplicações TypeScript em produção sem contratar um APM caro por aplicação. Você instala o SDK, envia os dados para o OpenTelemetry Collector e visualiza métricas no Grafana usando só ferramentas open source rodando na sua própria infraestrutura.

O que é OpenTelemetry grátis e por que ele substitui um APM pago

O OpenTelemetry é um padrão aberto de instrumentação para gerar, coletar e exportar telemetria. Ele é grátis porque o projeto é mantido pela CNCF sob licença Apache 2.0 e não cobra por volume de dados nem por aplicação instrumentada. Na prática, você troca a assinatura de um APM comercial pelo custo de servidor, disco e tempo de máquina que você mesmo opera.

O padrão nasceu de uma colaboração entre fornecedores de observabilidade e cobre três sinais: logs, traces e métricas. O SDK oficial existe para TypeScript, Go, Rust, C#, Python e outras linguagens, sempre com o mesmo protocolo de transporte, o OTLP (OpenTelemetry Protocol).

Uma cotação citada pelo autor no vídeo aponta APMs a cerca de R$ 120 por mês por aplicação. Com quatro microserviços e dois bancos de dados, a conta chega perto de R$ 720 mensais, ou quase R$ 10 mil por ano. Esse número é uma estimativa do autor, não uma tabela oficial de preços.

O autor roda um cluster Kubernetes com mais de 60 aplicações e paga apenas por disco e tempo de uso de máquina. Se tivesse que pagar licença para monitorar essas dezenas de aplicações, o custo seria inviável.

A contrapartida real é operacional: alguém precisa atualizar o Collector, cuidar da retenção do Prometheus e revisar alertas de uso. O custo sai da fatura e entra na rotina de engenharia.

A stack open source que o vídeo usa: Collector, Prometheus e Grafana

A arquitetura mostrada no vídeo tem quatro peças: o SDK na aplicação, o OpenTelemetry Collector como central de recebimento, o Prometheus como banco de métricas e o Grafana para dashboards. Cada peça é open source, roda em contêiner e não cobra um centavo de licença.

O Collector aceita dados via OTLP sobre gRPC na porta 4317. gRPC é o protocolo binário mais rápido disponível para esse transporte. O Collector recebe e redistribui: a aplicação não precisa conhecer o banco final. Essa separação evita acoplar o código do serviço ao fornecedor de armazenamento, então trocar de banco depois vira só uma mudança de configuração.

O Prometheus não recebe push do Collector no modo padrão. Ele faz scrape de um endpoint de métricas a cada intervalo configurado. No exemplo do vídeo, o endpoint fica na porta 8889 e o scrape acontece a cada 2 segundos.

Para logs e traces, a stack citada inclui Grafana Loki e Grafana Tempo, além do Jaeger como alternativa de tracing. A demonstração manteve apenas métricas com o Prometheus.

Como instrumentar TypeScript e Fastify sem tocar na regra de negócio

A instrumentação de uma API TypeScript com Fastify cabe em um arquivo de cerca de 50 linhas, importado antes de qualquer outro módulo. Você instala o pacote de auto-instrumentação do Node.js, o plugin do Fastify e inicializa tudo no início do processo.

A ordem do import é o detalhe que quebra a coleta quando ignorada. Se o arquivo de telemetria entrar depois do servidor HTTP, os módulos já foram carregados e a auto-instrumentação perde os ganchos de rede. O autor não precisou mexer em nenhuma linha da regra de negócio do projeto: só importou o arquivo de telemetria no main.

Os pacotes usados no vídeo são @opentelemetry/sdk-node e @opentelemetry/auto-instrumentations-node. Ambos são publicados pelo projeto OpenTelemetry no npm.

O fluxo de inicialização tem três passos previsíveis:

  1. Importar o arquivo de telemetria no topo do main, antes de qualquer outro import.
  2. Inicializar o sdk-node passando a URL do Collector por variável de ambiente e definindo o intervalo de envio de métricas.
  3. Registrar as auto-instrumentações do Node.js e do Fastify, e chamar beforeExit para dar flush nas métricas pendentes quando a aplicação for encerrada.

O beforeExit resolve um problema silencioso: o SDK acumula métricas em memória e envia de tempos em tempos, não a cada requisição. Se o processo cair sem esse gancho, as últimas métricas se perdem. O autor configura esse envio em intervalos de 30 ou 60 segundos, e o ajusta conforme a necessidade de granularidade.

O export do arquivo de telemetria fica vazio de propósito. A única coisa obrigatória é chamar esse arquivo antes de todos os outros.

O que a auto-instrumentação já entrega sem você escrever código

Ligar as auto-instrumentações do Node.js já entrega um conjunto de métricas do próprio runtime, sem nenhuma configuração extra:

  • event loop do Node.js e sua latência;
  • tempo de inicialização do processo;
  • métricas do V8;
  • atividade do garbage collector do JavaScript;
  • chamadas HTTP internas, com rota, esquema (http ou https) e status code;
  • latência das requisições, no bucket http_server_duration_minutes_bucket.

Essas métricas aparecem no Grafana assim que a aplicação começa a enviar dados. O autor usou o bucket de duração das requisições como base do dashboard de latência.

Se a aplicação usa Knex, Prisma ou o driver do Postgres, existe instrumentação específica para cada uma dessas bibliotecas. Você instala o pacote correspondente e a biblioteca faz o resto. O exemplo do vídeo não chegou nesse nível porque a demonstração queria mostrar só o que vitnha por padrão.

Métricas, logs e traces: qual banco recebe cada sinal

Cada sinal de telemetria tem um destino diferente, e misturar os três no mesmo banco costuma encarecer a operação. Métrica é dado agregado e numérico, trace é a árvore de chamadas de uma requisição e log é o evento textual emitido pelo código.

A métrica responde perguntas de tendência: quantas requisições chegaram, qual a média de erro por endpoint, qual o tempo médio de resposta. O trace responde onde o tempo foi gasto, ligando a chamada HTTP à query do banco e ao microsserviço acionado. O log guarda o contexto do caso isolado, útil quando um erro 500 precisa ser reproduzido.

Um número mostra bem a diferença entre os três. No experimento do vídeo, uma mesma métrica agregada apareceu registrada 563 vezes com o valor idêntico: eram requisições ao mesmo endpoint retornando 200. O dado individual não interessa ali, o que interessa é o volume.

A recomendação prática é enviar tudo ao Collector e deixar que ele roteie para Prometheus, Loki ou Tempo conforme o tipo. Você poderia configurar a aplicação para enviar direto ao Grafana, sem passar pelo Collector, mas aí cada serviço precisa conhecer o endereço de cada banco.

Como configurar o Collector e o Grafana na prática

A infraestrutura inteira cabe em um docker-compose.yml somado a uma pasta de configuração. O autor adicionou os serviços de monitoramento ao compose que o projeto já tinha, sem alterar o restante.

O desenho do Collector tem dois lados:

  • receivers, que definem por onde os dados entram (OTLP na porta 4317, via gRPC);
  • exporters, que definem para onde saem (o endpoint que o Prometheus vai raspar).

No Grafana, a configuração praticamente se resume a três passos:

  1. Cadastrar o Prometheus como Data Source.
  2. Importar o dashboard pronto, seja por Download JSON do repositório ou colando o ID do dashboard direto na interface.
  3. Conferir se o UID do Data Source no JSON bate com o UID configurado no Grafana.

Esse último ponto é uma armadilha real. O dashboard baixado trazia o UID Grafana Prom, enquanto a instância local usava Prometheus, e os dados simplesmente não apareciam. O painel fica vazio sem indicar erro de configuração.

Na demonstração, o Grafana subiu na porta 3000 sem autenticação, o que é aceitável em ambiente local. Em produção, o autor recomenda habilitar login e os demais controles de acesso.

O experimento com a Rinha de Backend

Para provar que a stack funciona sob carga real, o autor instrumentou uma das aplicações vencedoras da Rinha de Backend, campeonato online de performance organizado por Francisco Zanfranceschi com a comunidade. O desafio do primeiro trimestre de 2024 era criar uma API que simula transações de crédito e débito numa conta bancária, sob teste de carga com centenas de usuários conectados por segundo, e garantir que o saldo final nunca ficasse inválido ou negativo.

O projeto escolhido foi o de Emerson Costa Alves, disponível no GitHub. A implementação ficou entre as cinco melhores dos quase 700 participantes, competindo com linguagens como Go, Rust e C#. O autor rodou o teste de carga do próprio campeonato contra a API instrumentada e acompanhou os números mudando no dashboard a cada 5 segundos.

Como o código estava em JavaScript, adaptar o projeto existente foi o caminho mais direto para testar a stack sem escrever uma aplicação do zero. Todo o código-fonte do experimento está publicado no GitHub do autor.

Comparação: OpenTelemetry com stack própria contra APM comercial

A escolha não é entre ter e não ter observabilidade, mas entre operar a stack ou terceirizá-la. A tabela abaixo resume as diferenças que aparecem com mais frequência em decisões de time pequeno.

CritérioOpenTelemetry com stack própriaAPM comercial
Custo diretoServidor, disco e tempo de máquinaAssinatura por aplicação e por volume
Quem operaSeu time de engenhariaFornecedor
Padrão de dadosOTLP, abertoProprietário, com exportador OTLP em parte dos casos
Migração futuraVocê troca o destino sem reinstrumentarDepende do fornecedor
Esforço inicialSetup do Collector e dos bancosConfiguração de agente e chaves
Escala econômicaO custo cresce com a infraestruturaO custo cresce com o número de aplicações

O ponto decisivo costuma ser volume. Quanto mais aplicações, mais a assinatura pesa e mais a stack própria compensa em custo absoluto. Uma operação com 60 serviços pagando R$ 120 cada um chegaria a R$ 7.200 por mês em licença, o que muda a conversa rapidamente.

Em compensação, a stack própria exige decisões que o fornecedor tomava por você: tempo de retenção, política de amostragem de traces e a criação dos próprios alertas.

Onde o OpenTelemetry grátis cobra o preço em operação

OpenTelemetry grátis não significa custo zero: significa custo previsível de infraestrutura no lugar de licença por uso. O trabalho que sobra é operacional e recai sobre quem mantém o cluster.

A lista de manutenção inclui:

  • manter o Collector atualizado, porque cada versão nova muda configurações de receivers e exporters;
  • ajustar retenção do Prometheus, que cresce em disco conforme o número de séries;
  • revisar alertas de uso, para não ser avisado depois que o disco encheu;
  • manter Loki e Tempo, caso você adote logs e traces além das métricas;
  • entender PromQL, a linguagem de consulta do Prometheus, se quiser montar dashboards próprios.

O teste de carga do vídeo foi reduzido de propósito para não consumir dados demais durante a gravação. Vale lembrar que medir custa recurso: quanto menor o intervalo de envio de métricas, mais dados trafegam e mais a instrumentação compete com a aplicação.

Erros comuns ao montar essa stack

Os tropeços que o autor encontrou ou antecipou têm quase sempre a mesma origem: configuração, não instrumentação.

  • Importar o arquivo de telemetria depois do servidor HTTP, o que desliga a auto-instrumentação.
  • Esquecer o beforeExit, perdendo as métricas do último ciclo.
  • UID do Data Source diferente entre JSON do dashboard e Grafana, deixando o painel vazio.
  • Enviar métricas em intervalo curto demais em produção, competindo com o tráfego real.
  • Esperar que o Collector faça push para o Prometheus, quando é o Prometheus que faz scrape.

Nenhum desses problemas exige mudar o SDK ou reinventar a instrumentação. Todos se resolvem em arquivos de configuração.

Perguntas frequentes sobre OpenTelemetry grátis

  • OpenTelemetry é realmente gratuito para uso comercial? Sim. O projeto é mantido pela CNCF sob licença Apache 2.0 e não cobra por volume de dados nem por aplicação instrumentada. O que você paga é a infraestrutura onde o Collector e os bancos de dados rodam, seja ela própria ou contratada.
  • Preciso instrumentar cada endpoint da minha API TypeScript manualmente? Não. O pacote @opentelemetry/auto-instrumentations-node já cobre HTTP, Fastify e eventos internos do runtime. Instrumentação manual só é necessária para métricas de negócio específicas, como número de saques ou saldo médio.
  • Por que o dashboard do Grafana aparece sem dados? O motivo mais comum é o UID do Data Source. O JSON do dashboard aponta para um UID, e a instância do Grafana precisa ter exatamente o mesmo UID cadastrado. Também vale conferir se o Prometheus está conseguindo raspar o endpoint do Collector.
  • Qual a diferença entre métrica, log e trace nessa stack? Métrica é dado agregado e numérico, ideal para tendência e alerta. Trace é a árvore de chamadas de uma requisição, útil para achar onde o tempo foi gasto. Log é o evento textual, útil para reproduzir um caso isolado. Cada um tem um banco especializado: Prometheus, Tempo e Loki, respectivamente.
  • Posso usar essa stack sem Kubernetes? Sim. A demonstração do vídeo roda inteira em Docker Compose, sem cluster. Kubernetes só ajuda quando você quer algo como o Prometheus Stack, que já traz dashboards e alertas prontos.
  • Qual porta o Collector usa para receber telemetria? A 4317, com OTLP sobre gRPC. É o protocolo binário que o OpenTelemetry usa para transportar os dados do SDK até o Collector.
  • O que acontece se eu criar métricas customizadas? Você pode. O SDK permite calcular indicadores de negócio, como saldo no momento, número de depósitos e número de saques. O vídeo não faz isso para manter o exemplo enxuto, mas o caminho é o mesmo da instrumentação automática.
  • Quanto tempo as métricas ficam armazenadas? Depende da sua configuração de retenção no Prometheus. É uma decisão sua, e é justamente uma das tarefas que a assinatura de um APM comercial resolveria por você.
  • Preciso saber PromQL para usar os dashboards prontos? Não. O dashboard importado já traz os painéis prontos. PromQL é a linguagem de consulta do Prometheus e só entra em cena quando você quer criar painéis próprios ou explorar dados específicos.

Onde aprender mais sobre OpenTelemetry e TypeScript

Se você quer se aprofundar em instrumentação de aplicações JavaScript, vale acompanhar conteúdos como os do canal Gustavo Dev Doido, que cobre performance e monitoramento de aplicações Node.js no dia a dia. Para quem prefere um caminho estruturado, o Crazystack Typescript é uma formação focada em projetos TypeScript completos, e o Bootcamp do Dev Doido trabalha projetos reais com foco em prática. Há também material gratuito em https://crazystack.com.br para quem quer começar sem compromisso.

A ideia central deste artigo é simples: monitorar bem depende mais de padrão aberto e disciplina operacional do que de orçamento de licença.

Se você tem esse tipo de experiência gravada em vídeo, o Skala Blog converte a gravação em texto publicado. Você cola a URL do YouTube, a transcrição é gerada e o texto vira artigo estruturado, com seções, tabelas e perguntas frequentes. O conhecimento que já está no vídeo passa a ser encontrável por busca.

Acesse Skala Blog


Source video