Prometheus & Grafana: Observabilidad, Telemetría Tri-Motor & Horizon
La suite de observabilidad de Mañuti centraliza métricas de infraestructura física, el clúster transaccional relacional, la memoria volátil de Redis, la persistencia documental de MongoDB y la salud de los procesos en segundo plano de Laravel Horizon y Laravel Reverb.
Mediante Prometheus (como motor de recolección TSDB mediante sondeo periódico) y Grafana OSS (como interfaz analítica y de tableros ejecutivos), se obtiene visibilidad en tiempo real de latencias P95/P99, saturación de CPU/RAM, desalojo de llaves y contención de hilos.
flowchart BT
GRAFANA["Grafana OSS Visualization<br/>(Dashboard UI :3000)"]
PROM["Prometheus Core TSDB Server<br/>(Daemon :9090)"]
NODE["Node Exporter<br/>(OS/Host)"]
MYSQL["MySQL Exporter<br/>(MariaDB L7)"]
REDIS["Redis Exporter<br/>(Cache/Locks)"]
MONGO["Mongo Exporter<br/>(Auditoría)"]
APP["Laravel App<br/>Horizon/Reverb"]
PROM -->|"Consultas PromQL"| GRAFANA
NODE -->|":9100<br/>(Pull 15s)"| PROM
MYSQL -->|":9104<br/>(Pull 15s)"| PROM
REDIS -->|":9121<br/>(Pull 15s)"| PROM
MONGO -->|":9216<br/>(Pull 15s)"| PROM
APP -->|":80 /metrics<br/>(Pull 10s)"| PROM
1. Matriz de Componentes, Puertos y Dashboards Oficiales
| Componente | Puerto | Protocolo | Métrica Crítica / Utilidad | ID Dashboard Oficial |
|---|---|---|---|---|
| Node Exporter | 9100 |
HTTP / Text | Saturación CPU, RAM, I/O Disco y Tráfico de Red. | 1860 / 15172 |
| mysqld_exporter | 9104 |
HTTP / Text | Queries/sec, Conexiones abiertas, InnoDB Buffer Pool. | 14057 |
| redis_exporter | 9121 |
HTTP / Text | Consumo de RAM, Comandos/seg, Tasa de Desalojo (Key Eviction). | 11835 |
| mongodb_exporter | 9216 |
HTTP / Text | Operaciones OpCounters (Auditoría Forense), Bloqueos wiredTiger. | 12079 / 20867 |
| Laravel App / Horizon | 80 |
HTTP / Endpoint | Jobs procesados, Jobs fallidos, Longitud de colas, Sockets Reverb. | 12105 / 11034 |
2. Instalación del Servidor Central: Prometheus & Grafana
Ejecutar en el servidor designado para monitoreo y analítica (Ubuntu 24.04 LTS):
2.1 Aprovisionamiento de Prometheus y Node Exporter Base
sudo apt update && sudo apt upgrade -y
sudo apt install -y prometheus prometheus-node-exporter
# Verificar arranque de Prometheus (:9090) y Node Exporter (:9100)
sudo systemctl enable --now prometheus prometheus-node-exporter
ss -antpl | grep -E '9090|9100'
2.2 Aprovisionamiento de Grafana OSS
# 1. Importar llave GPG del repositorio oficial de Grafana Labs
sudo mkdir -p /etc/apt/keyrings
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
# 2. Añadir repositorio APT oficial
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
# 3. Instalación e inicio del servicio
sudo apt update
sudo apt install -y grafana
sudo systemctl daemon-reload
sudo systemctl enable --now grafana-server
# Verificar puerto 3000
ss -antpl | grep 3000
3. Despliegue de Exportadores del Stack Tri-Motor
3.1 MariaDB / MySQL Exporter (mysqld_exporter v0.15+)
A. Creación del Usuario de Monitoreo en MariaDB
sudo mariadb -u root -p
-- Usuario de lectura técnica con concurrencia restringida
CREATE USER 'exporter_user'@'localhost' IDENTIFIED BY 'ExporterSecurePass_2025!' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
B. Binario y Configuración Segura
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.15.0/mysqld_exporter-0.15.0.linux-amd64.tar.gz
tar -xzvf mysqld_exporter-0.15.0.linux-amd64.tar.gz
sudo mv mysqld_exporter-0.15.0.linux-amd64/mysqld_exporter /usr/local/bin/
rm -rf mysqld_exporter*
# Archivo de credenciales protegido
sudo tee /etc/.mysqld_exporter.cnf <<EOF
[client]
user=exporter_user
password=ExporterSecurePass_2025!
EOF
sudo chmod 600 /etc/.mysqld_exporter.cnf
sudo chown prometheus:prometheus /etc/.mysqld_exporter.cnf
C. Servicio Systemd (/etc/systemd/system/mysql_exporter.service)
[Unit]
Description=Prometheus MySQL Exporter
After=network.target
[Service]
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/mysqld_exporter \
--config.my-cnf=/etc/.mysqld_exporter.cnf \
--collect.info_schema.innodb_metrics \
--collect.engine_innodb_status \
--collect.info_schema.processlist \
--collect.info_schema.tablestats
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now mysql_exporter
3.2 Redis Exporter (prometheus-redis-exporter)
Monitorea la saturación de memoria de sesiones de usuario y el canal Pub/Sub de Laravel Reverb:
sudo apt install -y prometheus-redis-exporter
sudo systemctl enable --now prometheus-redis-exporter
# Si Redis requiere autenticación (requirepass), editar /etc/default/prometheus-redis-exporter:
# REDIS_ADDR="redis://:[email protected]:6379"
# Verificar puerto 9121
ss -antpl | grep 9121
3.3 MongoDB Exporter (mongodb_exporter v0.40+)
Monitorea la colección documental de auditoria y system_errors:
A. Creación de Usuario en MongoDB
// En mongosh:
use admin
db.createUser({
user: "exporter_user",
pwd: "MongoExporterSecurePass_2025!",
roles: [
{ role: "clusterMonitor", db: "admin" },
{ role: "read", db: "local" }
]
})
B. Instalación del Binario
wget https://github.com/percona/mongodb_exporter/releases/download/v0.40.0/mongodb_exporter-0.40.0.linux-amd64.tar.gz
tar -xzvf mongodb_exporter-0.40.0.linux-amd64.tar.gz
sudo mv mongodb_exporter-0.40.0.linux-amd64/mongodb_exporter /usr/local/bin/
rm -rf mongodb_exporter*
C. Servicio Systemd (/etc/systemd/system/mongodb_exporter.service)
[Unit]
Description=Prometheus MongoDB Exporter
After=network.target
[Service]
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/mongodb_exporter \
--mongodb.uri=mongodb://exporter_user:[email protected]:27017/admin
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now mongodb_exporter
ss -antpl | grep 9216
4. Telemetría de Laravel Horizon & WebSockets Reverb
Para exponer las métricas internas de jobs, colas y sockets, el aplicativo Mañuti implementa el paquete spatie/laravel-prometheus:
composer require spatie/laravel-prometheus
php artisan vendor:publish --provider="Spatie\Prometheus\PrometheusServiceProvider"
4.1 Configuración de Colectores (config/prometheus.php)
return [
'enabled' => true,
'url' => 'prometheus/metrics',
'collectors' => [
// Orquestador de Colas y Workers Horizon
Spatie\Prometheus\Collectors\Horizon\HorizonCollector::class,
// Métricas de Almacenamiento y Caché
Spatie\Prometheus\Collectors\General\StorageCollector::class,
],
];
5. Configuración Unificada de Scraping (/etc/prometheus/prometheus.yml)
El servidor Prometheus sondea todos los objetivos de la topología local o distribuida:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
# 1. Sistema Operativo del Servidor
- job_name: 'node_exporter'
static_configs:
- targets: ['localhost:9100']
# 2. Motor Transaccional MariaDB
- job_name: 'mariadb'
static_configs:
- targets: ['localhost:9104']
# 3. Caché y Sesiones Redis
- job_name: 'redis'
static_configs:
- targets: ['localhost:9121']
# 4. Logs de Auditoría Forense MongoDB
- job_name: 'mongodb'
static_configs:
- targets: ['localhost:9216']
# 5. Core Mañuti (Laravel Horizon & Workers)
- job_name: 'manuti_app'
metrics_path: '/prometheus/metrics'
static_configs:
- targets: ['localhost:80']
# Validar sintaxis y reiniciar Prometheus
promtool check config /etc/prometheus/prometheus.yml
sudo systemctl restart prometheus
6. Configuración de Grafana y Aprovisionamiento de Paneles
6.1 Vinculación del Data Source
- Acceder vía navegador a
http://IP_SERVIDOR:3000(Credenciales iniciales:admin/admin). - Navegar a Connections > Data Sources > Add data source.
- Seleccionar Prometheus.
- Establecer URL:
http://localhost:9090. - Clic en Save & Test (Confirmar check verde de disponibilidad).
6.2 Importación de Dashboards Recomendados
Navegar a Dashboards > New > Import e ingresar los siguientes IDs oficiales:
- Host Linux Full (ID:
1860o15172): Visibilidad de núcleos CPU, saturación de RAM, I/O Wait y discos NVMe. - MySQL / MariaDB Overview (ID:
14057): Peticiones por segundo, slow queries, uso del Buffer Pool de InnoDB. - Redis Dashboard (ID:
11835): Monitoreo de memoria consumida vs asignada y desalojo de llaves (evicted_keys). - MongoDB Performance (ID:
12079): Ratios de lectura/escritura en colecciones de auditoría forense. - Laravel Horizon Metrics (ID:
12105o11034): Estado de colas (wait_time), jobs en ejecución y errores transitorios.
7. Reglas de Alerta Críticas de Producción (/etc/prometheus/alert.rules.yml)
groups:
- name: ManutiCriticalAlerts
rules:
# Alerta: Servidor de base de datos caído
- alert: DatabaseServiceDown
expr: mysql_up == 0 or mongodb_up == 0
for: 30s
labels:
severity: disaster
annotations:
summary: "Instancia transaccional o documental caída en Mañuti."
# Alerta: Desalojo crítico en Redis
- alert: RedisEvictingKeys
expr: rate(redis_evicted_keys_total[1m]) > 0
for: 1m
labels:
severity: critical
annotations:
summary: "Redis está destruyendo llaves por saturación de RAM. Aumente maxmemory."
# Alerta: Colas de Horizon atascadas
- alert: HorizonQueueBacklogHigh
expr: horizon_queue_jobs_count{queue="default"} > 1000
for: 5m
labels:
severity: warning
annotations:
summary: "Acumulación anormal de más de 1,000 jobs en la cola default."