Introducción: del healthcheck básico a la observabilidad profunda
\nEl monitoreo básico de aplicaciones PHP, que incluye la verificación de disponibilidad (healthcheck) y la carga de CPU, es el mínimo que se debe configurar en primer lugar. Sin embargo, para sistemas en producción con alta carga y lógica de negocio compleja, esto no es suficiente. El monitoreo avanzado cambia el enfoque de «vivo/muerto» a la observabilidad y permite responder preguntas como: «¿Por qué cayó la conversión?», «¿Qué endpoint específico ralentizó el trabajo?», «¿Cuántos usuarios no pudieron completar el pago?».
\nEn este artículo, exploraremos la arquitectura del monitoreo avanzado de aplicaciones PHP, aprenderemos a recopilar métricas personalizadas (incluyendo métricas de negocio), configuraremos alertas basadas en anomalías e integraremos todo en un panel unificado de Grafana. Todos los ejemplos de código están escritos en PHP y listos para su implementación.
\n\n1. Arquitectura de recopilación de métricas: Prometheus y exportadores personalizados
\nEl estándar moderno de facto para la recopilación de métricas es Prometheus con el modelo pull. La aplicación PHP no está obligada a entregar métricas directamente en el puerto /metrics. En su lugar, utilizamos un exportador personalizado: un script independiente que consulta la aplicación (a través de Redis, BD o archivo) y genera una respuesta en el formato de Prometheus.
\n\n1.1. Instalación del cliente Prometheus para PHP
\nLa biblioteca recomendada es promphp/prometheus_client_php. Instalación a través de Composer:
composer require promphp/prometheus_client_php\n\n1.2. Ejemplo de exportador de métricas (metrics.php)
\nCrearemos un script que devuelva métricas en formato Prometheus. Para el almacenamiento utilizaremos Redis (bandera PERSISTENT para producción).
<?php\nrequire 'vendor/autoload.php';\n\nuse Prometheus\\CollectorRegistry;\nuse Prometheus\\Storage\\Redis;\nuse Prometheus\\RenderTextFormat;\n\n// Conexión a Redis\nRedis::setDefaultOptions(['host' => '127.0.0.1', 'port' => 6379]);\n$registry = new CollectorRegistry(new Redis());\n\n// Registramos un histograma para el tiempo de respuesta\n$histogram = $registry->getOrRegisterHistogram(\n 'app_http_request_duration_seconds',\n 'HTTP request duration in seconds',\n ['method', 'endpoint', 'status']\n);\n\n// Registramos un contador de métrica de negocio\n$counter = $registry->getOrRegisterCounter(\n 'app_orders_total',\n 'Total number of orders processed',\n ['status'] // success, failed\n);\n\n// Simulación de datos (en la realidad se lee de BD o logs)\n$histogram->observe(0.12, ['GET', '/api/orders', '200']);\n$counter->incBy(1, ['success']);\n\n// Entregamos las métricas\n$renderer = new RenderTextFormat();\nheader('Content-Type: text/plain');\necho $renderer->render($registry->getMetricFamilySamples());\n\nLuego configuramos Nginx o Apache para que este script sea accesible en la ruta /metrics, y agregamos el target en Prometheus.
2. Métricas de negocio: monitoreo de lo que realmente importa
\nLas métricas técnicas (latencia, tasa de error) son la base, pero las métricas de negocio brindan comprensión de la salud del producto. Ejemplos de estas métricas:
\n- \n
- Cantidad de pedidos exitosos por minuto — una caída señala problemas con la pasarela de pago. \n
- Tiempo promedio de finalización del carrito — un aumento puede indicar una regresión en el código. \n
- Porcentaje de abandonos de registro — si aumenta bruscamente, es posible que el formulario se haya roto. \n
2.1. Integración de métricas de negocio en el código de la aplicación
\nUsamos el mismo prometheus_client_php, pero envolvemos las llamadas en middleware o en la capa de servicio. Ejemplo para Laravel:
<?php\nnamespace App\\Http\\Middleware;\n\nuse Closure;\nuse Prometheus\\CollectorRegistry;\n\nclass MetricsMiddleware\n{\n protected $registry;\n\n public function __construct(CollectorRegistry $registry)\n {\n $this->registry = $registry;\n }\n\n publi