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ć
Note

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:

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" } }

Gdy aktywny jest W3C Trace Context, obok standardowych pól dołączane są trace_id i span_id:

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" } }

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:

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

Cel 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:

bash
ACCESS_LOG=all
Logi 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:

bash
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ą:

bash
TRACE_CONTEXT=true

Upewnij się też, że Twój klient nadrzędny lub load balancer wysyła nagłówek traceparent w żądaniach.

Przykład 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"

Dobre praktyki

  • Używaj ACCESS_LOG=error na 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ż