Advanced PHP Application Monitoring: Metrics and Alerts

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: From Basic Healthcheck to Deep Observability

\n

Basic monitoring of PHP applications, including availability checks (healthcheck) and CPU load, is the minimum that needs to be configured first. However, for production systems with high load and complex business logic, this is not enough. Advanced monitoring shifts the focus from "alive/dead" to observability and allows answering questions like: "Why did conversion drop?", "Which specific endpoint slowed down?", "How many users failed to complete payment?".

\n

In this article, we will explore the architecture of advanced PHP application monitoring, learn how to collect custom metrics (including business metrics), configure anomaly-based alerts, and integrate everything into a single Grafana dashboard. All code examples are written in PHP and ready for implementation.

\n\n

1. Metrics Collection Architecture: Prometheus and Custom Exporters

\n

The modern de facto standard for metrics collection is Prometheus with a pull model. A PHP application does not have to directly expose metrics on the /metrics port. Instead, we use a custom exporter — a separate script that polls the application (via Redis, DB, or file) and generates a response in Prometheus format.

\n\n

1.1. Installing the Prometheus Client for PHP

\n

The recommended library is promphp/prometheus_client_php. Install via Composer:

\n
composer require promphp/prometheus_client_php
\n\n

1.2. Example Metrics Exporter (metrics.php)

\n

Let's create a script that returns metrics in Prometheus format. We'll use Redis for storage (the PERSISTENT flag for production).

\n
<?php\nrequire 'vendor/autoload.php';\n\nuse Prometheus\\CollectorRegistry;\nuse Prometheus\\Storage\\Redis;\nuse Prometheus\\RenderTextFormat;\n\n// Connect to Redis\nRedis::setDefaultOptions(['host' => '127.0.0.1', 'port' => 6379]);\n$registry = new CollectorRegistry(new Redis());\n\n// Register a histogram for response time\n$histogram = $registry->getOrRegisterHistogram(\n    'app_http_request_duration_seconds',\n    'HTTP request duration in seconds',\n    ['method', 'endpoint', 'status']\n);\n\n// Register a business metric counter\n$counter = $registry->getOrRegisterCounter(\n    'app_orders_total',\n    'Total number of orders processed',\n    ['status'] // success, failed\n);\n\n// Simulate data (in reality, read from DB or logs)\n$histogram->observe(0.12, ['GET', '/api/orders', '200']);\n$counter->incBy(1, ['success']);\n\n// Output metrics\n$renderer = new RenderTextFormat();\nheader('Content-Type: text/plain');\necho $renderer->render($registry->getMetricFamilySamples());\n
\n

Then configure Nginx or Apache to make this script accessible at the /metrics path, and add the target to Prometheus.

\n\n

2. Business Metrics: Monitoring What Really Matters

\n

Technical metrics (latency, error rate) are the foundation, but business metrics provide insight into product health. Examples of such metrics:

\n
    \n
  • Number of successful orders per minute — a drop signals problems with the payment gateway.
  • \n
  • Average cart processing time — an increase may indicate a code regression.
  • \n
  • Registration abandonment rate — if it spikes, the form might be broken.
  • \n
\n\n

2.1. Integrating Business Metrics into Application Code

\n

We use the same prometheus_client_php, but wrap the calls in middleware or a service layer. Example for Laravel:

\n
<?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                

Blogs

Book Recommendations