Entre para a LISTA VIP da Black Friday

00

DIAS

00

HORAS

00

MIN

00

SEG

Clique para saber mais
Alura > Cursos de DevOps > Cursos de Confiabilidade > Conteúdos de Confiabilidade > Primeiras aulas do curso Monitoramento: Prometheus, Grafana e Alertmanager

Monitoramento: Prometheus, Grafana e Alertmanager

Dashboards com Grafana - Apresentação

Olá! Te desejo boas-vindas ao curso de Monitoramento com Prometheus, Grafana e Alertmanager! Meu nome é Kleber Costa e serei seu instrutor nesta jornada.

Audiodescrição: Kleber é um homem de pele clara e cabelos curtos e cacheados na cor loiro escuro. Possui barba e bigode, também curtos, na cor loiro escuro e tons de grisalho. Usa óculos de armação retangular na cor cinza e veste uma camiseta lisa na cor azul-marinho. Ao fundo, uma parede lisa na cor branca.

Nesta jornada, abordaremos o seguinte conteúdo:

Aplicabilidade

Esse curso é destinado para pessoas desenvolvedoras, pessoas de operação de infraestrutura, pessoas de DevOps e pessoas de engenharia de confiabilidade de sites (site reliability engineering).

Requisitos

Para realizar esse treinamento sem grandes dificuldades, você precisa ter feito o curso de Observabilidade com Spring e Prometheus, já que estamos dando sequência nas implantações da stack apresentadas.

Neste primeiro curso, fizemos a instrumentação de uma API Spring para que ela pudesse expor as métricas default da JVM e as métricas personalizadas. Tudo isso foi feito utilizando o Actuator e, posteriormente, o Micrometer, para fazer a interface dessas métricas e levá-las com um formato legível para o Prometheus.

O Prometheus foi levantado nesse curso também e houve uma introdução à linguagem PromQL, trabalhando com a sua sintaxe e os tipos de métricas que o Prometheus utiliza, além de lidar com questões relacionadas à composição das métricas.

Se você já possui esse conhecimento, não é necessário fazer o curso anterior. Porém, se não entendeu algum dos termos que mencionamos, recomendamos que faça o curso anterior para poder acompanhar este assunto sem grandes dificuldades, dando continuidade a todas as tarefas.

Outros pré-requisitos incluem ter o Docker e o Docker Compose instalados em sua máquina.

Golden Signals

Agora, vamos falar um pouco sobre o que será abordado nesse treinamento.

Falaremos sobre os Golden Signals (Sinais de Ouro), que são quatro:

Esses sinais foram definidos pelo Google e a premissa é a seguinte: se só pudermos olhar para quatro componentes da aplicação, devemos focar nesses quatro.

A latência está relacionada ao tempo de resposta da aplicação; o tráfego, ao número de requisições que a aplicação recebe; e a saturação, ao uso excedente dos recursos que suportam a aplicação. Os erros, por sua vez, correspondem à quantidade de erros que ocorrem durante a execução da aplicação, seja em retorno para o usuário ou em interação com a infraestrutura que suporta o sistema.

Esses sinais de ouro estão referenciados no livro SRE, do Google. É extremamente importante entender esse conceito e, ao olhar para um projeto, planejar a camada de observabilidade e monitoramento de forma que esses quatro sinais possam ser observados.

Metodologias USE e RED

Como os sinais abrangem um espectro muito amplo, existem métodos que facilitam a observabilidade e o monitoramento desses aspectos.

A metodologia USE foca na utilização de recursos, na saturação e nos erros. Esta metodologia está bastante voltada para questões de infraestrutura. Analisamos fundamentalmente a utilização do disco, o desempenho de IO, o tráfego de pacotes, a saturação (que representa o uso excessivo de recursos) e os erros gerados na comunicação entre recursos, decorrentes da interação dos usuários com sua aplicação e da forma como ela se relaciona com a infraestrutura que a suporta.

O método USE não será nosso foco neste treinamento. Isso porque, por ser muito abrangente, precisaria de um curso específico, focado apenas nele.

Aqui, focaremos no método RED, que aborda a taxa de requisições (Rate), os erros gerados pelas iterações e a duração dessas requisições. É importante entender que esses três aspectos geram muitos desdobramentos, por isso também veremos algumas particularidades do método USE que complementem a utilização do método RED, entregando uma camada de observabilidade e monitoramento completa.

O método RED, diferentemente do USE, foca mais em iterações que estão relacionadas ao protocolo HTTP. Nosso objetivo, portanto, é mensurar a experiência do usuário final, medindo a satisfação de quem consome a API.

Cenário do curso

Agora, vamos entender o cenário do curso para entender qual é nossa missão.

Já falamos sobre a jornada do nosso cliente, que é um cliente sintético. Se trata, basicamente, de um container com um script que consome de forma não previsível a nossa API. Isso gera, inclusive, algumas interações com erros, o que é interessante em termos de observabilidade, para que ela realmente possa ser testada.

Já temos um proxy reverso, a API, um cache e um banco de dados. Cada um em seu respectivo container, todos rodando em uma stack do Docker Compose. Além disso, já temos o Prometheus configurado e sendo utilizado.

O que faremos nesse curso é configurar o Grafana. Para isso, vamos configurar diversos painéis, tendo um dashboard abrangente com o Grafana, subir o Alert Manager e configurar a integração dele com o Slack.

Também faremos a comunicação do Prometheus configurado com o Alert Manager, a camada de visualização gráfica utilizando o Grafana, e o Slack como o endpoint de alertas. Basicamente, o nosso Alert Manager vai se comunicar com o Slack, passando para um canal específico todos os alertas que forem gerados através de eventos críticos em nosso ambiente.

Todo incidente que ocorrer vai gerar um alerta que será enviado para o Slack e visualizado por um time de suporte e pelas pessoas desenvolvedoras dessa API.

Benefícios

Para finalizar, vamos falar sobre os benefícios de concluir esse treinamento.

A prática que faremos aqui serve para trabalharmos na redução do tempo médio de detecção de incidentes, o MTTD (Mean Time To Detect). Quando temos visibilidade sobre métricas, temos essa camada de observabilidade, conseguimos detectar algumas nuances dentro do nosso sistema. Então, conseguimos identificar o início de degradações que, ao se desenvolverem, causam um incidente.

Uma vez que identificamos o início dessa degradação, conseguimos iniciar uma busca pela causa raiz do incidente e resolver o problema antes que grande parte dos usuários seja impactada. Com isso, também teremos uma redução do MTTR (Mean Time To Repair), que é o Tempo Médio de Reparo.

Além disso, vamos abordar um assunto que está dentro do escopo SRE, mas que também é derivado de métricas: o Acordo de Nível de Serviço, o SLA (Service Level Agreement), que é um documento que faz parte de uma norma ISO e que serve como base para termos um objetivo de nível de serviço. Esse objetivo será basicamente o foco em manter a qualidade e a estabilidade do nosso serviço acima desse SLA.

Então, temos um Acordo de Nível de Serviço, que normalmente gera algum tipo de punição caso não seja cumprido. Para manter esse SLA, teremos um objetivo de nível de serviço que está acima desse SLA. Para estar dentro desse objetivo de nível de serviço, precisamos ter indicadores, e esses indicadores são considerados como o SLI (Service Level Indicators), que são basicamente compostos através de métricas.

Dentro desse escopo, vamos abordar brevemente o Error Budget (Orçamento de Erro), que é a margem de erro que temos para falhar sem culpa. Não vamos detalhar esse assunto porque o escopo dele é SRE, e aqui estaremos falando de uma prática da engenharia de confiabilidade de sites, que é a medição, o trabalho com a observabilidade e o monitoramento através de métricas. Ou seja, este não é um curso de SRE.

Além de aprender esses conceitos e trabalhar com métricas, entenderemos o que é a composição de uma Baseline comportamental, afinal de contas, uma série temporal pode entregar isso. Entenderemos, ainda, que as ações de escalabilidade automática e preditiva são derivadas também do uso de métricas, por isso a importância de se trabalhar com métricas.

Aprenderemos, também, ações reativas e proativas. As ações reativas acontecem quando existe uma reação, como um evento disparado com base em algo que foi monitorado e observado. Dentro desse escopo, entram os acionamentos, um call, e alertas automatizados.

Um alerta, ou uma ação automatizada, é uma reação. Já quando falamos de escalabilidade preditiva, temos ações proativas. Tudo isso é gerado através do uso de métricas.

O ponto mais forte deste curso é a medição da experiência do usuário. Se não temos usuários satisfeitos com a nossa aplicação, ela não serve de nada. Por isso, este é o nosso objetivo final e com ele vamos rumo à confiabilidade.

Esperamos agregar um pouco de conhecimento na sua jornada. Vamos nessa?

Dashboards com Grafana - Subindo o Grafana

Nessa aula, vamos configurar o Grafana. Este processo é bastante simples. Você já terá um pacote na plataforma com todo o conteúdo para a configuração do Grafana. Faremos algumas configurações após a configuração inicial do container, que você realmente precisará executar. Recomendamos que você utilize o que já foi preparado para evitar erros de digitação relacionados à sintaxe do YAML no Docker Compose. No entanto, se você preferir digitar e fazer manualmente, também é válido e funcionará.

No diretório de trabalho, onde está o Docker Compose, vamos criar um diretório chamado grafana com o comando mkdir grafana. Este diretório servirá como um volume para o container e é onde o Grafana armazena suas informações.

mkdir grafana

Após a criação deste diretório, vamos aplicar um comando chmod para alterar suas permissões para 777.

chmod 777 grafana

Quando executamos este comando, estamos atribuindo permissões muito abertas, o que pode ser considerado inseguro, para este diretório. No entanto, estamos falando apenas do diretório grafana. Ao verificar este diretório com ls- lh grafana/, vemos que ele está vazio.

ls- lh grafana/

Ao olharmos para o diretório em si com ls- lhd grafana/, vemos que qualquer pessoa pode executar, ler e escrever no diretório. Este passo é necessário porque quando o container do Grafana é levantado, ele terá um usuário próprio que precisará usar este diretório, pois ele será montado como um volume dentro do container. Se ele não tiver permissões para entrar no diretório e escrever, o container não será iniciado.

ls- lhd grafana/

Agora, vamos abrir nosso arquivo docker-compose.yml.

vim docker-compose.yml

Nele, temos a configuração atual com o container do Prometheus e o container do client, que depende do Prometheus para iniciar. Na verdade, o Prometheus depende do proxy e o client depende do Prometheus. Temos essa dependência intercalada de containers. Vamos respeitar isso para o Grafana.

Para economizar tempo, vamos colar a configuração que já preparamos entre o conteúdo do Prometheus e do client, nas linhas 97 a 108.

dependes_on: 
    - proxy-forum-apt

grafana-forum-api:
    image: grafana/grafana
    container_name: grafana-forum-api
    volumes:
        - ./grafana:/var/lib/grafana
    restart: unless-stopped
    ports:
        - 3000:3000
    networks:
        - monit
    depends_on:
        - prometheus-forum-apt

client-forum-api:

Esse bloco indica que teremos um service, que é o container, chamado grafana-forum-api, que trabalhará com a imagem mais recente do Grafana. Ele terá como volume o diretório grafana, que criamos e aplicamos a permissão, e ele será montado dentro do container em /var/lib/grafana.

O esquema de reinício é igual ao dos outros containers. Se derrubarmos este container, ele não voltará automaticamente. Isso é intencional. Se tivermos uma falha, não entraremos em um loop tentando iniciar o serviço, e também em casos em que derrubamos um container para forçar uma situação de erro, ele não vai subir automaticamente. O Grafana roda na porta 3000 TCP, e ele fará a ligação da porta para o Docker Host, para a sua máquina. Assim, em localhost:3000, você poderá acessar o Grafana. Ele está na Network monit, que é a mesma do Prometheus, e ele depende do prometheus-forum-api.

A única alteração adicional que faremos é na dependência do client. Agora, o client será iniciado após o Grafana. Isso é bom porque dá um tempo para o client enviar as requisições para a API. O client se comunica com a API através do proxy, enviando requisições, mas ele inicia antes que o MySQL esteja devidamente configurado.

No esquema de dependência, o redis é o primeiro a subir, o mysql sobe depois do redis e depende dele para subir. O app depende do mysql para subir. O proxy depende do app para subir, e o prometheus depende do proxy.

depends_on:
    - grafana-forum-api

Agora, o grafana depende do prometheus e o client depende do grafana. Sem essa configuração, da maneira que estava antes, mesmo que o container do MySQL subisse, o MySQL ainda não estava com o banco de dados configurado e o client já enviava requisições. Isso resultava em alguns erros 500 que vocês podem observar nas métricas anteriores que verificamos.

Vamos salvar o conteúdo e rodar o comando docker -compose up -d para que ele suba. Ele baixará a imagem do Grafana, fará todo esse processo já conhecido e subirá toda a stack na ordem de dependências que está no Docker Compose e, por último, subirá o Grafana.

docker -compose up -d

Vamos aguardar finalizar o processamento. Em seguida, para validar isso, abriremos o navegador em localhost/metrics. Se não subiu, basta atualizar até que o container tenha subido.

Note que temos o erro 500 que conseguimos observar. Isso porque estamos usando um volume no Prometheus e o TSDB está sendo armazenado, então temos essa referência histórica. Se procurarmos por requisições 200, temos o actuator prometheus. Agora, o nosso client, que já começa a atingir /auth, começa também a atingir /topicos/{id}.

Estamos consumindo a aplicação e isso já está sendo refletido nas métricas. Se acessarmos localhost:9090, chegaremos à interface do Prometheus, com o expression browser (navegador de expressão).

Em seguida, podemos ir para o Grafana, que está em localhost:3000, como mencionamos anteriormente. No primeiro acesso ao Grafana, o login é admin e a senha também. Ele vem com essa configuração por padrão. Depois que autenticarmos, ele pedirá para criarmos uma nova senha.

Após autenticarmos no Grafana, teremos acesso à sua interface. Nela, a primeira coisa que faremos é configurar um data source. Então, no símbolo de "Configuration", na lateral esquerda, clicamos em "Data Sources".

Um data source é uma origem de dados para o Grafana. Ele pode ter vários data sources, como Splunk, CloudWatch, Prometheus, etc. Em seguida, clicamos em "Add data source" para adicionar um data source. O primeiro da lista é o Prometheus, vamos selecioná-lo.

O nome será Prometheuse como URL passaremos http://prometheus-forum-api:9090. Este é o endereço porque ele vai se comunicar com o container. Se colocarmos localhost, o Grafana vai achar que ele é o próprio endpoint de métricas do Prometheus e não é. Não vamos mexer em mais nenhuma opção, apenas salvar e testar clicando em "Save & test".

Feito isso, vamos em "Configuration", na barra lateral", e clicamos em "Data sources". Com isso, veremos o Prometheus configurado.

Vamos para outra configuração rápida. Primeiro, clicamos no símbolo de "+" (mais), na barra lateral esquerda, e vamos em "Folder". Criaremos uma pasta e toda a nossa configuração de dashboard ficará nesta pasta. A nomeamos como forum-api e clicamos em "Create".

Em seguida, clicamos em "Create Dashboard", no centro da página, e em "Dashboard Settings", no menu superior direito. O nome deste dashboard será dash-forum-api. Não faremos nenhuma outra alteração, então basta clicarmos em "Save dashboard".

Esta é a configuração inicial do Grafana e a configuração mais básica, que consiste na seleção de um data source e na criação de uma pasta onde nosso dashboard será configurado. Na próxima aula, vamos trabalhar com as variáveis que usaremos no Grafana.

Dashboards com Grafana - Variáveis e métricas Uptime e Start Time

Agora que já temos uma pasta e nosso Dash criado, vamos iniciar a criação dos painéis. Antes disso, começaremos a utilizar um recurso interessante no Grafana: as variáveis.

Mas por que utilizar variáveis no Grafana? Imagine que a sua API foi implantada em um ambiente distribuído. Você precisaria ter uma métrica para cada instância onde a sua API fosse implantada, o que não seria nada interessante. Com uma variável, é possível alimentar essa variável com valores que estão relacionados às instâncias que estão suportando a sua API. Além disso, podemos também conter uma métrica que possa atender mais de uma aplicação. Portanto, ao utilizar variáveis, tornamos nossas métricas dinâmicas, o que é mais interessante.

Para configurar a variável é simples. Primeiro, vamos em "Dashboard Settings" > "Variables" > "Add variable". A variável terá o nome de application. O "Type" (tipo) da variável se refere a como ela é configurada. Neste caso, será configurada como uma "Query" (consulta).

Sendo assim, vamos realizar uma consulta no endpoint e a configuração dessa variável será herdada de uma configuração já estabelecida no endpoint de métricas. Existem outros tipos, como customizada, constante, entre outros. Mas, no momento, vamos trabalhar com o tipo "Query".

O rótulo da variável ("Label") também será application. Nas opções de query, o "Data Source" é o "Prometheus". Então, vamos buscar no endpoint que está configurado nesse Data Source. A Query que vamos fazer é simples. O primeiro ponto para entender é que vamos trabalhar com um label_values(), então precisamos passar isso no campo "Query". Entre parênteses, indicamos qual é a configuração de label que será encontrada no endpoint de métricas e que vai alimentar a nossa variável application. Neste caso, é o valor application.

label_values(application)

Após fazer isso, automaticamente o Grafana já exibe para nós um preview of values. Feito isso, clicamos em "Update" e temos a primeira variável configurada.

Note que aparecerá um símbolo de aviso de que essa variável não foi referenciada por nenhuma outra variável ou Dashboard. Não se preocupe, não é um erro. Logo criaremos outra variável que vai referenciar essa e o aviso sumirá.

Vamos criar a próxima variável que se chamará instance. Ela também será do tipo "Query", terá o rótulo ("Label") instance e usará o Prometheus como Data Source. A Query que vamos fazer será label_values() e passaremos a métrica jvm_classes_loaded_classes.

label_values(jvm_classes_loaded_classes)

Dentro dessa métrica vamos configurar a variável instance, que trabalha buscando por application. Dentro de application teremos application. Por fim, fora dessa configuração de métrica, declaramos o instance, que será alimentado.

label_values(jvm_classes_loaded_classes{application="$application"}, instance)

Automaticamente, o Preview traz para nós app-forum-api:8080. 8080 se refere à porta TCP que a aplicação está rodando e app-forum-api ao nome da instância onde ela está rodando. Lembre-se que esse é o nome do container.

Feito isso, clicamos em "Update". Agora temos as variáveis application e instance configuradas.

Vamos criar mais uma variável cujo nome e rótulo serão pool e seu tipo será "Query" (consulta). Vamos passar label_values() e usar uma métrica para buscar essa variável, a hikaricp_connections com os Labels instance e application. Ela vai pegar o valor do pool de conexões, que é da JDBC.

label_values(hikaricp_connections{instance="$instance", application="$application"}, pool)

Automaticamente, aparece HikariPool-1em "Previus". Então, podemos clicar em "Update".

Nossas variáveis estão configuradas. Como a variável pool não é referenciada por outra, aparecerá um aviso ao lado dela, mas não precisamos nos preocupar.

Agora, basta salvar o Dashboard e nomear como variables. Com isso, já temos application, instance e o pool de conexões que vamos utilizar.

Vamos em "Add panel", no menu superior direito, e clicamos em "Add a new row" para adicionar uma nova linha. Essa linha será chamada de API Basic. Dentro dessa linha, vamos criar os painéis desse capítulo 3.

Criaremos um painel simples que, basicamente, será uma métrica que traz o Uptime do processo, então passamos process_uptime_seconds{}. Isso nos traz um dado não muito interessante, mas vamos formatá-lo. Trabalharemos com os Labels application, mas é interessante também trabalharmos com as nossas variáveis. Isso porque, se em algum momento tivermos outra aplicação que essa métrica possa ser utilizada, a variável terá mais de um valor. Neste caso, basta ajustá-la e conseguiremos trabalhar com ela como se fosse um vetor.

Além de application e instance, podemos passar outro label importante, que é o job, para o qual não criamos uma variável.

process_uptime_seconds{application="$application", instance="$instance", job="app-forum-api"}

Com isso, temos o painel onde a métrica será exibida. Abaico, temos o datasource e as opções de query. Inclusive, podemos inspecionar a nossa query clicando em "Query Inspector".

Em seguida, temos o browser de métricas, onde colocamos a nossa métrica e ela gera a informação que será exibida no painel. Aqui podemos colocar uma legenda, o formato que estamos utilizando. Em "Legend", podemos colocar uma legenda, e em "Format", o formato. Temos, ainda, outras configurações, como o "Min step", "Resolution", entre outras, com as não lidaremos agora.

O que importa para nós, agora, é configurar o tipo de visualização. Para isso, na barra lateral direita, clicamos em "Time series", onde temos diversos tipos de visualização. Para essa, vamos utilizar o tipo "Stat". Vamos intitular como UPTIME e a descrição será API Uptime. Quando colocamos uma descrição, ao posicionar o mouse sobre o painel, essa descrição é exibida.

Mais abaixo, ainda na barra lateral direita, temos o campo "Calculation", que corresponde à forma de cálculo do valor que será exibido. Vamos pegar o último valor não nulo, que é "Last". O tipo de campo, em "Fields", será numérico, portanto "Numeric Fields".

Em "Color mode", temos um modo de coloração. Se colocarmos como "None", ele ficará sem cor; se colocamos como "Value", ele colore o valor. Já como "Background", colore o fundo. Vamos manter como "Value". O campo "Graph Mode" corresponde à coloração de métrica. Não vamos utilizar, pois queremos colorir apenas o número, então manteremos como "None".

Não faremos alterações no tamanho de texto, em "Text size". Nas opções padrões, em "Standard options", temos um tipo de unidade, no campo "Unit". A unidade ideal para esse valor é "Time", do tipo "durantion)hh/mm/ss)". Ou seja, em hora, minuto e segundo. Ao selecionar essa opção, vemos que a aplicação está de pé há 4 horas, 46 minutos e 15 segundos.

Em seguida, temos o campo "Threshold", que não será utilizado, mas colocaremos essa métrica na cor azul. Com isso, finalizamos algumas configurações e já podemos visualizar o painel UPTIME. Vamos arrastá-lo para dentro de API BASIC. Pronto! Já temos um primeiro painel com o UPTIME da aplicação.

Agora, vamos criar outro, que utilizará a métrica process_start_time_seconds{}. Aqui, vamos pegar o momento que o processo foi reiniciado. Temos o UPTIME da nossa API, mas temos também um Start Time de processo que pode mudar se reiniciarmos a nossa aplicação. Isso não vai influenciar no Uptime, pois são dois valores distintos.

Trabalharemos com os labels application, instance e job.

process_start_time_seconds{application="$application", instance="$instance", job="app-forum-api"}

Mais adiante, vamos configurar uma variável como job. Assim, podemos simplesmente colocar job="$job". Caso tenhamos mais de um job, poderemos utilizar a variável como um recurso válido.

Tendo colocado essa métrica, temos um valor no painel que não fica interessante em forma de gráfico. Então, vamos mudar essa visualização para um formato "Stat", assim como fizemos anteriormente.

Note que temos um Unix Timestamp, uma numeração difícil de entender, por isso teremos que fazer uma conversão rápida. Vamos nomear esse painel como START TIME. Na descrição, passaremos "Hora da inicialização da API".

No cálculo, vamos usar o último valor, "Last". O campo será numérico, portanto "Numeric Fiels". O "Graph mode" ficará como "None". Na unidade, trabalharemos com "Data & time" como do tipo "Datetime ISO".

Em "Thresholds", colocaremos a cor azul. Como é um Unix Time Stamp e está com um bug mostrando a data, vamos multiplicar por mil:

process_start_time_seconds{application="$application", instance="$instance", job="app-forum-api"} * 1000

Fazendo essa conversão, a data some. Temos o painel de START TIME. Este horário corresponde à hora que subimos a nossa API.

Então, já temos dois painéis configurados e já estamos trabalhando com variáveis. Na próxima aula, trabalharemos com uma métrica de usuários autenticados e erros de autenticação.

Sobre o curso Monitoramento: Prometheus, Grafana e Alertmanager

O curso Monitoramento: Prometheus, Grafana e Alertmanager possui 222 minutos de vídeos, em um total de 28 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:

Aprenda Confiabilidade acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas