Dia 25: Monitoring com Prometheus e Grafana no Linux
Saber o estado de um servidor Linux não se resume a verificar se ele responde a ping. Monitorização é sobre CPU, memória, disco, rede, processos e serviços — de forma contínua, histórica e accionável. Prometheus recolhe métricas via exporters, armazena-as numa base de dados de séries temporais e permite consultas com PromQL. Grafana liga-se ao Prometheus e apresenta dashboards visuais com alertas. Este artigo mostra como instalar ambos, configurar o node_exporter, criar dashboards e definir regras de alerta num servidor Linux.
A stack Prometheus + Grafana é o padrão de facto para monitorização em infraestruturas modernas (Prometheus docs, Grafana docs). Funciona em qualquer distribuição Linux e é gratuita.
- Arquitectura da Stack Prometheus + Grafana
- Instalar o Prometheus
- Instalar o node_exporter
- Instalar o Grafana
- Configurar Datasource e Dashboard no Grafana
- Consultas PromQL Essenciais
- Configurar Alertas no Prometheus
- Alertas no Grafana
- Erros Comuns
- Firewall e Segurança
- Checklist de Verificação
- Artigos Relacionados
apt (Debian/Ubuntu) e dnf (RHEL/Rocky/Alma). Se a distribuição usar um gestor diferente, adaptar o comando de instalação.Arquitectura da Stack Prometheus + Grafana
A arquitectura divide-se em três camadas. O node_exporter corre em cada servidor monitorizado e expõe métricas do sistema (CPU, memória, disco, rede) num endpoint HTTP na porta 9100. O Prometheus é o servidor central que faz scrape desses endpoints em intervalos configuráveis (por defeito, 15 segundos), armazena as métricas localmente e permite consultas via PromQL. O Grafana é a camada de visualização que se liga ao Prometheus como datasource e apresenta os dados em dashboards.
O fluxo de dados é simples: exporters → Prometheus (scrape + store) → Grafana (query + display). Não há push de métricas dos servidores para o Prometheus — é o Prometheus que vai buscar os dados (modelo pull). Isto simplifica firewalls porque só é necessário permitir tráfego de saída do Prometheus para os exporters Prometheus docs.
Instalar o Prometheus
O Prometheus pode ser instalado via repositório ou binário directo. Para Debian/Ubuntu, o pacote oficial existe em repositórios de terceiros. Para RHEL/Rocky/Alma, há pacotes via copr. A forma mais universal é descarregar o binário da página oficial.
Descarregar e instalar o binário Prometheus (universal, qualquer distribuição):
# Criar utilizador do sistema para o Prometheus
sudo useradd --system --no-create-home --shell /usr/sbin/nologin prometheus
# Descarregar a versão mais recente (verificar a última em https://prometheus.io/download/)
wget https://github.com/prometheus/prometheus/releases/download/v3.2.1/prometheus-3.2.1.linux-amd64.tar.gz
# Extrair e instalar
tar xzf prometheus-3.2.1.linux-amd64.tar.gz
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo cp prometheus-3.2.1.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-3.2.1.linux-amd64/promtool /usr/local/bin/
sudo cp -r prometheus-3.2.1.linux-amd64/consoles /etc/prometheus/
sudo cp -r prometheus-3.2.1.linux-amd64/console_libraries /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus
Criar o ficheiro de configuração principal do Prometheus:
sudo tee /etc/prometheus/prometheus.yml > /dev/null << 'EOF'
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
rule_files:
# - "alert_rules.yml"
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "node_exporter"
static_configs:
- targets: ["localhost:9100"]
EOF
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
Criar o serviço systemd para o Prometheus arrancar automaticamente:
sudo tee /etc/systemd/system/prometheus.service > /dev/null << 'EOF'
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries \
--web.listen-address=0.0.0.0:9090
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
sudo systemctl status prometheus
Após iniciar, o Prometheus fica disponível em http://localhost:9090. O endpoint /targets mostra o estado de cada exporter configurado Prometheus configuration docs.
Instalar o node_exporter
O node_exporter é o exporter mais comum para métricas de sistema Linux. Expõe CPU, memória, disco, rede, filesystem e muito mais na porta 9100. Corre em cada servidor que se pretende monitorizar node_exporter no GitHub.
Instalar via pacote do sistema (mais simples, quando disponível):
# Debian/Ubuntu
sudo apt update && sudo apt install -y prometheus-node-exporter
sudo systemctl enable --now prometheus-node-exporter
# RHEL/Rocky/Alma (via EPEL)
sudo dnf install -y epel-release
sudo dnf install -y node_exporter
sudo systemctl enable --now node_exporter
Alternativa: instalar via binário directo (universal):
wget https://github.com/prometheus/node_exporter/releases/download/v1.9.0/node_exporter-1.9.0.linux-amd64.tar.gz
tar xzf node_exporter-1.9.0.linux-amd64.tar.gz
sudo cp node_exporter-1.9.0.linux-amd64/node_exporter /usr/local/bin/
sudo tee /etc/systemd/system/node_exporter.service > /dev/null << 'EOF'
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
Verificar que o node_exporter está a exportar métricas: curl -s http://localhost:9100/metrics | head -20. O output deve mostrar linhas começadas com # HELP, # TYPE e métricas como node_cpu_seconds_total.
Instalar o Grafana
O Grafana corre como serviço web na porta 3000 por defeito. A instalação via repositório oficial garante actualizações automáticas Grafana docs.
Debian/Ubuntu:
sudo apt install -y apt-transport-https software-properties-common wget
sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install -y grafana
sudo systemctl enable --now grafana-server
RHEL/Rocky/Alma:
sudo tee /etc/yum.repos.d/grafana.repo > /dev/null << 'EOF'
[grafana]
name=grafana
baseurl=https://rpm.grafana.com
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://rpm.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
EOF
sudo dnf install -y grafana
sudo systemctl enable --now grafana-server
Após arrancar, aceder a http://localhost:3000. As credenciais por defeito são admin / admin. O Grafana pede para alterar a password no primeiro login.
Configurar Datasource e Dashboard no Grafana
O Grafana precisa de saber onde estão as métricas. Adicionar o Prometheus como datasource é o primeiro passo. Depois, importar um dashboard pronto evita construir gráficos do zero.
Passo 1 — Adicionar datasource Prometheus:
- No Grafana, ir a Connections → Data sources → Add data source.
- Seleccionar Prometheus.
- Em URL, inserir
http://localhost:9090(ou o IP do servidor Prometheus). - Clicar em Save & test. O Grafana deve mostrar "Data source is working".
Passo 2 — Importar um dashboard pronto:
A comunidade Grafana mantém dashboards prontos. O dashboard Node Exporter Full (ID 1860) é o mais popular para métricas de sistema Linux Grafana dashboards.
- No Grafana, ir a Dashboards → New → Import.
- Inserir o ID 1860 e clicar em Load.
- Seleccionar o datasource Prometheus criado no passo 1.
- Clicar em Import. O dashboard mostra CPU, memória, disco, rede e muito mais.
Consultas PromQL Essenciais
PromQL é a linguagem de consulta do Prometheus. Não é SQL — é uma linguagem funcional optimizada para séries temporais. Estas são as consultas mais úteis para monitorização de servidores Linux.
| Métrica | Consulta PromQL | Descrição |
|---|---|---|
| CPU usage (%) | 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) | Percentagem de CPU usada nos últimos 5 min |
| Memória disponível | node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 | Percentagem de memória disponível |
| Disco usado (%) | 100 - (node_filesystem_avail_bytes / node_filesystem_size_bytes * 100) | Percentagem de disco usado por mount point |
| Tráfego de rede | rate(node_network_receive_bytes_total[5m]) | Bytes recebidos por segundo (rx) |
| Uptime | node_time_seconds - node_boot_time_seconds | Segundos desde o último boot |
A função rate() é fundamental — converte counters (que só aumentam) em taxas por segundo. Sem rate(), um counter de CPU é inútil porque só mostra o total acumulado desde o boot.
Configurar Alertas no Prometheus
Os alertas permitem receber notificações quando uma métrica ultrapassa um limiar. No Prometheus, os alertas definem-se num ficheiro de regras (rule file) e são avaliados pelo próprio Prometheus. Para enviar notificações (email, Slack, etc.), é necessário o Alertmanager, mas neste artigo ficamos pelas regras e pelo estado dos alertas visível no próprio Prometheus Prometheus alerting docs.
Criar o ficheiro de regras de alerta:
sudo tee /etc/prometheus/alert_rules.yml > /dev/null << 'EOF'
groups:
- name: servidor_linux
rules:
- alert: HighCpuUsage
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "CPU acima de 80% em {{ $labels.instance }}"
description: "Uso de CPU é {{ $value }}% nos últimos 5 minutos."
- alert: HighMemoryUsage
expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "Memória acima de 85% em {{ $labels.instance }}"
description: "Uso de memória é {{ $value }}%."
- alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100 < 10
for: 10m
labels:
severity: critical
annotations:
summary: "Espaço em disco abaixo de 10% em {{ $labels.instance }}"
description: "Mount point {{ $labels.mountpoint }} tem {{ $value }}% livre."
EOF
Activar o ficheiro de regras no prometheus.yml (descomentar a linha rule_files) e recarregar a configuração:
# Editar prometheus.yml e garantir que rule_files inclui o ficheiro:
# rule_files:
# - "alert_rules.yml"
# Validar a configuração antes de recarregar
sudo -u prometheus /usr/local/bin/promtool check config /etc/prometheus/prometheus.yml
# Recarregar sem reiniciar o serviço (se o Prometheus tiver --web.enable-lifecycle)
curl -X POST http://localhost:9090/-/reload
# Alternativa: reiniciar o serviço
sudo systemctl restart prometheus
Os alertas activos ficam visíveis em http://localhost:9090/alerts. A cláusula for: 5m significa que o alerta só dispara se a condição se mantiver durante 5 minutos consecutivos — evita falsos positivos por picos momentâneos.
Alertas no Grafana
O Grafana tem o seu próprio sistema de alertas, independente das regras do Prometheus. A vantagem é que os alertas do Grafana podem incluir notificações directas para email, Slack, Discord ou webhook sem precisar do Alertmanager Grafana alerting docs.
- No Grafana, ir a Alerting → Alert rules → New alert rule.
- Definir a consulta PromQL (por exemplo, a de CPU acima de 80%).
- Definir a condição (threshold):
WHEN last() OF query IS ABOVE 80. - Configurar o contact point (email, Slack, webhook) em Alerting → Contact points.
- Guardar e testar o alerta com o botão Test rule.
Erros Comuns
| Problema | Causa | Solução |
|---|---|---|
| Prometheus mostra targets como "DOWN" | node_exporter não está a correr ou firewall bloqueia porta 9100 | Verificar systemctl status node_exporter e abrir a porta 9100 no firewall |
| Grafana: "Data source is not working" | URL do Prometheus incorrecto ou Prometheus inacessível | Confirmar que http://IP_DO_PROMETHEUS:9090 responde e que o Grafana consegue chegar ao Prometheus |
| Dashboard sem dados | Datasource não seleccionado ou métricas com nomes diferentes | Verificar o datasource do dashboard em Settings → Variables; validar nomes das métricas em http://localhost:9090/api/v1/label/__name__/values |
| Alertas não disparam | Cláusula for: demasiado longa ou expressão PromQL errada |
Testar a expressão em http://localhost:9090/graph; reduzir for: para 1m temporariamente |
| Prometheus consome muito disco | Retenção sem limite ou demasiados exporters | Definir --storage.tsdb.retention.time=15d e --storage.tsdb.retention.size=10GB no ExecStart |
Firewall e Segurança
Por defeito, o Prometheus escuta em 0.0.0.0:9090 e o Grafana em 0.0.0.0:3000. Ambos expõem interfaces web sem autenticação forte por defeito (Prometheus não tem autenticação nativa). É essencial proteger estas portas com firewall e, idealmente, colocar um reverse proxy com autenticação à frente.
Abrir apenas as portas necessárias (iptables/nftables ou UFW/firewalld):
# UFW (Debian/Ubuntu) — restringir acesso ao Prometheus e Grafana a uma rede interna
sudo ufw allow from 192.168.1.0/24 to any port 9090 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 3000 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 9100 proto tcp
# firewalld (RHEL/Rocky/Alma) — zona interna
sudo firewall-cmd --permanent --zone=internal --add-rich-rule='rule family=ipv4 source=192.168.1.0/24 port port=9090 protocol=tcp accept'
sudo firewall-cmd --permanent --zone=internal --add-rich-rule='rule family=ipv4 source=192.168.1.0/24 port port=3000 protocol=tcp accept'
sudo firewall-cmd --permanent --zone=internal --add-rich-rule='rule family=ipv4 source=192.168.1.0/24 port port=9100 protocol=tcp accept'
sudo firewall-cmd --reload
Checklist de Verificação
Antes de considerar a stack de monitorização pronta para produção, verificar cada ponto:
- Prometheus a correr:
systemctl status prometheusmostra active (running). - Targets acessíveis:
http://localhost:9090/targetsmostra todos os endpoints como UP. - node_exporter exporta métricas:
curl -s http://localhost:9100/metrics | grep node_cpudevolve linhas. - Grafana acessível:
http://localhost:3000carrega o login e a password foi alterada. - Datasource configurado: Grafana → Connections → Data sources mostra Prometheus com estado "Connected".
- Dashboard importado: Dashboard ID 1860 mostra gráficos com dados (não vazios).
- Regras de alerta activas:
http://localhost:9090/ruleslista as regras sem erros. - Firewall configurado: Portas 9090, 3000 e 9100 só acessíveis a partir de redes internas.
- Retenção definida: Prometheus tem
--storage.tsdb.retention.timeconfigurado para evitar disco cheio. - Serviços arrancam no boot:
systemctl is-enabled prometheus grafana-server node_exporterdevolve "enabled" para os três.
Artigos Relacionados
- Dia 7: Systemd no Linux — Services, Timers e journalctl — Os serviços do Prometheus e Grafana são geridos pelo systemd; este artigo explica a base.
- Dia 9: Firewalls Linux — iptables, nftables, UFW e firewalld — A protecção das portas do Prometheus e Grafana baseia-se nos conceitos deste artigo.
- Dia 8: Redes Linux — ip, ss, nmcli e DNS — Compreender a conectividade de rede é essencial para que o Prometheus chegue aos exporters remotos.
- Dia 14: Backups e Recuperação em Linux — Os dados do Prometheus em /var/lib/prometheus devem fazer parte da estratégia de backup.
- Dia 21: Docker — Containers e Volumes — Prometheus, Grafana e node_exporter também podem correr em containers; este artigo cobre o Docker.
- Dia 26: Logs Centralizados — rsyslog, journald e Loki — Monitorização de métricas (este artigo) complementa-se com logs centralizados (Dia 26).