Monitoring PHP Applications: Metrics and Alerts from A to Z
\n\nIn modern web development, application stability and performance are not just a wish, but a critical requirement. PHP, despite its maturity, requires close attention to monitoring. Without it, you risk learning about a site outage from users rather than from an alerting system. In this article, we will break down how to build a full-fledged monitoring system for a PHP application: from collecting key metrics to setting up alerts that will save your project from downtime.
\n\nWhy Monitor PHP? Key Metrics
\n\nMonitoring allows you to answer three main questions: "Is the application working?", "How fast is it working?" and "Is anything anomalous happening?". For PHP applications, the following groups of metrics are critically important:
\n\n- \n
- Availability Metrics (Uptime): Checking that the web server and PHP-FPM respond to requests. The simplest way is a health check endpoint. \n
- Performance Metrics: Request execution time (Response Time), throughput (Requests per Second), database and external API response times. \n
- Resource Metrics: Memory Usage, CPU load, number of active PHP-FPM processes. \n
- Error Metrics: Number of HTTP errors (5xx, 4xx), exceptions, fatal errors, and warnings. \n
- Business Metrics: Order checkout speed, number of registrations — anything important for your business. \n
You can collect these metrics in various ways: from simple file logging to using advanced observability systems like Prometheus + Grafana or commercial solutions (Datadog, New Relic).
\n\nCollecting Metrics: From Simple to Complex
\n\nLet's start with a basic approach — creating a simple health check and collecting metrics in Prometheus format.
\n\n1. Health Check endpoint
\nCreate a simple endpoint that checks the database and cache connection:
\n\n<?php\n// health.php\n$checks = [\n 'database' => false,\n 'redis' => false,\n 'status' => 'unhealthy'\n];\n\ntry {\n new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');\n $checks['database'] = true;\n} catch (PDOException $e) {\n // Log the error\n}\n\nif ($checks['database'] && $checks['redis']) {\n $checks['status'] = 'healthy';\n http_response_code(200);\n} else {\n http_response_code(503);\n}\n\nheader('Content-Type: application/json');\necho json_encode($checks);\n\n\n2. Collecting Metrics for Prometheus
\nPrometheus is a popular metrics collection system. Your application should expose data in the /metrics format. Example of a simple exporter:
<?php\n// metrics.php\nheader('Content-Type: text/plain; version=0.0.4');\n\n$metrics = [];\n\n// Request counter\n$metrics[] = '# HELP http_requests_total Total number of HTTP requests.';\n$metrics[] = '# TYPE http_requests_total counter';\n$metrics[] = 'http_requests_total{method="GET",route="/home"} 1024';\n\n// Response time histogram\n$metrics[] = '# HELP http_request_duration_seconds Request duration in seconds.';\n$metrics[] = '# TYPE http_request_duration_seconds histogram';\n$metrics[] = 'http_request_duration_seconds_bucket{le="0.1"} 500';\n$metrics[] = 'http_request_duration_seconds_bucket{le="0.5"} 800';\n$metrics[] = 'http_request_duration_seconds_bucket{le="+Inf"} 1024';\n\n// PHP metrics (memory, time)\n$metrics[] = '# HELP php_memory_bytes Current memory usage.';\n$metrics[] = '# TYPE php_memory_bytes gauge';\n$metrics[] = 'php_memory_bytes ' . memory_get_usage(true);\n\necho implode("\\n", $metrics) . "\\n";\n\n\nSetting Up Alerts: When and How to Notify
\n\nMetrics without alerts are just numbers. Alerts should be configured based on thresholds. Basic rules:
\n\n<