Olá! Bem-vindos ao curso de observabilidade na prática, do Zero ao Kubernetes com SLOs. Meu nome é Eric, e tenho mais de 18 anos de experiência na área, atuando como especialista em qualidade, SRE e observabilidade. Hoje, serei o instrutor nesta jornada de observabilidade.
Audiodescrição: Eric é um homem branco, com cabelo curto castanho e olhos castanhos. Ele veste uma camisa azul e está em um ambiente de escritório com uma parede clara ao fundo.
Neste curso, aprenderemos a instrumentar uma aplicação do zero, utilizando métricas e dashboards. Vamos migrar tudo isso para o Kubernetes, criando uma arquitetura em cloud com CICD automatizado e deploy automatizado. Além disso, dominaremos o SLA e o SLO em um cenário real.
O cenário que utilizaremos é o da empresa fictícia Fast Food Tech. Você acabou de ingressar na Fast Food Tech, no time de plataforma, e já enfrenta um desafio: o CEO está recebendo reclamações de que o aplicativo está lento, mas não temos dados para quantificar essa lentidão ou sua frequência. Nossa API é uma caixa preta, e nossa missão é transformá-la em um sistema observável. Vamos sair do escuro e tomar decisões baseadas em métricas e dados.
Antes de começarmos a prática, precisamos entender alguns conceitos fundamentais: logs, métricas e traces. Logs são como um diário de bordo detalhado, útil para identificar erros específicos. Eles registram tudo o que acontece na aplicação, sejam erros ou ações. No entanto, logs não são úteis para identificar tendências ou criar gráficos.
Para isso, utilizamos métricas, que funcionam como o painel de um carro, mostrando tendências numéricas e a saúde da aplicação. Focaremos bastante em métricas, pois elas são leves, baratas para armazenar e perfeitas para responder se o sistema está saudável.
Traces são o rastreamento de uma transação na aplicação, permitindo rastrear o caminho entre microserviços e o que acontece com uma determinada transação ou chamada.
Começaremos com métricas, pois elas respondem às nossas necessidades iniciais e são leves e baratas para armazenar. Agora, vamos colocar a mão na massa. No repositório da Fast Food Tech, há um README que explica como a aplicação foi construída, quais linguagens e tecnologias foram usadas. Inicialmente, trabalharemos localmente.
A API simples de pedidos do sistema Fast Food Tech foi construída em Node.js com Express e MySQL, rodando 100% localmente via Docker Compose. É importante conhecer a estrutura de pastas para saber onde está cada coisa. Vamos clonar o projeto e começar a trabalhar.
Para isso, precisamos ter o Docker instalado. Uma alternativa ao Docker Desktop é o Rancher, uma ferramenta open source e gratuita. Ao rodar o comando docker --version, verificamos se o Docker está instalado.
docker --version
Voltando à aplicação, há endereços onde ela estará disponível para facilitar os testes. Vamos clonar o projeto, abrir a IDE de preferência e explorar a estrutura de pastas, como SRC, Controllers, e arquivos de configuração do Express.
git clone https://github.com/eamaral/fastfood-observability.git
Para subir a aplicação, utilizamos o Docker. O arquivo Dockerfile contém as etapas de execução, e o Docker Compose se comunica com ele. Detalhes como banco de dados, portas e API estão configurados lá.
Com o Docker instalado, rodamos o comando docker-compose up -d para colocar a aplicação no ar. Podemos usar o modo detached para continuar usando o terminal. Após subir a aplicação, verificamos nos endereços do README se ela está no ar.
docker-compose up -d
Acessamos o Swagger, uma documentação interativa que permite fazer requisições para as APIs sem usar o terminal ou ferramentas como Postman. Testamos a aplicação criando produtos, clientes e pedidos.
Ainda estamos no escuro, sem métricas para entender a aplicação, mas agora começaremos a instrumentá-la. Antes disso, precisamos garantir que o Node está instalado. No Mac, usamos brew install npm para instalar. Verificamos a instalação com node -v.
Vamos instalar a biblioteca prom-client, que é o Prometheus. O Prometheus é um coletor que nos ajudará a coletar métricas. A página oficial das bibliotecas do Node mostra o que a biblioteca faz e como instalá-la.
Para instalar, utilizamos o comando npm install prom-client. Após a instalação, podemos verificar a presença da dependência no arquivo package.json. Em seguida, vamos criar um novo arquivo na pasta "src" para começar a codificar nossas métricas utilizando o prom-client.
Primeiro, importamos o prom-client com const client = require('prom-client').
const client = require('prom-client');
Vamos começar coletando métricas padrão, como uso de CPU e memória, utilizando a função collectDefaultMetrics. Declaramos const collectDefaultMetrics = client.collectDefaultMetrics para coletar essas métricas do sistema.
const collectDefaultMetrics = client.collectDefaultMetrics;
collectDefaultMetrics();
Precisamos também contar os pedidos. Para isso, criamos uma constante const ordersTotal = new client.Counter com o nome fastfoodorders_total e um rótulo para o status do pedido. Isso nos permitirá filtrar as métricas posteriormente.
const ordersTotal = new client.Counter({
name: 'orders_total',
help: 'Total de pedidos',
labelNames: ['status']
});
Outra métrica importante é o tempo de resposta da aplicação. Criamos um histograma para isso com const requestDuration = new client.Histogram, que nos ajudará a medir a performance da aplicação.
const httpRequestDuration = new client.Histogram({
name: 'fastfood_http_request_duration_seconds',
help: 'Tempo de duração das requisições HTTP',
buckets: [0.1, 0.5, 1, 2, 5]
});
Agora, vamos integrar essas métricas ao nosso servidor. No arquivo de servidor, importamos o register do prom-client e declaramos uma nova rota para expor as métricas. A rota /metrics será responsável por retornar as métricas coletadas.
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
Para contar os pedidos, precisamos incrementar o contador ordersTotal após a criação de um pedido. Isso é feito com ordersTotal.inc({ status: 'CRIADO' }).
try {
// ... (existing code)
ordersTotal.inc({ status: 'CRIADO' });
return res.status(201).json(pedidoCompleto);
} catch (error) {
ordersTotal.inc({ status: 'ERRO' });
return res.status(400).json({ error: error.message });
}
Por fim, discutimos a importância de evitar o uso de dados infinitos, como IDs, como rótulos nas métricas, pois isso pode causar uma explosão de cardinalidade e comprometer o desempenho do Prometheus.
Essa foi a nossa primeira aula. Nos encontramos na próxima aula. Até mais!
Na nossa última aula, criamos a rota matrix, mas ainda não a acessamos. Precisamos fazer isso para verificar se o que implementamos está funcionando corretamente. Essa será a primeira ação que realizaremos agora.
Lembram-se da rota que criamos? Vamos prosseguir. Para que nossas alterações tenham efeito, precisamos executar o comando docker compose down e, em seguida, subir novamente o ambiente.
docker compose down
No entanto, não basta apenas subir novamente; é necessário executar docker compose up e reconstruir tudo. Vamos fazer isso e verificar o resultado.
docker compose up --build
O Swagger está disponível, o que indica que a aplicação subiu em algum lugar. Vamos verificar juntos. A aplicação está no ar, e vamos acessar a rota matrix. Temos aqui uma série de dados que mostram que o que fizemos funcionou. As métricas estão aparecendo de forma estática, ou seja, são exibidas ao vivo, mas permanecem nesse endereço. Precisamos de um sistema que colete essas informações periodicamente. É aí que entra o Prometheus.
Outro ponto a observar é que há uma grande quantidade de texto, o que dificulta a extração de informações visuais. Nossa aplicação está expondo os dados, mas precisamos de uma ferramenta, como o Prometheus, para coletá-los periodicamente.
Vamos voltar ao código. Agora é o momento de pegar essas métricas, que estão sendo expostas de forma passiva, e fazer com que o Prometheus, de forma ativa, as colete. Isso é o que chamamos de pull e push, semelhante ao conceito do GitHub. O Prometheus segue o mesmo princípio.
No código, tudo está rodando. Precisamos criar o Prometheus para realizar essa tarefa. O que faremos primeiro? Vamos criar uma pasta chamada "Prometheus". Dentro dela, criaremos o arquivo prometheus.yaml.
Dentro desse arquivo, configuraremos o Prometheus. Na configuração global, a sugestão inicial é de 15 em 15 segundos, mas queremos que seja de 5 em 5 segundos.
global:
scrape_interval: 15s
Vamos ajustar o intervalo de coleta para 5 segundos.
scrape_interval: 5s
Definiremos o scrap e o local onde ele será feito. Precisamos ajustar o endereço também. O MatrixPath está definido, então ele buscará em Matrix StaticConfig. O target não será o padrão; faremos a alteração necessária.
scrape_configs:
- job_name: 'fastfood-observability'
static_configs:
- targets: ['localhost:3000']
Essa é a primeira configuração do nosso Prometheus, mas ainda não está completa. Precisamos também informar ao Docker Compose o que deve ser feito. Já temos uma sugestão de configuração que precisa ser incluída.
Vamos criar o Prometheus. Ele já está sugerindo algumas configurações. Vamos verificar se estão corretas: FastFood, Observability, Prometheus. A porta que vamos utilizar é a 9090. No entanto, vou trocar essa informação, pois não gosto de subir nessa porta. Às vezes, ela já está em uso. Vou utilizar outra porta que normalmente está livre e garanto que funcionará. A 9090 também é uma opção, se preferirem, não há problema. É uma escolha pessoal.
prometheus:
image: prom/prometheus:latest
container_name: fastfood-observability-prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
restart: unless-stopped
Vamos alterar a porta para evitar conflitos.
ports:
- "9099:9090"
O volume deve ser exatamente como está escrito aqui. Há mais uma coisa que não está presente, que precisamos adicionar: o command. Ele sugeriu o config, mas não utilizo isso. Vamos usar aspas simples aqui também. Este é o command.
command: ['--config.file=/etc/prometheus/prometheus.yml']
Precisamos adicionar o depends_on também, que é o depends_on API.
depends_on:
- api
Pronto, agora a configuração do nosso Prometheus está pronta dentro do nosso arquivo YAML do Docker Compose.
O que precisamos fazer novamente? A mesma coisa: se dermos um "Ctrl+C" aqui, ele interrompe os containers. Para mim também, mas é sempre bom executar um docker-compose down e um docker-compose up novamente. Vou fazer isso. Vamos lá, docker-compose up novamente. Ele vai iniciar novamente e então acessaremos o Prometheus na porta que configuramos.
docker-compose down
docker-compose up --build
Está no ar. Ele está indicando que a métrica também está ativa. Vamos acessar o Prometheus. Vamos acessar o localhost na porta 9099. Funcionou! Nosso Prometheus está no ar. O que podemos fazer aqui dentro? Que expressões podemos colocar? Uma das expressões que temos no nosso código está no arquivo metrics que criamos com esses nomes. Isso pode ser passado como expressão.
Por exemplo, ao digitar fastfood, ele já aparece, nem preciso digitar tudo. Ele já traz a métrica que criei. Vamos executar para ver o que acontece. Ele trouxe algo, mas ainda não há dados, pois não me lembro de ter criado nenhum pedido para ele contar. Mas o importante é que está funcionando, mesmo que ainda não seja o que queremos.
fastfood_orders_total
Por exemplo, se colocarmos app, conseguimos ver que a aplicação está no ar. Isso retorna um gráfico que mostra que está no ar. Podemos adicionar um track e outras coisas. Está configurado para uma hora, mas podemos ajustar para um minuto atrás. Ele indicará que está no ar, pois acabamos de subir.
up
Temos um gráfico, o Prometheus está ativo. Se fizermos um pedido no OrdersTotal, ele começará a aparecer na expressão do FastFoodOrdersTotal. Conseguiremos ver no gráfico. Precisamos aprender a debugar e veremos um handbook para isso na próxima aula. Primeira coisa, já conseguimos. Depois, veremos como debugar e criar um handbook.
Antes de continuarmos com a criação de gráficos, é importante saber como depurar quando um erro ocorre. Quais são as primeiras ações que devemos tomar? Qual a ordem que podemos seguir para resolver um problema?
Se o gráfico estiver vazio e não conseguirmos visualizar nada, devemos seguir um roteiro. Primeiramente, é necessário testar se a API está respondendo. Podemos testar a própria rota metrics, além de outra rota que será apresentada. Um erro comum que pode ocorrer está relacionado ao horário do servidor.
Para verificar se a API está ativa, podemos usar o seguinte comando:
# 1. A API está viva?
curl http://localhost:3000/metrics
Vamos examinar o código e acessar a primeira rota. Temos uma rota health e o nosso swagger. O primeiro passo é iniciar a depuração por lá. Vamos acessar a documentação da API para verificar se ela está ativa. A API está no ar e respondeu com o código 200.
Podemos verificar a saúde da API com o seguinte comando:
curl -X 'GET' \
'http://localhost:3000/health' \
-H 'accept: */*'
O segundo passo, caso as métricas não estejam aparecendo, é acessar o endereço correspondente para verificar se o que foi feito até o momento está funcionando corretamente. Além disso, existe outro caminho que podemos verificar, que é o targets. O que o targets faz? Ele nos permite saber se o Prometheus consegue acessar a API. No exemplo apresentado, o Prometheus não está conseguindo encontrar a API.
Para verificar se o target está ativo, podemos acessar:
# Verifique em: http://localhost:9090/targets
Por que não está encontrando? Primeiro, porque não é essa porta. Lembramos que definimos 9099. O Prometheus, como mencionado anteriormente, é um coletor. Ele acessa a rota metrics e coleta dados a cada 5 segundos. Definimos isso em nosso código. A cada 5 segundos, ele realiza o scrap, que é o intervalo para coletar as métricas nesse caminho. Assim, sabemos que ele está conseguindo acessar e coletar os dados corretamente. Esse é o tipo de detalhe que devemos observar.
Aqui está a configuração do Prometheus para coletar as métricas:
global:
scrape_interval: 5s
scrape_configs:
- job_name: 'fastfood-observability'
metrics_path: '/metrics'
static_configs:
- targets: ['api:3000']
Em relação ao horário no servidor, utilizamos frequentemente as configurações globais, como use local time, e também o horário do navegador. Como estamos em localhost, ele está utilizando o horário local, o que é compatível. Portanto, esse problema não ocorrerá aqui, mas é uma causa comum de gráficos pararem de aparecer. É importante estar atento a isso.
Para verificar se a hora está correta, podemos usar o comando:
# 3. A hora está certa?
date
Tudo está funcionando corretamente, e estamos prontos para avançar para a próxima etapa. A próxima etapa será a visualização com o Grafana, onde conectaremos o Prometheus a uma ferramenta ainda melhor. O Grafana permitirá que essas métricas sejam exibidas em gráficos, possibilitando um controle ainda mais eficaz. Nos vemos na próxima etapa.
O curso Observabilidade e métricas: instrumentação, dashboards e SLOs no Kubernetes possui 222 minutos de vídeos, em um total de 69 atividades. Gostou? Conheça nossos outros cursos de Confiabilidade em DevOps, ou leia nossos artigos de DevOps.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
O Plano Plus evoluiu: agora com Luri para impulsionar sua carreira com os melhores cursos e acesso à maior comunidade tech.
2 anos de Alura
Matricule-se no plano PLUS 24 e garanta:
Jornada de estudos progressiva que te guia desde os fundamentos até a atuação prática. Você acompanha sua evolução, entende os próximos passos e se aprofunda nos conteúdos com quem é referência no mercado.
Programação, Data Science, Front-end, DevOps, Mobile, Inovação & Gestão, UX & Design, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
Acesso à inteligência artificial da Alura.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Luri Vision chegou no Plano Pro: a IA da Alura que enxerga suas dúvidas, acelera seu aprendizado e conta também com o Alura Língua que prepara você para competir no mercado internacional.
2 anos de Alura
Todos os benefícios do PLUS 24 e mais vantagens exclusivas:
Chat, busca, exercícios abertos, revisão de aula, geração de legenda para certificado.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.
Para quem quer atingir seus objetivos mais rápido: Luri Vision ilimitado, vagas de emprego exclusivas e mentorias para acelerar cada etapa da jornada.
2 anos de Alura
Todos os benefícios do PRO 24 e mais vantagens exclusivas:
Catálogo de tecnologia para quem é da área de Marketing
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais de forma ilimitada.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.
Conecte-se ao mercado com mentoria individual personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.