Metryki Prometheus

OxPHP udostępnia metryki zgodne z Prometheus w tekstowym formacie ekspozycji pod GET /metrics na serwerze wewnętrznym. Obejmują one przepustowość żądań, czasy odpowiedzi, stan połączeń, kondycję puli workerów, buforowanie plików statycznych, wydajność kompresji oraz wydajność trybu worker.

Włączanie metryk

Ustaw INTERNAL_ADDR, aby uruchomić serwer wewnętrzny:

bash
INTERNAL_ADDR=127.0.0.1:9090

Następnie zbieraj dane z Prometheusa lub dowolnego kompatybilnego kolektora:

bash
curl http://localhost:9090/metrics

Metryki serwera

Metric Type Description
oxphp_uptime_seconds gauge Liczba sekund od uruchomienia procesu serwera
oxphp_requests_total counter Łączna liczba żądań HTTP odebranych na porcie głównym

Metryki żądań

Metric Type Description
oxphp_requests_by_method_total counter Żądania według metody HTTP. Etykieta: method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, QUERY, OTHER)
oxphp_responses_by_status_total counter Odpowiedzi według klasy statusu. Etykieta: status (1xx, 2xx, 3xx, 4xx, 5xx)
oxphp_request_bytes_total counter Łączna liczba odebranych bajtów treści żądań
oxphp_response_bytes_total counter Łączna liczba wysłanych bajtów treści odpowiedzi
oxphp_request_cancelled_total counter Anulowane żądania według przyczyny. Etykieta: reason (client_abort, timeout, shutdown). Zawsze emitowana
Note

Emitowane są tylko metody i klasy statusów, dla których zarejestrowano co najmniej jedno zdarzenie. Etykiety o zerowej liczbie są pomijane.

Histogram czasu trwania żądania

Metric Type Description
oxphp_request_duration_us histogram Czas trwania żądania end-to-end w mikrosekundach dla wszystkich żądań (pliki statyczne i PHP)

Granice przedziałów (mikrosekundy): 100, 500, 1000, 2500, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000, +Inf.

Użyj tego histogramu, aby śledzić ogólne opóźnienia, identyfikować wolne endpointy i mierzyć percentyle opóźnień ogona.

Metryki połączeń

Metric Type Description
oxphp_active_connections gauge Aktualnie otwarte połączenia TCP na porcie głównym
oxphp_pending_requests gauge Żądania PHP przyjęte, ale jeszcze bez odpowiedzi — czekające na miejsce w kolejce, w kolejce albo wykonywane. Tylko żądania skierowane do PHP: plik statyczny, 404 lub odrzucona ścieżka są obsługiwane bez kolejki i nigdy się tu nie pojawiają
oxphp_dropped_requests_total counter Żądania, w których worker PHP zawiódł po przyjęciu żądania
oxphp_admission_refused_total counter Żądania, na które odpowiedziano bez dotarcia do workera. Etykieta: reasonwait_timeout (odczekało pełne QUEUE_WAIT_TIMEOUT_MS, daj puli więcej zapasu), waiting_full (czekało już QUEUE_MAX_WAITING żądań, podnieś tę wartość lub MAX_CONNECTIONS), waiting_bytes (już zaparkowane ciała wypełniają QUEUE_MAX_WAITING_BYTES, więc ciało tego żądania nie miało gdzie się zmieścić — podnieś tę wartość albo obniż, ile klient może wysłać), queue_full (QUEUE_WAIT_TIMEOUT_MS=0, oczekiwanie jest wyłączone), shutting_down (termin wygaszania minął, gdy żądanie wciąż czekało na przyjęcie), pool_unavailable (nie został żaden wątek workera, któremu można przekazać żądanie — pula zniknęła, a nie jest zajęta). Tylko cztery pierwsze oznaczają przeciążenie i odpowiadają 529; shutting_down odpowiada 503 jak reszta łagodnego wygaszania, a pool_unavailable odpowiada 500. Alertuj o przeciążeniu konkretnie na tych czterech: metryka jako całość rośnie też przy restarcie. Wyłączone z oxphp_queue_wait_us

Metryki puli workerów

Metric Type Description
oxphp_workers_current gauge Bieżąca liczba wątków workerów PHP
oxphp_workers_min gauge Minimalna liczba workerów (równa liczbie bieżącej w trybie statycznym)
oxphp_workers_max gauge Maksymalna liczba workerów (równa liczbie bieżącej w trybie statycznym)
oxphp_workers_idle gauge Wątki workerów bez żadnego żądania w toku, obliczane jako workers_current - busy_workers
oxphp_busy_workers gauge Wątki workerów wykonujące aktualnie co najmniej jedno żądanie; nigdy nie przekracza oxphp_workers_current. Liczy wątki, nie żądania — w trybie worker jeden wątek multipleksuje wiele fiberów żądań i wciąż liczy się raz. Żądania czekające na przyjęcie lub siedzące w kolejce nie są liczone; te pojawiają się w oxphp_pending_requests
oxphp_workers_spawned_total counter Łączna liczba workerów utworzonych od uruchomienia (wliczając workery początkowe)
oxphp_workers_retired_total counter Łączna liczba workerów wycofanych z powodu limitu czasu bezczynności (tylko tryb dynamiczny)

Metryki nadzorcy workerów

Obserwowalność na poziomie pojedynczego workera emitowana przez nadzorcę workerów. Każda seria niesie etykietę worker_id (indeks slotu). Pojawiają się one, gdy nadzorca śledzi stan poszczególnych workerów.

Metric Type Description
oxphp_worker_request_age_seconds gauge Wiek żądania w trakcie realizacji na każdym workerze, w sekundach. Etykieta: worker_id
oxphp_worker_long_running_total counter Skany nadzorcy, które zaobserwowały żądanie starsze niż próg zablokowania. Etykieta: worker_id
oxphp_worker_stuck_total counter Licznik klasyfikacji zablokowania na workera. Etykiety: worker_id, kind (io, c_call, cpu)

Histogram czasu oczekiwania w kolejce

Metric Type Description
oxphp_queue_wait_us histogram Czas, przez jaki żądanie czeka w kolejce, zanim podejmie je worker, w mikrosekundach

Granice przedziałów (mikrosekundy): 50, 100, 250, 500, 1000, 2500, 5000, 10000, 50000, 100000, 250000, 500000, 1000000, +Inf.

Metryka mierzy czas spędzony na oczekiwaniu — na przyjęcie, a potem w kolejce — z odjętym czasem wykonania samego skryptu, więc odpowiada na pytanie „ile czasu minęło, zanim worker to podjął", a nie „ile trwało żądanie". Żądania odrzucone z 529 nigdy nie trafiły do kolejki i nie są tu rejestrowane; licz je metryką oxphp_admission_refused_total.

Wysokie czasy oczekiwania w kolejce wskazują, że wszystkie workery są zajęte i należy zwiększyć PHP_WORKERS. Zakres sięga jednej sekundy, odpowiadając domyślnemu QUEUE_WAIT_TIMEOUT_MS, więc żądanie, które przed uruchomieniem zużyło większość swojego budżetu oczekiwania, zostaje policzone, a nie wrzucone do +Inf. Nic, co zostaje obsłużone, nie czeka dłużej niż budżet — po jego przekroczeniu żądanie jest odrzucane — więc podniesienie QUEUE_WAIT_TIMEOUT_MS to jedyne ustawienie, które z powrotem wprowadza oczekiwania do +Inf.

Metryki ograniczania liczby żądań

Metric Type Description
oxphp_rate_limited_total counter Żądania odrzucone przez ogranicznik liczby żądań (zwrócono 429)
oxphp_php_deny_total counter Żądania zablokowane przez PHP_DENY_PATHS (odmowa wykonania .php). Zobacz Lista blokowania wykonywania PHP

Metryki pamięci podręcznej plików statycznych

Metric Type Description
oxphp_static_cache_hits_total counter Żądania plików statycznych obsłużone z pamięci podręcznej w pamięci operacyjnej
oxphp_static_cache_misses_total counter Żądania plików statycznych, które wymagały odczytu z dysku

Metryki kompresji

Metric Type Description
oxphp_compressed_responses_total counter Odpowiedzi skompresowane algorytmem Brotli
oxphp_compression_bytes_saved_total counter Łączna liczba bajtów zaoszczędzonych dzięki kompresji (rozmiar oryginalny minus rozmiar skompresowany)

Metryki trybu worker

Te metryki są emitowane tylko wtedy, gdy tryb worker jest aktywny (WORKER_MODE_ENABLED=true).

Liczniki globalne

Metric Type Description
oxphp_worker_mode_enabled gauge Zawsze 1, gdy tryb worker jest aktywny
oxphp_worker_requests_handled_total counter Łączna liczba żądań przetworzonych przez trwałe workery
oxphp_worker_recycles_total counter Łączna liczba recyklingów workerów (worker zakończył działanie i został ponownie uruchomiony)
oxphp_worker_recycles_by_reason_total counter Recyklingi według przyczyny. Etykieta: reason (scheduled, max_memory, error)
oxphp_worker_soft_resets_total counter Łączna liczba miękkich resetów wykonanych pomiędzy żądaniami

Wskaźniki na poziomie workera

Metric Type Description
oxphp_worker_memory_bytes gauge Bieżące zużycie sterty PHP na workera. Etykieta: worker (indeks slotu, np. "0", "1")
oxphp_worker_uptime_seconds gauge Liczba sekund od utworzenia każdego workera. Etykieta: worker
oxphp_worker_requests_count gauge Liczba żądań obsłużonych przez każdą instancję workera. Etykieta: worker

Histogram czasu trwania żądania workera

Metric Type Description
oxphp_worker_request_duration_us histogram Czas wykonania handlera PHP na żądanie w mikrosekundach (tylko tryb worker)

Granice przedziałów (mikrosekundy): 100, 250, 500, 1000, 2500, 5000, 10000, 25000, 50000, +Inf.

Ten histogram mierzy czas spędzony wewnątrz callbacka handlera PHP, z wyłączeniem czasu oczekiwania w kolejce. Użyj go, aby identyfikować wolne handlery i śledzić opóźnienia ogona w trybie worker.

Metryki puli asynchronicznej

Te metryki wymagają ustawienia ASYNC_WORKERS na wartość niezerową, a każda ma własną bramkę emisji: liczniki pojawiają się dopiero po tym, jak co najmniej jedno zadanie zostało wysłane lub odrzucone, wskaźniki _in_flight / _in_flight_limit pojawiają się, gdy pula podłączy swój licznik zadań w trakcie realizacji, a oxphp_async_output_discarded_bytes_total pojawia się dopiero po odrzuceniu jakiegoś wyjścia.

Metric Type Description
oxphp_async_tasks_dispatched_total counter Łączna liczba zadań asynchronicznych wysłanych do puli w tle
oxphp_async_tasks_completed_total counter Zadania asynchroniczne, które zakończyły się pomyślnie
oxphp_async_tasks_failed_total counter Zadania asynchroniczne, które rzuciły wyjątek
oxphp_async_tasks_cancelled_total counter Zadania asynchroniczne, które zostały anulowane
oxphp_async_tasks_rejected_total counter Zadania asynchroniczne odrzucone przy wysyłaniu — ponieważ kolejka puli była pełna lub osiągnięto limit zadań w trakcie realizacji (ASYNC_MAX_FIBERS × ASYNC_WORKERS)
oxphp_async_tasks_stranded_total counter Workery pozostawione działające po upływie limitu czasu await_race / await_any. Każde osierocone zadanie może wydłużyć RSHUTDOWN nawet o 5 sekund.
oxphp_async_tasks_in_flight gauge Zadania asynchroniczne aktualnie w kolejce lub uruchomione (emitowane, gdy pula podłączy swój licznik zadań w trakcie realizacji)
oxphp_async_tasks_in_flight_limit gauge Maksymalna liczba równoczesnych zadań asynchronicznych (ASYNC_MAX_FIBERS × ASYNC_WORKERS)
oxphp_async_output_discarded_bytes_total counter Bajty wyjścia zadań asynchronicznych odrzucone przy bezczynności workera (echo w zadaniu asynchronicznym nie ma klienta, który mógłby je odebrać)

Wskazówki do dashboardu Grafany

Poniższe zapytania PromQL są przydatne przy budowaniu dashboardów:

Częstotliwość żądań (żądania na sekundę):

text
rate(oxphp_requests_total[5m])

Średni czas odpowiedzi (milisekundy):

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

Czas trwania żądania p99 (milisekundy):

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

Częstotliwość błędów (odpowiedzi 5xx jako procent):

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

Wykorzystanie puli workerów:

text
oxphp_busy_workers / oxphp_workers_current

To prawdziwy ułamek między 0 a 1. Utrzymujące się wartości równe 1 oznaczają, że każdy worker jest zajęty, a kolejne nadchodzące żądania ustawiają się w kolejce. Zestaw go z rate(oxphp_admission_refused_total{reason=~"queue_full|wait_timeout|waiting_full|waiting_bytes"}[5m]), aby zobaczyć, czy ta zaległość zamienia się w odmowy, oraz z oxphp_pending_requests, aby zobaczyć, jak jest głęboka.

Nasycenie kolejki (częstotliwość odrzuceń na sekundę):

text
rate(oxphp_dropped_requests_total[5m])

Czas oczekiwania w kolejce p99 (mikrosekundy):

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

Współczynnik trafień pamięci podręcznej plików statycznych:

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

Bajty zaoszczędzone dzięki kompresji na sekundę:

text
rate(oxphp_compression_bytes_saved_total[5m])

Opóźnienie p99 trybu worker (mikrosekundy):

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

Częstotliwość recyklingu workerów (na minutę):

text
rate(oxphp_worker_recycles_total[5m]) * 60

Średnie zużycie pamięci przez workera:

text
avg(oxphp_worker_memory_bytes)

Konfiguracja scrape'owania Prometheus

Dodaj zadanie scrape'owania do swojego pliku prometheus.yml:

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

Dla wykrywania usług w 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"

Zobacz również

Znalazłeś błąd? Zgłoś go →