Métriques Prometheus

OxPHP expose des métriques compatibles Prometheus au format d'exposition texte via GET /metrics sur le serveur interne. Elles couvrent le débit des requêtes, les temps de réponse, l'état des connexions, la santé du pool de workers, la mise en cache des fichiers statiques, l'efficacité de la compression et les performances du mode worker.

Activation des métriques

Définissez INTERNAL_ADDR pour démarrer le serveur interne :

bash
INTERNAL_ADDR=127.0.0.1:9090

Ensuite, effectuez le scraping depuis Prometheus ou tout collecteur compatible :

bash
curl http://localhost:9090/metrics

Métriques du serveur

Métrique Type Description
oxphp_uptime_seconds gauge Secondes écoulées depuis le démarrage du processus serveur
oxphp_requests_total counter Total des requêtes HTTP reçues sur le port principal

Métriques de requêtes

Métrique Type Description
oxphp_requests_by_method_total counter Requêtes par méthode HTTP. Label : method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, QUERY, OTHER)
oxphp_responses_by_status_total counter Réponses par classe de statut. Label : status (1xx, 2xx, 3xx, 4xx, 5xx)
oxphp_request_bytes_total counter Total des octets de corps de requête reçus
oxphp_response_bytes_total counter Total des octets de corps de réponse envoyés
oxphp_request_cancelled_total counter Requêtes annulées par raison. Label : reason (client_abort, timeout, shutdown). Toujours émise
Note

Seules les méthodes et classes de statut ayant au moins un événement enregistré sont émises. Les labels à valeur nulle sont omis.

Histogramme de durée de requête

Métrique Type Description
oxphp_request_duration_us histogram Durée de requête de bout en bout en microsecondes pour toutes les requêtes (fichiers statiques et PHP)

Limites des buckets (microsecondes) : 100, 500, 1000, 2500, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000, +Inf.

Utilisez cet histogramme pour suivre la latence globale, identifier les endpoints lents et mesurer les percentiles de latence de queue.

Métriques de connexion

Métrique Type Description
oxphp_active_connections gauge Connexions TCP actuellement ouvertes sur le port principal
oxphp_pending_requests gauge Requêtes PHP acceptées mais pas encore répondues — en attente d'une place dans la file, en file, ou en cours d'exécution. Uniquement les requêtes routées vers PHP : un fichier statique, une 404 ou un chemin refusé reçoit sa réponse sans passer par la file et n'apparaît jamais ici
oxphp_dropped_requests_total counter Requêtes pour lesquelles le worker PHP a échoué après avoir accepté la requête
oxphp_admission_refused_total counter Requêtes répondues sans atteindre un worker. Label : reasonwait_timeout (a attendu la totalité de QUEUE_WAIT_TIMEOUT_MS, donnez plus de marge au pool), waiting_full (déjà QUEUE_MAX_WAITING requêtes en attente, relevez-le ou relevez MAX_CONNECTIONS), waiting_bytes (les corps déjà stationnés remplissent QUEUE_MAX_WAITING_BYTES, le corps de cette requête n'avait donc nulle part où se poser — relevez-le, ou abaissez ce qu'un client peut téléverser), queue_full (QUEUE_WAIT_TIMEOUT_MS=0, l'attente est désactivée), shutting_down (le délai de drainage a expiré pendant que la requête attendait encore son admission), pool_unavailable (il ne reste aucun thread worker à qui remettre la requête — le pool a disparu, il n'est pas occupé). Seules les quatre premières relèvent de la surcharge et répondent 529 ; shutting_down répond 503 comme le reste du drainage progressif, et pool_unavailable répond 500. Alertez sur la surcharge avec ces quatre-là précisément : la métrique dans son ensemble bouge aussi lors d'un redémarrage. Exclues de oxphp_queue_wait_us

Métriques du pool de workers

Métrique Type Description
oxphp_workers_current gauge Nombre actuel de threads worker PHP
oxphp_workers_min gauge Nombre minimal de workers (égal au nombre actuel en mode statique)
oxphp_workers_max gauge Nombre maximal de workers (égal au nombre actuel en mode statique)
oxphp_workers_idle gauge Threads worker sans aucune requête en cours, calculé comme workers_current - busy_workers
oxphp_busy_workers gauge Threads worker exécutant actuellement au moins une requête ; ne dépasse jamais oxphp_workers_current. Compte des threads, pas des requêtes — en mode worker, un thread multiplexe de nombreuses Fibers de requête et ne compte qu'une fois. Les requêtes en attente d'admission ou assises dans la file ne sont pas comptées ; celles-là apparaissent dans oxphp_pending_requests
oxphp_workers_spawned_total counter Total des workers créés depuis le démarrage (inclut les workers initiaux)
oxphp_workers_retired_total counter Total des workers retirés en raison d'un délai d'inactivité (mode dynamique uniquement)

Métriques du superviseur de workers

Observabilité par worker émise par le superviseur de workers. Chaque série porte un label worker_id (index de slot). Ces métriques apparaissent une fois que le superviseur suit l'état de chaque worker.

Métrique Type Description
oxphp_worker_request_age_seconds gauge Âge de la requête en cours de traitement sur chaque worker, en secondes. Label : worker_id
oxphp_worker_long_running_total counter Analyses du superviseur ayant observé une requête plus ancienne que le seuil de blocage. Label : worker_id
oxphp_worker_stuck_total counter Compteur de classification de blocage par worker. Labels : worker_id, kind (io, c_call, cpu)

Histogramme d'attente en file

Métrique Type Description
oxphp_queue_wait_us histogram Temps qu'une requête attend dans la file avant qu'un worker ne la prenne en charge, en microsecondes

Limites des buckets (microsecondes) : 50, 100, 250, 500, 1000, 2500, 5000, 10000, 50000, 100000, 250000, 500000, 1000000, +Inf.

Ceci mesure le temps passé à attendre — pour l'admission puis dans la file — en soustrayant le temps d'exécution propre au script, si bien qu'il répond à « combien de temps avant qu'un worker ne prenne cette requête » plutôt qu'à « combien de temps la requête a-t-elle pris ». Les requêtes refusées avec un 529 n'ont jamais été mises en file et ne sont pas enregistrées ici ; comptez-les avec oxphp_admission_refused_total.

Des temps d'attente en file élevés indiquent que tous les workers sont occupés et que vous devriez augmenter PHP_WORKERS. La plage atteint une seconde, en accord avec le QUEUE_WAIT_TIMEOUT_MS par défaut, si bien qu'une requête qui a dépensé l'essentiel de son budget d'attente avant de s'exécuter est quantifiée plutôt que reléguée dans +Inf. Rien de ce qui est servi n'attend plus longtemps que le budget — au-delà, la requête est refusée — donc relever QUEUE_WAIT_TIMEOUT_MS est le seul réglage qui renvoie des attentes dans +Inf.

Métriques de limitation de débit

Métrique Type Description
oxphp_rate_limited_total counter Requêtes rejetées par le limiteur de débit (429 renvoyé)
oxphp_php_deny_total counter Requêtes bloquées par PHP_DENY_PATHS (exécution .php refusée). Voir Liste de refus d'exécution PHP

Métriques du cache de fichiers statiques

Métrique Type Description
oxphp_static_cache_hits_total counter Requêtes de fichiers statiques servies depuis le cache en mémoire
oxphp_static_cache_misses_total counter Requêtes de fichiers statiques ayant nécessité une lecture disque

Métriques de compression

Métrique Type Description
oxphp_compressed_responses_total counter Réponses compressées avec Brotli
oxphp_compression_bytes_saved_total counter Total des octets économisés par la compression (taille originale moins taille compressée)

Métriques du mode worker

Ces métriques ne sont émises que lorsque le mode worker est actif (WORKER_MODE_ENABLED=true).

Compteurs globaux

Métrique Type Description
oxphp_worker_mode_enabled gauge Toujours 1 lorsque le mode worker est actif
oxphp_worker_requests_handled_total counter Total des requêtes traitées par les workers persistants
oxphp_worker_recycles_total counter Total des recyclages de workers (un worker s'est arrêté et a été recréé)
oxphp_worker_recycles_by_reason_total counter Recyclages par raison. Label : reason (scheduled, max_memory, error)
oxphp_worker_soft_resets_total counter Total des réinitialisations souples effectuées entre les requêtes

Jauges par worker

Métrique Type Description
oxphp_worker_memory_bytes gauge Utilisation actuelle du tas PHP par worker. Label : worker (index de slot, p. ex. "0", "1")
oxphp_worker_uptime_seconds gauge Secondes écoulées depuis la création de chaque worker. Label : worker
oxphp_worker_requests_count gauge Requêtes traitées par chaque instance de worker. Label : worker

Histogramme de durée de requête des workers

Métrique Type Description
oxphp_worker_request_duration_us histogram Temps d'exécution du gestionnaire PHP par requête en microsecondes (mode worker uniquement)

Limites des buckets (microsecondes) : 100, 250, 500, 1000, 2500, 5000, 10000, 25000, 50000, +Inf.

Cet histogramme mesure le temps passé à l'intérieur du callback du gestionnaire PHP, hors temps d'attente en file. Utilisez-le pour identifier les gestionnaires lents et suivre la latence de queue en mode worker.

Métriques du pool asynchrone

Ces métriques nécessitent que ASYNC_WORKERS soit défini à une valeur non nulle, et chacune possède sa propre condition d'émission : les compteurs n'apparaissent qu'après qu'au moins une tâche a été distribuée ou rejetée, les jauges _in_flight / _in_flight_limit apparaissent une fois que le pool a câblé son compteur de tâches en cours, et oxphp_async_output_discarded_bytes_total n'apparaît qu'après que de la sortie a été rejetée.

Métrique Type Description
oxphp_async_tasks_dispatched_total counter Total des tâches asynchrones distribuées au pool d'arrière-plan
oxphp_async_tasks_completed_total counter Tâches asynchrones terminées avec succès
oxphp_async_tasks_failed_total counter Tâches asynchrones ayant levé une exception
oxphp_async_tasks_cancelled_total counter Tâches asynchrones annulées
oxphp_async_tasks_rejected_total counter Tâches asynchrones rejetées à la distribution — parce que la file du pool était pleine ou que le plafond de tâches en cours (ASYNC_MAX_FIBERS × ASYNC_WORKERS) était atteint
oxphp_async_tasks_stranded_total counter Workers laissés en exécution au-delà d'un délai d'expiration await_race / await_any. Chaque tâche abandonnée peut prolonger RSHUTDOWN jusqu'à 5 secondes.
oxphp_async_tasks_in_flight gauge Tâches asynchrones actuellement en file ou en cours d'exécution (émise une fois que le pool câble son compteur de tâches en cours)
oxphp_async_tasks_in_flight_limit gauge Nombre maximal de tâches asynchrones concurrentes (ASYNC_MAX_FIBERS × ASYNC_WORKERS)
oxphp_async_output_discarded_bytes_total counter Octets de sortie de tâche asynchrone rejetés à l'inactivité du worker (un echo dans une tâche asynchrone n'a aucun client pour le recevoir)

Conseils pour tableau de bord Grafana

Les requêtes PromQL suivantes sont utiles pour construire des tableaux de bord :

Taux de requêtes (requêtes par seconde) :

text
rate(oxphp_requests_total[5m])

Temps de réponse moyen (millisecondes) :

text
rate(oxphp_request_duration_us_sum[5m]) / rate(oxphp_requests_total[5m]) / 1000

Durée de requête p99 (millisecondes) :

text
histogram_quantile(0.99, rate(oxphp_request_duration_us_bucket[5m])) / 1000

Taux d'erreur (réponses 5xx en pourcentage) :

text
rate(oxphp_responses_by_status_total{status="5xx"}[5m]) / rate(oxphp_requests_total[5m]) * 100

Utilisation du pool de workers :

text
oxphp_busy_workers / oxphp_workers_current

C'est une vraie fraction entre 0 et 1. Des valeurs soutenues à 1 signifient que chaque worker est occupé et que les arrivées supplémentaires font la queue. Associez-la à rate(oxphp_admission_refused_total{reason=~"queue_full|wait_timeout|waiting_full|waiting_bytes"}[5m]) pour voir si cet arriéré se transforme en refus, et à oxphp_pending_requests pour en mesurer la profondeur.

Saturation de la file (taux d'abandon par seconde) :

text
rate(oxphp_dropped_requests_total[5m])

Attente en file p99 (microsecondes) :

text
histogram_quantile(0.99, rate(oxphp_queue_wait_us_bucket[5m]))

Taux de succès du cache de fichiers statiques :

text
rate(oxphp_static_cache_hits_total[5m]) / (rate(oxphp_static_cache_hits_total[5m]) + rate(oxphp_static_cache_misses_total[5m]))

Octets économisés par la compression par seconde :

text
rate(oxphp_compression_bytes_saved_total[5m])

Latence p99 en mode worker (microsecondes) :

text
histogram_quantile(0.99, rate(oxphp_worker_request_duration_us_bucket[5m]))

Taux de recyclage des workers (par minute) :

text
rate(oxphp_worker_recycles_total[5m]) * 60

Utilisation mémoire moyenne des workers :

text
avg(oxphp_worker_memory_bytes)

Configuration de scraping Prometheus

Ajoutez un job de scraping à votre prometheus.yml :

prometheus.yml
scrape_configs: - job_name: "oxphp" scrape_interval: 15s static_configs: - targets: ["oxphp:9090"]

Pour la découverte de services Kubernetes :

prometheus.yml
scrape_configs: - job_name: "oxphp" kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_app] regex: oxphp action: keep - source_labels: [__meta_kubernetes_pod_ip] target_label: __address__ replacement: "$1:9090"

Voir aussi

Une erreur ? Signalez-la →