Sua aplicação é uma caixa preta? Está na hora de mudar isso
\n\nVocê já se pegou pensando: "Por que meu serviço em Node.js está lento, mesmo com o código perfeito?" Ou recebeu uma reclamação de um usuário, mas não conseguiu entender o que deu errado? Familiar? Bem-vindo ao mundo onde, sem observabilidade em JavaScript, você trabalha no escuro.
\n\nObservabilidade não é apenas uma palavra da moda. É uma abordagem que transforma seu código de uma caixa preta em um sistema transparente. Vamos aprender a fazer perguntas a ele: "Quem é o culpado?" (rastreamento), "O que está acontecendo agora?" (métricas) e "O que aconteceu ontem às 3:15?" (logs).
\n\nNeste artigo, vamos explorar os três pilares da observabilidade em Node.js: rastreamento, métricas e logs. Você receberá exemplos de código prontos e entenderá como implementar essas práticas ainda hoje. Vamos lá!
\n\nRastreamento em JavaScript: a jornada da requisição
\n\nImagine que um usuário clica no botão "Finalizar Pedido". Essa requisição passa pelo API Gateway, serviço de autenticação, carrinho, gateway de pagamento e banco de dados. Se algo quebrar, onde procurar? O rastreamento (ou distributed tracing) fornece um mapa dessa jornada.
\n\nO que é rastreamento em termos simples
\n\nRastreamento é uma forma de acompanhar o caminho de uma requisição específica através de todos os microsserviços e funções. Cada etapa é um span, e toda a cadeia é um trace. Você vê quanto tempo cada etapa levou e onde ocorreu o erro.
\n\nOpenTelemetry: o padrão para observabilidade em JavaScript
\n\nOpenTelemetry (OTel) é o padrão da indústria para coletar traces, métricas e logs. Ele é suportado por todas as principais nuvens e ferramentas (Jaeger, Zipkin, Grafana).
\n\nInstalação:
\nnpm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node\n\nExemplo básico de rastreamento para uma aplicação Express:
\nconst { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');\nconst { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');\nconst { ConsoleSpanExporter } = require('@opentelemetry/exporter-console');\nconst { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');\nconst { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');\n\nconst provider = new NodeTracerProvider();\nprovider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));\nprovider.register();\n\nconst { getTracer } = require('@opentelemetry/api');\nconst tracer = getTracer('my-app');\n\n// Rastreamento automático de HTTP e Express\nconst { registerInstrumentations } = require('@opentelemetry/instrumentation');\nregisterInstrumentations({\n tracerProvider: provider,\n instrumentations: [\n new ExpressInstrumentation(),\n new HttpInstrumentation()\n ]\n});\n\n// Agora cada requisição criará um trace com spans\nconst express = require('express');\nconst app = express();\n\napp.get('/api/order', async (req, res) => {\n // Span manual para lógica de negócio\n const span = tracer.startSpan('processPayment');\n try {\n // ... sua lógica\n await new Promise(r => setTimeout(r, 100)); // simulação\n span.setStatus({ code: 1 }); // OK\n } catch (err) {\n span.setStatus({ code: 2, message: err.message }); // ERROR\n throw err;\n } finally {\n span.end();\n }\n res.send('Order created');\n});\n\napp.listen(3000);\n\nAgora, no console, você verá dados estruturados: qual requisição, quanto tempo cada middleware levou, onde ocorreu o erro. Isso é observabilidade javascript em ação.
\n\nMétricas: o pulso da sua aplicação
\n\nO rastreamento é bom para requisições individuais, mas e o panorama geral? Quantas requisições por segundo? Qual a latência? Quanta memória seu Node.js está consumindo? As métricas cuidam disso.
\n\nPrometheus e cliente para Node.js
\n\nPrometheus é o padrão de facto para coleta de métricas. Ele "puxa" dados da sua aplicação via HTTP.