Olá! Boas-vindas ao curso de Observabilidade: coletando métricas de uma aplicação com Prometheus. Sou o Kleber Costa, instrutor responsável pelo curso.
Audiodescrição: Kleber é um homem de pele clara com cabelos curtos, ondulados e pretos. Tem olhos castanhos claros, barba grisalha e usa óculos de grau com armação retangular cinza. Está vestindo uma camiseta azul. Ao fundo, uma parede branca.
Neste vídeo, o conteúdo abordado será:
Este curso destina-se a pessoas desenvolvedoras, de operação de infraestrutura, pessoas, de DevOps e de engenharia de confiabilidade de sites. Mesmo que você ainda não integre uma dessas equipes, esse conteúdo te possibilitará adquirir diferencial para adentrar em um desses times.
A observabilidade consiste em acompanhar o estado de execução de um sistema através da externalização do seu comportamento em tempo de execução. Ou seja, o objetivo é tornar a aplicação observável para uma fonte externa. O que deve ser observável na aplicação são os comportamentos que importam para a experiência do usuário final.
O monitoramento consiste em acompanhar o estado de um sistema através de eventos registrados e executar ações como resposta a esses eventos. Essas respostas podem ser derivadas de ações reativas e proativas.
A observabilidade faz parte do escopo de monitoramento. Com aplicações complexas e distribuídas, não é possível mais ter um monitoramento efetivo sem a observabilidade. Portanto, a observabilidade é fundamental para entendermos como um sistema tem se comportando diante do consumo.
Se estamos lidando com observabilidade e monitoramento, precisamos de algum indicador para trazer os dados importantes. Uma métrica é basicamente um indicador de nível de serviço, coletado dentro de uma série temporal.
As métricas são utilizadas para a medição de performance, disponibilidade, saturação (uso dos recursos que ultrapassa o previsto), erros e qualquer informação útil para o negócio. Portanto, a métrica é uma medição em uma janela de tempo que foca em uma propriedade do sistema.
Uma métrica sempre vai possuir um objetivo específico. Para cada ponto de atenção do sistema deve existir uma métrica correspondente. Significa que podemos extrair métricas da infraestrutura, da execução da aplicação e também de regras de negócio. Isso é possível através da instrumentação.
A partir das métricas, obteremos informações úteis tanto para a equipe de desenvolvimento, para a operação de infraestrutura e também para a área de negócios.
Entendendo o que é observabilidade, monitoramento e o que são métricas, podemos avançar para o cenário do curso.
Este diagrama que mostra o ambiente que vamos utilizar. Este ambiente sobe uma stack do Docker Compose. Então, é pré-requisito para esse curso ter o Docker e Docker Compose instalados, além do Maven. Será necessário ter também o Java. Recomendo a versão 1.8 do Java, OpenJDK.
Além disso, recomendo que você utilize alguma IDE que possa trazer dependências de forma automatizada. Nós vamos trabalhar com o Eclipse, então, fica a seu critério adotar esta ou outra IDE que cumpra esse requisito.
Nossa jornada do cliente para consumir essa aplicação começa com um cliente sintético, que vai representar os nossos usuários e executará um acesso não previsível à aplicação, gerando tanto acessos em rotas com êxito, como erros de autenticação, logins, busca por conteúdos que não existem. Mas, a maior parte dos acessos terão êxito.
Este cliente inicia a sua jornada passando por um proxy reverso, um container em GeneXus que redireciona para as rotas da API. Essa API tem uma rota principal, que no curso vamos chamar de endpoint
, para não causar nenhuma dificuldade para quem não entende o mundo de desenvolvimento.
Essa rota principal tem seu conteúdo armazenado em um cache, que é um container rodando o redis. Na subida da aplicação, esse conteúdo não estará cacheado, portanto, o primeiro acesso não terá Cache Hit, seguirão para o container que é a base de dados, o mysql, retornarão o conteúdo para o cliente e o armazenará em cache.
Também existe uma passagem de parâmetros que busca por um ID específico nesta rota principal que se chama Topicus. Essas consultas sempre chegarão ao database. Existe a autenticação que validará, via regras de negócio, o que for inserido pelo usuário com dados contidos no database.
Além disso, contamos com a função de delete da API, mas ela não será utilizada. Nosso foco é específico em relação à instrumentalização e das métricas.
Nesse primeiro passo, vamos instrumentar essa API, externalizar suas métricas com seu comportamento e subir o Prometheus, que está em nossa stack de monitoramento. O Prometheus será utilizado para entendermos quais são os tipos de métricas default que ele utiliza e começarmos a nossa imersão na linguagem PromQL.
Na plataforma Alura, você encontra um segundo curso que dá sequência a essa atividade e tem como foco atividades no grafana e no alertmanager integrado ao Slack para fazer a camada final de monitoramento em cima da observabilidade que configuraremos.
Finalizamos a apresentação do curso. Nos encontramos no próximo vídeo!
Olá, pessoal, tudo bem? Boas-vindas! Neste vídeo, vamos configurar e entender algumas peculiaridades do ambiente.
Estamos utilizando o Eclipse, que é uma dependência para seguir com o curso. Se quiser, você pode usar outra IDE, porém, recomendamos o Eclipse, porque ele tem a funcionalidade de trazer as dependências que precisamos para essa aplicação, como o Maven.
Então, vamos importar o projeto selecionando "Import projects". Na próxima tela, buscaremos por um projeto Maven já existente, "Existing Maven Projects", e apertaremos "Next". Na outra tela, apertaremos "Browse" e encontraremos o conteúdo descompactado do pacote que está disponível na plataforma.
Por conveniência, estamos usando o path do Workdir do Eclipse. Você pode utilizar outro lugar sem problemas. Então, vamos selecionar "prometheus-grafana". Dentro desse conteúdo, acessaremos o subdiretório "app". Nesse subdiretório, existe um arquivo pom.xml
que o Eclipse vai reconhecer automaticamente como o arquivo de um projeto.
No canto superior direito, apertaremos o botão "Open". Na outra tela, verificaremos que esse arquivo está selecionado e pressionaremos "Finish" para que o projeto seja importado. Feito isso, na lateral esquerda da próxima tela, visualizaremos a nossa API: forum
. O primeiro passo foi realizado com êxito!
Agora, vamos para o segundo passo. Vamos abrir o terminal. Estamos usando o Linux, mas você pode cumprir as dependências em qualquer sistema operacional, seja o Windows, o Linux ou o MacOS.
Vamos entrar onde a aplicação está descompactada, onde está toda a stack.
cd eclipse-workspace/prometheus-grafana/
Em seguida, passaremos ls
.
ls
app docker-compose.yaml grafana mysql nginx
Encontraremos o diretório MySQL
, um docker-compose
com Pose
e o app
. Não usaremos o grafana
ou o nginx
no momento. Não precisamos nos preocupar com eles, são só lixo residual que ficou nesse pacote que estamos utilizando. O que será disponibilizado na plataforma não terá esse conteúdo.
Vamos começar analisando o conteúdo que está dentro de mysql
.
cat mysql/database.sql
Este script será executado quando o container do MySQL subir para popular a base. Agora, vamos analisar o docker-compose
. Ele é quem vai subir a stack que utilizaremos.
vim docker-compose.yaml
Retorno:
version: '3'
networks:
local:
services:
redis-forum-api:
image: redis
container_name: redis-forum-apt
restart: unless-stopped
ports:
- 6379:6379
networks:
- local
mysql-forum-apt:
image: mysql:5.7
container_name: mysql-forum-api
restart: unless-stopped
environment:
MYSQL_DATABASE: forum
MYSQL_USER: 'forum'
MYSQL PASSWORD: 'Bk55yclu@elqgabe'
MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
MYSQL_ROOT_HOST: '%'
volumes:
- ./mysql:/docker-entrypoint-initdb.d
ports:
- 3306:3306
networks
- local
depends on:
- redis-forum-api
"docker-compose.yaml" 33L, 641c
Temos dois serviços: o redis-forum-api
e o mysql-forum-api
. Esses dois containers farão bind de porta com a máquina. Então, se tivermos uma instância local rodando MySQL, geraremos conflito. Se tivermos qualquer serviço ocupando a porta 3306 TCP, devemos derrubá-lo para que o bind ocorra sem gerar nenhum problema.
O mesmo vale para o Redis, que vai rodar na 6379
, porta padrão do Redis, fazendo bind para 6379
da nossa máquina. Ele estará numa rede local do docker-compose
, mas vai bindar na nossa porta. Em seguida, temos configurações do MySQL e sua dependência. Ele precisa que o Redis suba primeiro para que ele possa subir depois.
Essas são as dependências básicas de comunicação da API. Ela depende disso. Por isso, essa stack foi disponibilizada nesta aula.
Antes de subir a stack, vamos fazer uma equivalência. É importante que o docker esteja instalado. Então, vamos rodar um docker --version
, para realizar uma equivalência de versão.
docker --version
Docker version 20.10.7, build 20.10.7-0ubuntu5~18.04.3
Essa é a versão do Docker que estamos utilizando. E também temos a versão do docker-compose
.
docker-compose --version
docker-compose version 1.29.2, build 5becea4c
É importante que você tenha uma versão igual ou superior à nossa. Se for muito superior, talvez aconteça algum conflito. Se isso acontecer, basta comunicar o fórum ou fazer downgrade da versão. É um problema bastante simples de resolver e, de qualquer maneira, é bastante difícil acontecer essa quebra de compatibilidade.
Também vamos rodar o java -version
e conferir a versão.
java -version
Picked up JAVA_OPTIONS: -Djdk.net.URLClassPath.disableClassPathURLCheck=true
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (build 1.8.0_312-8u312-b07-0ubuntu1-18.04-b07)
OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)
Estamos na versão 1.8. Feito isso, podemos subir a stack:
docker-compose up
Retorno:
File "http/client.py", line 1032, in send_output
File "http/client.py", line 972, in send
File "docker/transport/unixconn.py", line 43, in connect
urllib3.exceptions.ProtocolError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "docker/api/client.py", line 214, in_retrieve_server_version
File "docker/api/daemon.py", line 181, in version
File "docker/utils/decorators.py", line 46, in inner
File "docker/api/client.py", line 237, inget File "requests/sessions.py", line 543, in get
File "requests/sessions.py", line 530, in request File "requests/sessions.py", line 643, in send
File "requests/adapters.py", line 498, in send
// Retorno omitido.
Não vamos subir de forma em in daemon agora. Tivemos um erro previsível. Não subimos o serviço do Docker e, sem ele, o docker-compose
não vai conseguir subir os containers. Vamos fazer isso.
sudo systemctl start docker.socket
No Windows, o processo é outro. Ele tem, inclusive, um cliente de interface gráfica, que facilita a operação. Basta dar "start" no serviço.
Seguindo, basta aguardar. Vamos verificar o status do serviço.
sudo systemctl status docker docker.socket
Retorno:
docker.service Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled) Active: active (running) since Thu 2022-01-06 17:10:22 -03; 5s ago
Docs: https://docs.docker.com
Main PID: 22256 (dockerd)
Tasks: 13
CGroup: /system.slice/docker.service
22256 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
// Retorno omitido.
Apareceu active running
, então, subiu tudo. Agora podemos passar o docker-compose up
. Então, ele vai criar as redes e os containers. O processo de criação dos containers é um pouco mais demorado, porque o Docker vai fazer download do Redis, na última versão, e do MySQL 5.7, das imagens base.
Com isso, temos a base necessária para rodar a nossa aplicação. Terminou de rodar e apresentou até o versionamento. E ele está esperando por conexões, isto é, ready for connections
.
Vamos abrir o terminal e acessar app
.
cd app/
Em app
, vamos rodar o comando mvn clean package
, que é o Maven. Então, estamos chamando o Maven para fazer o build da aplicação e verificar se está tudo certo com o pacote que baixamos.
mvn clean package
É possível fazer isso pelo Eclipse, pois ele também tem essa funcionalidade, mas preferimos fazer no terminal. Ele vai executar uma série de testes da aplicação. E, se tudo passar, vai concluir o build e gerar um artefato JAR. Passou e ele rodou quatro testes, com nenhuma falha ou erro.
Results:
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
// Retorno omitido.
Feito isso, vamos ao Eclipse. Temos um script chamado start.sh
. Basta executar esse script para que a aplicação possa subir. Por enquanto, estamos fazendo algo bem básico, porque vamos alterar poucas coisas no código da aplicação. Mas, esse processo evitar termos que ficar rebuildando containers várias vezes.
Quando chegarmos ao status final da aplicação, com ela instrumentada, com o Application Properties
devidamente configurado, ela se transformará em um container e subirá diretamente via Docker Compose.
Então, subimos a aplicação. Agora, vamos ao Firefox e acessaremos localhost:8080/topicos
. Está rodando!
content:
0:
id: 3
titulo: "Duvida 3"
mensagem: "2019-05-05T17:00:00
1:
id: 1
titulo: "Projeto nao compila"
dataCriacao: "2019-05-05T16:00:00"
// API omitida.
Essa é a nossa API, ela responde por topicos
e também aceita um ID específico em topicos
. Por exemplo, vamos passar a URL localhost:8080/topicos/1
. O resultado será:
id: 1
titulo: "Duvida 1"
mensagem: "Erro ao criar projeto"
dataCriacao: "2019-05-05T15:00:00
nomeAutor: "Aluno"
status: "NAO RESPONDIDO"
respostas: []
Na base, o script SQL populou 3 IDs. Então, temos 1, 2 e o 3, são endpoints. Para cada inserção de tópico que ocorrer nessa aplicação, um endpoint com um número de ID será gerado.
Então, configuramos a stack, já temos tudo pronto para seguirmos com os próximos passos! Temos que resolver um problema: se observarmos nossa aplicação hoje, ela não está instrumentalizada, ela não tem observabilidade. Então, não sabemos como está seu funcionamento de fato.
Ela está respondendo, mas, quanto está consumindo de CPU? Qual o tempo de resposta para os clientes? Quanto está usando de memória? Como está a conexão com a base de dados? Qual é a duração de uma requisição? Estamos com algum erro? Não sabemos essas informações.
Portanto, vamos criar a primeira parte da camada de observabilidade para compreendermos o funcionamento da aplicação, começando pelo Actuator. Até mais!
Olá, pessoal! Agora, vamos iniciar a configuração do Actuator para tornar nossa aplicação observável.
Na aula anterior, conseguimos implementar o ambiente e subir a aplicação. É importante que você consulte a documentação do Actuator. Ela é facilmente encontrada no Google. Basta pesquisar "Actuator" e um dos primeiros resultados será a documentação do Spring, explicando como habilitar o Actuator.
Você pode acessar a documentação do Actuator através do link Spring Boot Reference Documentation.
Para encontrar a dependência Maven, basta acessar o link Enabling Production-ready Features
O Actuator atua como uma dependência. No nosso caso, estamos utilizando o Maven. Então, vamos copiar essa dependência.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Se você estiver usando o Gradle, a implantação será outra. Mas, no nosso caso, é o Maven.
Agora, acessaremos o Eclipse e abriremos o arquivo forum/pom.xml
. Neste arquivo, há uma série de dependências já configuradas. Vamos encontrar um espaço para colar a dependência que copiamos, tomando cuidado para manter a identação.
Com isso, a dependência já está configurada. Vamos salvar e, automaticamente, o Maven vai baixar essa dependência através do Eclipse. O processo é bem simples!
Terminada esta etapa, vamos realizar alguns ajustes na nossa aplicação. Porém, não alteraremos o código da aplicação agora. Ainda no Ecplise, lateral esquerda da tela, acessaremos "src/main/resources" e abriremos o arquivo applicationprod.properties
.
Nele, encontraremos diversas configurações: a porta onde a aplicação sobe; a configuração do Redis, MySQL e JPA para conexão; e o token JWT, porque essa aplicação usa um token. Para algumas ações, como excluir ou criar um tópico, é necessário ter um token gerado através de uma autenticação. Estamos falando de uma API REST.
Vamos inserir algumas linhas neste arquivo.
#actuator
management.endpoint.health.show-details=always
management.endpoints.web.exposure.include=*
A primeira linha que inserimos está como always
, logo, mostrará todos os detalhes. Na segunda, temos o web.exposure
. Mantendo o asterisco, receberemos todas as informações relacionadas à JVM e tudo que estiver relacionado ao gerenciamento da aplicação pela JVM. Para o nosso caso, isso não é muito interessante.
Sendo assim, apagaremos o asterísco e acessaremos alguns endpoints: health
; info
; e metrics
. Esses três já são suficientes. Nosso foco será o metrics
.
#actuator
management.endpoint.health.show-details=always
management.endpoints.web.exposure.include=health,info,metrics
O health
é útil por poder ser usado para health check, dependendo de onde a aplicação estiver rodando. E o info
é útil porque nos permite acessar as informações da aplicação importantes para nós e não para o público externo.
Os endpoints Health
, info
e metrics
são internos, eles não devem ser expostos publicamente. Quando a aplicação estiver rodando na stack do Docker Compose, estes endpoints estarão fechados. Para acessá-la, teremos que passar por um proxy que também será implantado mais adiante.
Com esses pré-requisitos cumpridos, vamos ao terminal. A aplicação está rodando e podemos fechar a janela de /bin/bash
. Como já estamos no diretório da aplicação, vamos rodar um mvn clean package
para recompilar essa aplicação. O processo é bem simples e, como dito na aula anterior, pode ser feito diretamente no Eclipse.
Nos containers, não é necessário realizar nenhuma alteração. Não subimos em modo daemon, então, ele está trazendo o status dos containers. Vamos localizar o ponto em que a aplicação está sendo buildada. Rodou corretamente. Vamos agora para o Eclipse.
No Eclipse, vamos acessar o start.sh
novamente e rodar a aplicação. Se você estiver usando o Windows, provavelmente o /bin/bash
não funcionará. Neste caso, você pode rodar o código a seguir na linha de comando, no cmd do próprio Windows, contanto que você esteja posicionado no path, onde está o app
. Você tem que estar dentro do diretório app
.
java -jar -Xms128M -Xmx128M -XX:PermSize=64m -XX:MaxPermSize=128m -Dspring.profiles.active=prod target/forum.jar
Lembrando que, no Windows, é necessário usar "contra barra" /
ao invés de barra \
, porque ele não entende a barra. No Linux, ela faz distinção entre um diretório e outro. No MacOS não muda nada.
A aplicação foi iniciada. Temos topicos
, topocos/1
e de outros ids, e agora, temos /actuator
. Então, vamos acessar http://localhost:8080/actuator
.
Temos o health
e um path específico, mas ele é herdado do health
que foi configurado no application.properties
.
Então, temos o endpoint health
, o endpoint health-path
, que veio herdado do health
. Temos o info
e o metrics
com uma métrica específica e o metrics
puro. Vamos abrir o health
.
O health
pode ser usado como health check. O status indica "up". Ele apresenta, inclusive, a comunicação da qual a aplicação depende, no caso, o MySQL (que stá conectado). Apresenta também o espaço em disco e o Redis.
Então, esse health
é importantíssimo para a questão de health check. Ele nos ajuda a entender, de maneira imediata, se alguma dependência está com problema. Se ele não se conectar com o Redis, essa informação aparecerá aqui. Se não se conectar com o MySQL, também, pois isso não depende da aplicação.
Agora, vamos analisar o info
. Nele, econtramos o app
, o nome, a descrição, a versão e como ele está codificado. Em seguida, temos a versão do Java. O ponto alto é que, acessando metrics
, temos a exposição de todas as métricas da JVM.
Dentre essas métricas, é possível consultar o uso de CPU, o log em "logback", as threads, memória, garbage collector, pool de conexões da JDBC com o banco, conexões pendentes, timeout utilizado, tempo de criação, entre outras.
Selecionando um dos nomes dessas métricas, conseguimos chegar no endpoint e acessar a métrica específica. Por exemplo, vamos selecionar Hikaricp.connections
e chamar o endpoint passando a métrica:
localhost:8080/actuator/metrics/hikaricp.connections
Com isso, abrimos a métrica Hikaricp.connections
e encontramos o valor 10.
Conseguimos expor as métricas da JVM, porém, elas não estão no formato esperado. Não conseguimos identificar e usar essas métricas através do Prometheus, que é o nosso objetivo.
A seguir, vamos configurar o Micrometer, que tornará essas métricas legíveis para o Prometheus. Até logo!
O curso Observabilidade: coletando métricas de uma aplicação com Prometheus possui 160 minutos de vídeos, em um total de 23 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:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
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.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes á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.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.