Monitoreo y Observabilidad en WordPress: Logs, Métricas y Alertas con Prometheus
Cuando un sitio WordPress crece en tráfico, complejidad o número de plugins, el enfoque reactivo de «esperar a que el usuario reporte un error» se vuelve insostenible. La observabilidad WordPress no es un lujo, es una necesidad para mantener la estabilidad, el rendimiento y la seguridad. En este artÃculo, exploraremos cómo implementar un stack completo de monitoreo WordPress utilizando Prometheus, Grafana y un sistema de alertas WordPress inteligentes. Dejaremos atrás los paneles básicos de cPanel y nos sumergiremos en métricas reales, logs estructurados y alertas proactivas.
¿Por qué Prometheus y Grafana para WordPress?
Prometheus es un sistema de monitoreo y alerta de código abierto diseñado para entornos dinámicos y orientados a microservicios. Sin embargo, su modelo de recolección pull y su potente lenguaje de consulta (PromQL) lo hacen ideal para monitorizar servidores web, bases de datos y aplicaciones como WordPress.
Grafana, por su parte, es la capa de visualización. Conecta múltiples fuentes de datos (Prometheus, Loki para logs, y bases de datos SQL) y permite construir dashboards interactivos.
[INFO] A diferencia de soluciones como New Relic o Datadog, Prometheus + Grafana es 100% autogestionado, sin costes de licencia por host y con control total sobre los datos. Ideal para agencias y empresas con múltiples sitios WordPress.
Componentes clave de la observabilidad WordPress
La observabilidad se compone de tres pilares: logs, métricas y trazas. En este artÃculo nos centraremos en logs y métricas, que son los más accesibles para un stack WordPress.
1. Métricas de rendimiento (Prometheus + Node Exporter + WordPress Exporter)
Las métricas son datos numéricos agregados en intervalos de tiempo. Para WordPress necesitamos:
- Métricas del servidor: CPU, RAM, disco, E/S, conexiones de red.
- Métricas de PHP-FPM: procesos activos, memoria por worker, colas.
- Métricas de MySQL/MariaDB: consultas por segundo, conexiones activas, tamaño de la base de datos.
- Métricas de WordPress: número de visitas, tiempo de carga de páginas, consultas a la base de datos por página, uso de caché, estado de plugins/transients.
Herramientas necesarias:
- Node Exporter: expone métricas del sistema operativo.
- PHP-FPM Exporter: expone métricas del pool PHP.
- mysqld_exporter: expone métricas de MySQL.
- WordPress Exporter (por ejemplo,
wp-prometheusplugin o un script personalizado): expone métricas especÃficas de WordPress.
2. Logs estructurados (Loki o ELK)
Los logs de WordPress tradicionales (debug.log, access.log, error.log) son texto plano y difÃciles de analizar a escala. Para lograr observabilidad WordPress real, debemos centralizarlos y estructurarlos.
Solución recomendada: Loki (de Grafana Labs) + Promtail. Loki es un sistema de agregación de logs diseñado para trabajar con Prometheus, indexando metadatos en lugar del contenido completo, lo que lo hace ligero y económico.
Configuración básica:
- Instalar Promtail en cada servidor WordPress.
- Configurar Promtail para leer los logs de Nginx/Apache y el
debug.logde WordPress. - Enviar logs a Loki.
- Visualizar logs en Grafana con consultas LogQL.
3. Alertas proactivas (Alertmanager)
Alertmanager gestiona las alertas generadas por Prometheus. Permite silenciar, agrupar y enrutar alertas a canales como Slack, Telegram, correo o PagerDuty.
Implementación paso a paso
Paso 1: Instalación de Prometheus y Node Exporter
Asumimos un servidor Ubuntu 22.04 con WordPress corriendo.
# Instalar Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.47.0/prometheus-2.47.0.linux-amd64.tar.gz
tar xvf prometheus-2.47.0.linux-amd64.tar.gz
sudo mv prometheus-2.47.0.linux-amd64 /etc/prometheus
sudo useradd --no-create-home --shell /bin/false prometheus
sudo chown -R prometheus:prometheus /etc/prometheus
# Instalar Node Exporter
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.0/node_exporter-1.6.0.linux-amd64.tar.gz
tar xvf node_exporter-1.6.0.linux-amd64.tar.gz
sudo mv node_exporter-1.6.0.linux-amd64/node_exporter /usr/local/bin/
sudo useradd --no-create-home --shell /bin/false node_exporter
sudo node_exporter & # o crear systemd service
Configurar /etc/prometheus/prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
- job_name: 'wordpress'
static_configs:
- targets: ['localhost:9101'] # Puerto del exporter WordPress
- job_name: 'mysql'
static_configs:
- targets: ['localhost:9104']
Paso 2: Exponer métricas de WordPress con un plugin personalizado
No existe un plugin oficial de Prometheus para WordPress, pero podemos crear un endpoint simple que exponga métricas clave. Creamos un plugin llamado wp-prometheus-exporter.
<?php
/*
Plugin Name: WP Prometheus Exporter
Description: Expone métricas de WordPress para Prometheus.
*/
add_action('rest_api_init', function () {
register_rest_route('metrics/v1', '/prometheus', array(
'methods' => 'GET',
'callback' => 'wp_prometheus_metrics',
'permission_callback' => '__return_true',
));
});
function wp_prometheus_metrics() {
global $wpdb;
header('Content-Type: text/plain; charset=utf-8');
$metrics = [];
// Número de posts publicados
$posts_count = wp_count_posts()->publish;
$metrics[] = '# HELP wp_posts_published Número de posts publicados.';
$metrics[] = '# TYPE wp_posts_published gauge';
$metrics[] = "wp_posts_published $posts_count";
// Consultas a la base de datos en la última página cargada
$queries = get_num_queries();
$metrics[] = '# HELP wp_db_queries Número de consultas SQL en la última petición.';
$metrics[] = '# TYPE wp_db_queries gauge';
$metrics[] = "wp_db_queries $queries";
// Tiempo de carga de la página (si tienes un timer)
$timer = timer_stop();
$metrics[] = '# HELP wp_page_load_time Tiempo de carga de la página en segundos.';
$metrics[] = '# TYPE wp_page_load_time gauge';
$metrics[] = "wp_page_load_time $timer";
// Transients caducados
$expired = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->options WHERE option_name LIKE '_transient_timeout_%' AND option_value < UNIX_TIMESTAMP()");
$metrics[] = '# HELP wp_expired_transients Transients caducados en la base de datos.';
$metrics[] = '# TYPE wp_expired_transients gauge';
$metrics[] = "wp_expired_transients $expired";
return implode("\n", $metrics);
}
[WARNING] Este endpoint es público. Protégelo con autenticación básica o un token secreto en producción. Puedes usar
permission_callbackcon una función personalizada.
Añadir el scrape en Prometheus:
- job_name: 'wordpress'
metrics_path: /wp-json/metrics/v1/prometheus
static_configs:
- targets: ['midominio.com']
scheme: https
basic_auth:
username: 'prometheus'
password: 'misecreto'
Paso 3: Centralizar logs con Loki y Promtail
Instalamos Loki y Promtail en el servidor:
# Descargar Loki y Promtail
wget https://github.com/grafana/loki/releases/download/v2.9.0/loki-linux-amd64.zip
unzip loki-linux-amd64.zip
sudo mv loki-linux-amd64 /usr/local/bin/loki
sudo mkdir /etc/loki
sudo nano /etc/loki/loki-config.yaml
Configuración básica de Loki:
auth_enabled: false
server:
http_listen_port: 3100
ingester:
lifecycler:
address: 127.0.0.1
ring:
kvstore:
store: inmemory
replication_factor: 1
final_sleep: 0s
chunk_idle_period: 5m
chunk_retain_period: 30s
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /data/loki/boltdb-shipper-active
cache_location: /data/loki/boltdb-shipper-cache
cache_ttl: 24h
shared_store: filesystem
filesystem:
directory: /data/loki/chunks
compactor:
working_directory: /data/loki/compactor
Configuración de Promtail para leer logs de WordPress:
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://localhost:3100/loki/api/v1/push
scrape_configs:
- job_name: nginx
static_configs:
- targets: ['localhost']
labels:
job: nginx
__path__: /var/log/nginx/access.log
pipeline_stages:
- regex:
expression: '^(?P<client_ip>\S+) \S+ \S+ \[(?P<timestamp>[^\]]+)\] "(?P<method>\S+) (?P<path>\S+) \S+" (?P<status>\d+) (?P<size>\d+)'
- labels:
status:
method:
- job_name: wordpress_debug
static_configs:
- targets: ['localhost']
labels:
job: wordpress
__path__: /var/www/html/wp-content/debug.log
pipeline_stages:
- regex:
expression: '\[(?P<date>[^\]]+)\] (?P<type>[A-Z]+): (?P<message>.*)'
- labels:
type:
Paso 4: Configurar Grafana y crear dashboards
Instalamos Grafana:
sudo apt-get install -y software-properties-common
sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install grafana
sudo systemctl start grafana-server
Añadir fuentes de datos:
- Prometheus:
http://localhost:9090 - Loki:
http://localhost:3100
Crear dashboard de WordPress:
- Panel de métricas del servidor (CPU, RAM, disco) desde Node Exporter.
- Panel de PHP-FPM (procesos activos, memoria media).
- Panel de MySQL (conexiones, consultas lentas, tamaño BD).
- Panel de WordPress (posts publicados, consultas por página, tiempo de carga, transients caducados).
- Panel de logs (errores PHP, 404, patrones de ataque).
Paso 5: Alertas inteligentes con Alertmanager
Creamos reglas de alerta en Prometheus. Ejemplo en /etc/prometheus/rules.yml:
groups:
- name: wordpress_alerts
rules:
- alert: WordPressHighDBQueries
expr: wp_db_queries > 500
for: 5m
labels:
severity: warning
annotations:
summary: "Alto número de consultas SQL ({{ $value }})"
description: "El número de consultas por página supera 500. Revisar plugins o consultas lentas."
- alert: WordPressExpiredTransients
expr: wp_expired_transients > 1000
for: 10m
labels:
severity: critical
annotations:
summary: "Transients caducados acumulados"
description: "Hay más de 1000 transients caducados. Ejecutar limpieza."
- alert: HighPHPFPMQueue
expr: phpfpm_processes_active > 10
for: 2m
labels:
severity: critical
annotations:
summary: "Cola PHP-FPM alta"
description: "Hay más de 10 procesos activos en la cola. Posible pico de tráfico o plugin bloqueante."
Configurar Alertmanager:
route:
receiver: 'slack-notifications'
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receivers:
- name: 'slack-notifications'
slack_configs:
- api_url: 'https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXX'
channel: '#alerts-wordpress'
send_resolved: true
title: '{{ .GroupLabels.alertname }}'
text: '{{ .CommonAnnotations.description }}'
[TIP] No alertes sobre todo. Prioriza métricas que tengan un impacto directo en la experiencia del usuario o en la estabilidad del servidor. Empieza con 5-10 alertas bien definidas.
Buenas prácticas para la observabilidad WordPress
1. Monitoreo de plugins y temas
Los plugins mal optimizados son la principal causa de lentitud en WordPress. Usa métricas como wp_db_queries y wp_page_load_time para detectar regresiones tras actualizaciones.
2. Logs de seguridad
Centraliza los logs de intentos de login fallidos (Wordfence, Limit Login Attempts) en Loki. Crea una alerta que se active si hay más de 50 intentos fallidos en 5 minutos.
3. Métricas de caché
Si usas Redis o Varnish, expón métricas de caché (hit rate, tamaño, expiraciones). Una caÃda en el hit rate puede indicar problemas de configuración.
4. Alertas sobre el estado de los plugins
Monitorea la versión de los plugins y el núcleo de WordPress. Si un plugin tiene una vulnerabilidad conocida (CVE), la alerta debe llegar al equipo de seguridad.
Conclusión
Implementar un stack de monitoreo WordPress con Prometheus, Grafana y alertas WordPress proactivas transforma la manera en que gestionas tus sitios. Pasas de apagar incendios a prevenir incendios. La observabilidad WordPress te permite entender el comportamiento de tu aplicación en profundidad, detectar anomalÃas antes de que afecten a los usuarios y tomar decisiones basadas en datos reales.
No necesitas ser un experto en DevOps para empezar. Con los pasos descritos, puedes tener un sistema funcional en un par de horas. A medida que crezcas, añadirás más exportadores, dashboards más complejos y alertas más inteligentes.
[INFO] Recuerda que la observabilidad no es un proyecto de una sola vez. Es un proceso continuo de mejora. Revisa tus dashboards semanalmente, ajusta umbrales de alerta y añade nuevas métricas según evolucione tu WordPress.
¿Listo para dejar de reaccionar y empezar a observar? Tu WordPress y tus usuarios te lo agradecerán.
