Formação AWS

← Todos os artigos

X-Ray com Docker: tracing de uma aplicação Node em 4 passos

ContainersPor Henrylle Maia · 15 out 2026 · 7 min de leitura

Sua aplicação está com a CPU perto de 90% e os logs não dizem qual rota custa mais caro. Com o AWS X-Ray você manda para a AWS cada requisição, com rota, método, status e tempo de resposta, e enxerga isso agrupado no console. Aqui rodo o daemon do X-Ray em container ao lado de uma aplicação Node com React e mostro o resultado no Service Map.

Por que log não basta e o trace resolve

Imagine uma aplicação web em dois servidores, de repente com 90% de uso de CPU. O primeiro nível de investigação é a máquina. O segundo é o log, no CloudWatch: você vê as requisições e o tempo de cada uma, 630 ms, 940 ms, 230 ms.

Só que, no volume de um log de produção, fica difícil dizer onde agir. Quais requisições custam mais? Qual rota recebe mais chamadas? Qual o tempo médio? Atendendo um cliente com a frota quase sempre em 100% de CPU, foi exatamente aí que o log deixou de bastar.

O trace é o nível seguinte. A aplicação se integra a um serviço que coleta as métricas e as compila. Na AWS esse serviço é o X-Ray. Numa rota como GET /api/tarefas, você passa a ver quantas requisições chegam, o tempo médio e o status de resposta.

O SDK envia os dados ao daemon, que roda em outro container e repassa tudo ao X-RayAplicação NodeSDK do X-Ray no ExpressDaemon em containerporta 2000 TCP e UDPAWS X-Rayrecebe os segmentosConsole do X-RayService Map e lista de traces
O SDK envia os dados ao daemon, que roda em outro container e repassa tudo ao X-Ray

Por que usar Docker nesta prova de conceito

O X-Ray trabalha junto da aplicação por meio de um processo chamado daemon. A aplicação manda os dados para ele, e ele repassa ao X-Ray. Com Docker, essa peça roda igual em Windows, Linux ou Mac, e o ambiente fica simples de subir.

Usei a BIA, uma aplicação Node com React que já roda com Docker, com Dockerfile e docker-compose.yml. Clonei o projeto, entrei na pasta e criei uma branch chamada xray:

bash
git checkout -b xray

1Criar o Dockerfile do daemon

Criei o arquivo Dockerfile_xray_daemon. A estrutura vem da própria documentação da AWS: instala o unzip, baixa o daemon, extrai, copia o executável e expõe a porta 2000, em TCP e UDP.

dockerfile
FROM amazonlinux
RUN yum install -y unzip
RUN curl -o daemon.zip <URL do daemon na documentação da AWS>
RUN unzip daemon.zip && cp xray /usr/bin/xray
ENTRYPOINT ["/usr/bin/xray", "-t", "0.0.0.0:2000", "-b", "0.0.0.0:2000"]
EXPOSE 2000/udp
EXPOSE 2000/tcp

A URL de download eu copiei da documentação e não reproduzo aqui, porque a versão do daemon muda. Pegue a atual na página do daemon.

Serviço xray_daemon no docker-compose: build do Dockerfile_xray_daemon, container xray, AWS_REGION us-east-1, command --local-mode, portas 2000 e volume ~/.aws
Serviço xray_daemon no docker-compose: build do Dockerfile_xray_daemon, container xray, AWS_REGION us-east-1, command --local-mode, portas 2000 e volume ~/.aws

2Subir o daemon junto da aplicação no Compose

No docker-compose.yml já havia os serviços server e database. Criei um serviço novo, xray_daemon, para subir junto:

  • build: o Dockerfile_xray_daemon, com o diretório atual como contexto;
  • container_name: xray;
  • environment: AWS_REGION com us-east-1, a região para onde vão os dados;
  • command: --local-mode, porque na documentação da AWS esse modo faz o daemon não checar se está numa máquina EC2, e aqui estou rodando local;
  • ports: a 2000, em TCP e UDP;
  • volumes: a pasta de credenciais da AWS da minha máquina, para o daemon saber para qual conta enviar.

No volume, usei o profile padrão do aws configure, de um usuário com permissão de administrador. Para o X-Ray, o mínimo é a permissão de administração do X-Ray, e usei a de administrador geral só no teste.

No serviço server, fiz três ajustes para ele enxergar o daemon:

  • depends_on apontando para o xray_daemon, para o daemon subir antes;
  • links com o xray_daemon, para a aplicação resolver o endereço dele;
  • a variável AWS_XRAY_DAEMON_ADDRESS com xray_daemon:2000, junto de AWS_REGION com us-east-1.

Depois deixei tudo commitado na branch xray.

3Integrar o SDK do X-Ray ao Express

A aplicação precisa do SDK do X-Ray; há um para JavaScript, e também para .NET, Java e outras linguagens. Para Node:

bash
npm install --save aws-xray-sdk

No express.js, importei o SDK e abri um segmento no início da configuração, dando o nome bia. No fim, depois de registrar as rotas, fechei o segmento. O X-Ray coleta o que acontece nesse intervalo.

javascript
var AWSXray = require("aws-xray-sdk");

app.use(AWSXray.express.openSegment("bia"));
// ...rotas da aplicação...
app.use(AWSXray.express.closeSegment());

É uma integração simples, só para ver o funcionamento.

express.js importando aws-xray-sdk na linha 6 e abrindo o segmento com AWSXray.express.openSegment("bia") na linha 11
express.js importando aws-xray-sdk na linha 6 e abrindo o segmento com AWSXray.express.openSegment("bia") na linha 11

4Gerar a imagem, subir e ver o resultado

Como mudei a aplicação, gerei uma nova imagem do server (antes parei tudo com docker compose down):

bash
docker compose down
docker compose build server
docker compose up -d
docker logs -f xray

No log do container xray, a confirmação de que deu certo é a mensagem de envio de um batch de segmentos para o X-Ray. Depois abri a aplicação em localhost:3001 e cadastrei, alterei e apaguei algumas tarefas para gerar requisições.

No console, em CloudWatch, X-Ray traces, Service map, o mapa apareceu: 2 traces por minuto, 100% das requisições OK e latência média de 8 ms.

Service Map do X-Ray com o serviço bia: Ok 100%, 2.00 t/min, latência média de 8 ms e 0.00 falhas por minuto
Service Map do X-Ray com o serviço bia: Ok 100%, 2.00 t/min, latência média de 8 ms e 0.00 falhas por minuto

Em Traces estão as requisições, com as rotas que chegaram. Dá para refinar por URL e ver o percentual de cada rota, o tempo de resposta e o método de cada uma. Na AWS, também dá para agrupar por instância. Foram 10 traces nesse teste.

Lista de 10 traces com duração de 0,003 s a 0,029 s, método HTTP e URL de cada requisição à API de tarefas
Lista de 10 traces com duração de 0,003 s a 0,029 s, método HTTP e URL de cada requisição à API de tarefas

Com isso, a decisão sobre onde atuar passa a vir de dado agrupado, e não de uma pilha de linhas de log.

O que esta prova de conceito ainda não mostra

O mapa mostra só a camada web. A BIA conversa com um banco, e essa camada não foi integrada aqui. Com ela no Service Map, você identifica se o gargalo está no banco. Fica como evolução do projeto.

Checklist

  • [ ] Entendi a diferença entre olhar a máquina, olhar o log e olhar o trace.
  • [ ] Criei o Dockerfile do daemon do X-Ray, expondo a porta 2000 em TCP e UDP.
  • [ ] Adicionei o serviço do daemon no Compose, com --local-mode e a região.
  • [ ] Configurei depends_on, links e AWS_XRAY_DAEMON_ADDRESS no serviço da aplicação.
  • [ ] Instalei o SDK e abri e fechei o segmento no Express.
  • [ ] Refiz a imagem, subi o Compose e vi o Service Map e a lista de traces.
  • [ ] Conferi o aviso de manutenção e o caminho de migração para OpenTelemetry na documentação.

O que os alunos dizem

  • “Comecei a estudar Cloud em 2023 e entrei na Imersão AWS para aprofundar minha prática.”

    Luiz Claudio, Arquiteto de Soluções

    Ver depoimento
  • “Hoje recebo oportunidades 100% remoto e finalmente me sinto recolocada no mercado.”

    Patrícia Prado, Desenvolvedora Back-end

    Ver depoimento
  • “A Formação AWS me mostrou o caminho, me deu prática de verdade e mudou minha vida.”

    Rodrigo Raspinola, Analista Cloud / SRE

    Ver depoimento

Formação AWS

Aprenda AWS e IA na prática, com projeto real e acompanhamento. Converse com o time sobre a Formação AWS.

Agende uma conversa

Prefere assistir?

A aula completa (30 min) está no canal Domine AWS. O vídeo toca aqui mesmo.

Leia também

Compartilhe este post