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 |
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 :
{
"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 :
{
"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 :
# Suppress general info messages, keep access logs
RUST_LOG=warn,access_log=infoLa 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 :
ACCESS_LOG=allLes 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 :
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 :
TRACE_CONTEXT=trueEt 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
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=erroren 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
- ID de requête — chaque entrée de journal inclut un
request_idpour le traçage - Référence de configuration — référence complète des variables d'environnement