Rejestrowanie dostępu
OxPHP emituje ustrukturyzowane logi dostępu w formacie JSON dla każdego żądania HTTP, zapisywane na stdout. Rejestrowanie jest asynchroniczne, więc nigdy nie blokuje obsługi żądań.
Jak to działa
Gdy ustawiona jest zmienna ACCESS_LOG, OxPHP zapisuje na stdout jedną linię JSON po każdym zakończonym żądaniu. Zapisy te są buforowane w wątku zapisującym działającym w tle, więc rejestrowanie nigdy nie blokuje potoku żądań.
Tryb decyduje o tym, co jest zapisywane. ACCESS_LOG=all rejestruje każde żądanie; ACCESS_LOG=error rejestruje tylko odpowiedzi ze statusem 400 lub wyższym.
Każda linia logu zawiera pole request_id, które łączy wpisy logu dostępu z logami Twojej aplikacji. Gdy włączona jest propagacja W3C Trace Context, wpisy zawierają dodatkowo pola trace_id i span_id.
Konfiguracja
| Zmienna | Domyślnie | Opis |
|---|---|---|
ACCESS_LOG |
(nieustawiona) | Tryb logu dostępu. all rejestruje każde żądanie; error rejestruje tylko odpowiedzi 4xx i 5xx. Pozostaw nieustawioną lub pustą, aby wyłączyć |
Jedyne akceptowane wartości to all i error. Ustawienie nierozpoznanej wartości powoduje zapisanie ostrzeżenia i wyłączenie rejestrowania dostępu.
Format logu
Każdy wpis logu dostępu to pojedyncza linia JSON zapisywana na 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"
}
}Gdy aktywny jest W3C Trace Context, obok standardowych pól dołączane są trace_id i span_id:
{
"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"
}
}Pola
| Pole | Typ | Opis |
|---|---|---|
request_id |
string | Unikalny identyfikator żądania. Zobacz ID żądań |
method |
string | Metoda HTTP (GET, POST itd.) |
path |
string | Ścieżka URI żądania |
status |
number | Kod statusu odpowiedzi HTTP |
duration_us |
number | Całkowity czas obsługi żądania w mikrosekundach |
remote_ip |
string | Adres IP klienta (bez portu). Gdy skonfigurowano TRUSTED_PROXIES, pokazuje rzeczywisty adres IP klienta wyodrębniony z nagłówków przekazujących, a nie adres IP proxy |
trace_id |
string | ID śledzenia W3C (obecne tylko gdy TRACE_CONTEXT=true) |
span_id |
string | ID spanu W3C (obecne tylko gdy TRACE_CONTEXT=true) |
Filtrowanie szczegółowe
OxPHP używa wewnętrznego celu logowania access_log dla wpisów logu dostępu. Użyj zmiennej RUST_LOG, aby filtrować logi dostępu niezależnie od pozostałego wyjścia logów:
# Suppress general info messages, keep access logs
RUST_LOG=warn,access_log=infoCel access_log jest używany do filtrowania przez RUST_LOG, ale nie jest zawarty w wyjściu JSON. Aby zidentyfikować wpisy logu dostępu w systemach docelowych, użyj pola "message": "request completed" oraz charakterystycznego zestawu pól (method, path, status, duration_us).
Rozwiązywanie problemów
Nie pojawiają się żadne wpisy logu dostępu
Rejestrowanie dostępu jest wyłączone, gdy ACCESS_LOG jest nieustawiona lub pusta.
Rozwiązanie: ustaw zmienną na all lub error:
ACCESS_LOG=allLogi dostępu pokazują tryb `error`, ale brakuje udanych żądań
ACCESS_LOG=error rejestruje tylko odpowiedzi ze statusem 400 lub wyższym. Jest to działanie zamierzone — sprawdź wartość i przełącz na all, jeśli potrzebujesz rejestrowania wszystkich żądań.
Sprawdzenie: potwierdź aktywne ustawienie:
curl -s http://localhost:9090/config | jq '.access_log'Wpisy logu pojawiają się bez `trace_id` i `span_id`
Pola kontekstu śledzenia są obecne tylko wtedy, gdy włączona jest propagacja W3C Trace Context.
Rozwiązanie: włącz ją za pomocą:
TRACE_CONTEXT=trueUpewnij się też, że Twój klient nadrzędny lub load balancer wysyła nagłówek traceparent w żądaniach.
Przykład 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"Dobre praktyki
- Używaj
ACCESS_LOG=errorna produkcji, aby zmniejszyć objętość logów, wciąż przechwytując wszystkie nieudane żądania. Udane żądania nie są rejestrowane, ale błędy o dowolnym statusie 400+ są zawsze przechwytywane. - Dołączaj ID żądania do logów swojej aplikacji za pomocą
oxphp_request_id(), aby móc korelować wpisy logów na poziomie PHP z wpisami logu dostępu. - Używaj ustrukturyzowanego agregatora logów, takiego jak Elasticsearch, Loki czy Datadog, aby efektywnie odpytywać i filtrować linie logów JSON.
Integracja
Ponieważ logi są liniami JSON na stdout, integrują się bezpośrednio ze sterownikami logów kontenerów i narzędziami do agregacji:
- Docker — zbierane automatycznie przez sterownik logów kontenera (json-file, fluentd i inne)
- Kubernetes — przechwytywane przez agenta logów węzła (Fluentd, Fluent Bit, Filebeat i inne)
- systemd — przechwytywane podczas uruchomienia jako usługa systemd z logowaniem stdout przez journald
Nie jest potrzebny żaden sidecar ani przesyłanie logów oparte na plikach.
Zobacz też
- ID żądań — każdy wpis logu zawiera
request_iddo śledzenia - Dokumentacja konfiguracji — pełny wykaz zmiennych środowiskowych