Journalisation des accès

OxPHP émet des journaux d'accès JSON structurés pour chaque requête HTTP, écrits sur stdout. La journalisation est asynchrone, elle ne bloque donc jamais le traitement des requêtes.

Fonctionnement

Lorsque ACCESS_LOG est défini, OxPHP écrit une ligne JSON sur stdout après chaque requête terminée. Ces écritures sont mises en tampon dans un thread d'écriture en arrière-plan, si bien que la journalisation ne bloque jamais le pipeline de requêtes.

Le mode contrôle ce qui est enregistré. ACCESS_LOG=all journalise chaque requête ; ACCESS_LOG=error journalise uniquement les réponses dont le statut est 400 ou supérieur.

Chaque ligne de journal porte un champ request_id qui met en corrélation les entrées du journal d'accès avec les journaux de votre application. Lorsque la propagation W3C Trace Context est activée, les entrées incluent également les champs trace_id et span_id.

Configuration

Variable Par défaut Description
ACCESS_LOG (non défini) Mode de journalisation des accès. all journalise chaque requête ; error journalise uniquement les réponses 4xx et 5xx. Laissez la variable non définie ou vide pour désactiver
Note

Les seules valeurs acceptées sont all et error. Définir une valeur non reconnue génère un avertissement et désactive la journalisation des accès.

Format des journaux

Chaque entrée du journal d'accès est une unique ligne JSON écrite sur stdout :

json
{ "timestamp": "2026-02-11T12:34:56.789012Z", "level": "INFO", "fields": { "request_id": "67890abc12341a2b0042", "method": "GET", "path": "/api/users", "status": 200, "duration_us": 1234, "remote_ip": "10.0.0.1", "message": "request completed" } }

Lorsque W3C Trace Context est actif, trace_id et span_id sont inclus aux côtés des champs standard :

json
{ "timestamp": "2026-02-11T12:34:56.789012Z", "level": "INFO", "fields": { "request_id": "67890abc12341a2b0042", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "span_id": "00f067aa0ba902b7", "method": "POST", "path": "/api/orders", "status": 201, "duration_us": 8421, "remote_ip": "10.0.0.1", "message": "request completed" } }

Champs

Champ Type Description
request_id string Identifiant unique de requête. Voir ID de requête
method string Méthode HTTP (GET, POST, etc.)
path string Chemin de l'URI de la requête
status number Code de statut de la réponse HTTP
duration_us number Temps total de traitement de la requête en microsecondes
remote_ip string Adresse IP du client (sans port). Lorsque TRUSTED_PROXIES est configuré, affiche la véritable IP du client extraite des en-têtes de transfert, et non l'IP du proxy
trace_id string ID de trace W3C (présent uniquement lorsque TRACE_CONTEXT=true)
span_id string ID de span W3C (présent uniquement lorsque TRACE_CONTEXT=true)

Filtrage fin

OxPHP utilise la cible de journalisation interne access_log pour les entrées du journal d'accès. Utilisez la variable RUST_LOG pour filtrer les journaux d'accès indépendamment du reste de la sortie des journaux :

bash
# Suppress general info messages, keep access logs RUST_LOG=warn,access_log=info
Note

La cible access_log sert au filtrage RUST_LOG mais n'est pas incluse dans la sortie JSON. Pour identifier les entrées du journal d'accès dans les systèmes en aval, utilisez le champ "message": "request completed" et l'ensemble de champs caractéristique (method, path, status, duration_us).

Dépannage

Aucune entrée du journal d'accès n'apparaît

La journalisation des accès est désactivée lorsque ACCESS_LOG est non défini ou vide.

Correctif : définissez la variable sur all ou error :

bash
ACCESS_LOG=all
Les journaux d'accès affichent le mode `error` mais les requêtes réussies sont absentes

ACCESS_LOG=error ne journalise que les réponses dont le statut est 400 ou supérieur. C'est intentionnel — vérifiez la valeur et passez à all si vous avez besoin de journaliser toutes les requêtes.

Vérification : confirmez le paramètre actif :

bash
curl -s http://localhost:9090/config | jq '.access_log'
Les entrées de journal apparaissent sans `trace_id` ni `span_id`

Les champs de contexte de trace ne sont présents que lorsque la propagation W3C Trace Context est activée.

Correctif : activez-la avec :

bash
TRACE_CONTEXT=true

Et assurez-vous que votre client en amont ou votre répartiteur de charge envoie un en-tête traceparent sur les requêtes.

Exemple Docker

compose.yaml
services: app: image: ghcr.io/oxphp/oxphp:0.10.0 ports: - "80:80" - "9090:9090" volumes: - ./src:/var/www/html:ro environment: ACCESS_LOG: "all" ENTRY_FILE: "index.php" INTERNAL_ADDR: "0.0.0.0:9090"

Bonnes pratiques

  • Utilisez ACCESS_LOG=error en production pour réduire le volume des journaux tout en capturant toutes les requêtes en échec. Les requêtes réussies ne sont pas journalisées, mais les erreurs à tout statut 400+ sont toujours capturées.
  • Incluez l'ID de requête dans les journaux de votre application via oxphp_request_id() afin de pouvoir corréler les entrées de journal au niveau PHP avec les entrées du journal d'accès.
  • Utilisez un agrégateur de journaux structurés tel qu'Elasticsearch, Loki ou Datadog pour interroger et filtrer efficacement les lignes de journal JSON.

Intégration

Comme les journaux sont des lignes JSON sur stdout, ils s'intègrent directement avec les pilotes de journalisation de conteneurs et l'outillage d'agrégation :

  • Docker — collectés automatiquement via le pilote de journalisation du conteneur (json-file, fluentd, et autres)
  • Kubernetes — récupérés par l'agent de journalisation du nœud (Fluentd, Fluent Bit, Filebeat, et autres)
  • systemd — capturés lors de l'exécution en tant que service systemd avec journalisation stdout via journald

Aucun sidecar ni acheminement de journaux basé sur des fichiers n'est nécessaire.

Voir aussi