Grafana: dashboards para Node.js e PostgreSQL
Grafana transforma métricas do Prometheus em dashboards visuais que revelam o comportamento da sua aplicação em tempo real. Um dashboard bem construído responde três perguntas de imediato: o sistema está saudável? onde está o gargalo? o que mudou agora? Este guia cobre a criação de painéis práticos para APIs Node.js em produção.
Instalar Grafana com Docker Compose
Stack Prometheus + Grafana com configuração mínima:
# docker-compose.yml:
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=30d'
ports:
- "127.0.0.1:9090:9090"
restart: unless-stopped
grafana:
image: grafana/grafana-oss:latest
container_name: grafana
environment:
GF_SECURITY_ADMIN_PASSWORD: "SUA_SENHA_FORTE"
GF_USERS_ALLOW_SIGN_UP: "false"
GF_SERVER_ROOT_URL: "https://grafana.seudominio.com.br"
GF_SMTP_ENABLED: "true"
GF_SMTP_HOST: "smtp.seudominio.com.br:587"
volumes:
- grafana-data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
ports:
- "127.0.0.1:3001:3000"
restart: unless-stopped
depends_on:
- prometheus
volumes:
prometheus-data:
grafana-data:
# prometheus.yml — scrape da API Node.js:
# scrape_configs:
# - job_name: 'nodejs-api'
# static_configs:
# - targets: ['host.docker.internal:3000']
# metrics_path: '/metrics'Dashboard de API Node.js: latência e throughput
Queries PromQL essenciais para monitorar uma API:
# Queries PromQL para painéis Grafana:
# 1. Throughput (req/s) — Rate de requisições por endpoint:
rate(http_request_duration_seconds_count{job="nodejs-api"}[5m])
# Por endpoint (top 10 mais chamados):
topk(10, sum by (route, method) (
rate(http_request_duration_seconds_count[5m])
))
# 2. Latência P50/P95/P99 — Percentis de tempo de resposta:
histogram_quantile(0.50, sum by (le, route) (
rate(http_request_duration_seconds_bucket{job="nodejs-api"}[5m])
))
histogram_quantile(0.95, sum by (le, route) (
rate(http_request_duration_seconds_bucket{job="nodejs-api"}[5m])
))
histogram_quantile(0.99, sum by (le) (
rate(http_request_duration_seconds_bucket{job="nodejs-api"}[5m])
))
# 3. Taxa de erro (% de 4xx e 5xx):
sum(rate(http_request_duration_seconds_count{status_code=~"[45].."}[5m]))
/
sum(rate(http_request_duration_seconds_count[5m])) * 100
# 4. Erros por endpoint (para identificar rotas problemáticas):
sum by (route, status_code) (
rate(http_request_duration_seconds_count{status_code=~"5.."}[5m])
)
# 5. Conexões ativas Node.js:
nodejs_active_handles_total{job="nodejs-api"}Painel de uso de recursos do sistema
Métricas do Node Exporter para CPU, memória e disco:
# Queries PromQL para recursos do servidor:
# CPU usage % (por core e total):
100 - (avg by (instance) (
rate(node_cpu_seconds_total{mode="idle"}[5m])
) * 100)
# Por modo (user/system/iowait):
sum by (mode) (
rate(node_cpu_seconds_total{instance="servidor:9100"}[5m])
) * 100
# Memória livre %:
(node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# Memória por componente (painel tipo "stack"):
node_memory_MemTotal_bytes - node_memory_MemFree_bytes
- node_memory_Buffers_bytes - node_memory_Cached_bytes
# Disco: uso % por filesystem:
(
node_filesystem_size_bytes{mountpoint="/"}
- node_filesystem_free_bytes{mountpoint="/"}
) / node_filesystem_size_bytes{mountpoint="/"} * 100
# I/O de disco (bytes/s):
rate(node_disk_read_bytes_total{device="sda"}[5m])
rate(node_disk_written_bytes_total{device="sda"}[5m])
# Rede (bytes/s por interface):
rate(node_network_receive_bytes_total{device="eth0"}[5m])
rate(node_network_transmit_bytes_total{device="eth0"}[5m])Painel PostgreSQL com postgres_exporter
Monitorar banco de dados PostgreSQL no Grafana:
# Instalar postgres_exporter:
# docker-compose.yml (adicionar ao stack):
postgres-exporter:
image: prometheuscommunity/postgres-exporter:latest
environment:
DATA_SOURCE_NAME: "postgresql://monitoring:senha@postgres:5432/mydb?sslmode=disable"
ports:
- "127.0.0.1:9187:9187"
# Queries PromQL para PostgreSQL:
# Conexões ativas vs máximo:
pg_stat_activity_count{datname="mydb", state="active"}
pg_settings_max_connections
# Transações por segundo:
rate(pg_stat_database_xact_commit{datname="mydb"}[5m])
rate(pg_stat_database_xact_rollback{datname="mydb"}[5m])
# Cache hit ratio (deve ficar acima de 99%):
pg_stat_database_blks_hit{datname="mydb"}
/ (
pg_stat_database_blks_hit{datname="mydb"}
+ pg_stat_database_blks_read{datname="mydb"}
) * 100
# Queries lentas (via pg_stat_statements):
pg_stat_statements_mean_time_seconds
# Ordenar por: topk(10, pg_stat_statements_mean_time_seconds)
# Tamanho do banco:
pg_database_size_bytes{datname="mydb"}
# Locks esperando:
pg_locks_count{mode="ExclusiveLock", granted="false"}Provisioning automático de dashboards
Versionar dashboards como código e carregar automaticamente:
# Estrutura de arquivos:
# grafana/
# provisioning/
# datasources/
# prometheus.yml → configurar Prometheus como datasource
# dashboards/
# dashboard.yml → apontar para pasta de JSON
# dashboards/
# nodejs-api.json → dashboard exportado
# grafana/provisioning/datasources/prometheus.yml:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false
# grafana/provisioning/dashboards/dashboard.yml:
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
disableDeletion: false
updateIntervalSeconds: 30
options:
path: /var/lib/grafana/dashboards
# Exportar dashboard existente como JSON:
# Grafana UI → Dashboard → Share → Export → Save to file
# Importar dashboard da comunidade (Grafana.com/dashboards):
# Dashboard ID 1860 → Node Exporter Full (métricas de sistema)
# Dashboard ID 11159 → Node.js Application Dashboard
# Dashboard ID 9628 → PostgreSQL Database
# API Grafana para importar via curl:
curl -X POST http://admin:senha@localhost:3001/api/dashboards/import -H 'Content-Type: application/json' -d '{"dashboard": {...}, "overwrite": true, "folderId": 0}'$ runstack deploy --plan starter
Não quer configurar manualmente?
Não quer configurar manualmente? Implante o VPS para Node.js em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.