Prometheus メトリクス
OxPHP は、内部サーバーの GET /metrics で Prometheus 互換のメトリクスをテキスト表示形式(text exposition format)で公開します。これらのメトリクスは、リクエストのスループット、レスポンスタイム、コネクションの状態、ワーカープールの健全性、静的ファイルのキャッシュ、圧縮効率、ワーカーモードのパフォーマンスをカバーします。
メトリクスの有効化
内部サーバーを起動するには INTERNAL_ADDR を設定します。
INTERNAL_ADDR=127.0.0.1:9090その後、Prometheus または任意の互換コレクターからスクレイプします。
curl http://localhost:9090/metricsサーバーメトリクス
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_uptime_seconds |
gauge | サーバープロセスが起動してからの経過秒数 |
oxphp_requests_total |
counter | メインポートで受信した HTTP リクエストの総数 |
リクエストメトリクス
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_requests_by_method_total |
counter | HTTP メソッド別のリクエスト数。ラベル: method(GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, QUERY, OTHER) |
oxphp_responses_by_status_total |
counter | ステータスクラス別のレスポンス数。ラベル: status(1xx, 2xx, 3xx, 4xx, 5xx) |
oxphp_request_bytes_total |
counter | 受信したリクエストボディの総バイト数 |
oxphp_response_bytes_total |
counter | 送信したレスポンスボディの総バイト数 |
oxphp_request_cancelled_total |
counter | 理由別のキャンセルされたリクエスト数。ラベル: reason(client_abort, timeout, shutdown)。常に出力されます |
記録されたイベントが 1 つ以上あるメソッドおよびステータスクラスのみが出力されます。カウントがゼロのラベルは省略されます。
リクエスト処理時間のヒストグラム
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_request_duration_us |
histogram | すべてのリクエスト(静的ファイルと PHP)のエンドツーエンドのリクエスト処理時間(マイクロ秒) |
バケットの境界値(マイクロ秒): 100, 500, 1000, 2500, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000, +Inf。
このヒストグラムを使って、全体のレイテンシーを追跡し、遅いエンドポイントを特定し、テールレイテンシーのパーセンタイルを測定できます。
コネクションメトリクス
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_active_connections |
gauge | メインポートで現在オープンしている TCP コネクション数 |
oxphp_pending_requests |
gauge | 受け入れ済みでまだ応答されていない PHP リクエスト数 — キュースロット待ち、キュー内、または実行中。PHP へルーティングされたリクエストのみが対象です。静的ファイル、404、拒否されたパスはキューを経由せずに応答されるため、ここには決して現れません |
oxphp_dropped_requests_total |
counter | リクエストを受理した後に PHP ワーカーが失敗したリクエスト数 |
oxphp_admission_refused_total |
counter | ワーカーに到達しないまま応答されたリクエスト数。ラベル: reason — wait_timeout(QUEUE_WAIT_TIMEOUT_MS をまるごと待った。プールに余裕を持たせてください)、waiting_full(既に QUEUE_MAX_WAITING 件が待機中。その値か MAX_CONNECTIONS を引き上げてください)、waiting_bytes(既に待機中のボディが QUEUE_MAX_WAITING_BYTES を満たしており、このリクエストのボディの置き場がなかった。その値を引き上げるか、クライアントがアップロードできる量を減らしてください)、queue_full(QUEUE_WAIT_TIMEOUT_MS=0 で待機が無効)、shutting_down(受け入れ待ちの間にドレイン期限が過ぎた)、pool_unavailable(リクエストを渡すワーカースレッドが残っていない — プールがビジーなのではなく消滅している)。過負荷なのは最初の 4 つだけで 529 を返します。shutting_down はグレースフルドレインの他の部分と同じく 503 を、pool_unavailable は 500 を返します。過負荷のアラートはその 4 つを明示して設定してください。メトリクス全体は再起動でも動くからです。oxphp_queue_wait_us からは除外されます |
ワーカープールメトリクス
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_workers_current |
gauge | 現在の PHP ワーカースレッド数 |
oxphp_workers_min |
gauge | ワーカー数の最小値(静的モードでは現在の数と等しくなります) |
oxphp_workers_max |
gauge | ワーカー数の最大値(静的モードでは現在の数と等しくなります) |
oxphp_workers_idle |
gauge | 処理中のリクエストを持たないワーカースレッド数。workers_current - busy_workers として計算されます |
oxphp_busy_workers |
gauge | 現在少なくとも 1 つのリクエストを実行しているワーカースレッド数。oxphp_workers_current を超えることはありません。数えるのはスレッドであってリクエストではありません — ワーカーモードでは 1 つのスレッドが多数のリクエストファイバーを多重化しても 1 とカウントされます。受け入れ待ちやキュー内のリクエストはカウントされず、それらは oxphp_pending_requests に現れます |
oxphp_workers_spawned_total |
counter | 起動以降に生成されたワーカーの総数(初期ワーカーを含む) |
oxphp_workers_retired_total |
counter | アイドルタイムアウトにより終了したワーカーの総数(動的モードのみ) |
ワーカースーパーバイザーメトリクス
ワーカースーパーバイザーが出力するワーカーごとのオブザーバビリティです。各系列は worker_id ラベル(スロットのインデックス)を持ちます。これらはスーパーバイザーがワーカーごとの状態を追跡し始めると出力されます。
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_worker_request_age_seconds |
gauge | 各ワーカーで処理中のリクエストの経過時間(秒)。ラベル: worker_id |
oxphp_worker_long_running_total |
counter | スタック判定のしきい値を超えたリクエストを検出したスーパーバイザーのスキャン回数。ラベル: worker_id |
oxphp_worker_stuck_total |
counter | ワーカーごとのスタック分類カウンター。ラベル: worker_id, kind(io, c_call, cpu) |
キュー待機時間のヒストグラム
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_queue_wait_us |
histogram | ワーカーがリクエストを取り出すまでにキュー内で待機した時間(マイクロ秒) |
バケットの境界値(マイクロ秒): 50, 100, 250, 500, 1000, 2500, 5000, 10000, 50000, 100000, 250000, 500000, 1000000, +Inf。
これは待機に費やされた時間 — 受け入れ待ち、次いでキュー内 — を測るもので、スクリプト自身の実行時間は差し引かれます。つまり「リクエストにどれだけ時間がかかったか」ではなく「ワーカーが取り出すまでどれだけかかったか」に答えます。529 で拒否されたリクエストは一度もキューに入っていないため、ここには記録されません。それらは oxphp_admission_refused_total で数えてください。
キュー待機時間が長い場合は、すべてのワーカーがビジー状態であることを示しており、PHP_WORKERS を増やす必要があります。レンジはデフォルトの QUEUE_WAIT_TIMEOUT_MS に合わせて 1 秒まで達するため、実行前に待機予算の大半を費やしたリクエストも +Inf にまとめられるのではなく定量化されます。処理されるリクエストが予算より長く待つことはありません — 予算を超えたリクエストは拒否されるためです — ので、待機を再び +Inf へ押し込む唯一の設定は QUEUE_WAIT_TIMEOUT_MS の引き上げです。
レート制限メトリクス
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_rate_limited_total |
counter | レート制限によって拒否されたリクエスト数(429 を返したもの) |
oxphp_php_deny_total |
counter | PHP_DENY_PATHS によってブロックされたリクエスト数(.php の実行が拒否されたもの)。PHP 実行拒否リスト を参照してください |
静的ファイルキャッシュメトリクス
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_static_cache_hits_total |
counter | インメモリキャッシュから提供された静的ファイルリクエスト数 |
oxphp_static_cache_misses_total |
counter | ディスク読み込みを必要とした静的ファイルリクエスト数 |
圧縮メトリクス
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_compressed_responses_total |
counter | Brotli で圧縮されたレスポンス数 |
oxphp_compression_bytes_saved_total |
counter | 圧縮によって節約された総バイト数(元のサイズから圧縮後のサイズを引いたもの) |
ワーカーモードメトリクス
これらのメトリクスはワーカーモードが有効な場合(WORKER_MODE_ENABLED=true)のみ出力されます。
グローバルカウンター
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_worker_mode_enabled |
gauge | ワーカーモードが有効な場合は常に 1 |
oxphp_worker_requests_handled_total |
counter | 永続ワーカーが処理したリクエストの総数 |
oxphp_worker_recycles_total |
counter | ワーカーのリサイクル総数(ワーカーが終了して再生成されたもの) |
oxphp_worker_recycles_by_reason_total |
counter | 理由別のリサイクル数。ラベル: reason(scheduled, max_memory, error) |
oxphp_worker_soft_resets_total |
counter | リクエスト間で実行されたソフトリセットの総数 |
ワーカーごとのゲージ
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_worker_memory_bytes |
gauge | ワーカーごとの現在の PHP ヒープ使用量。ラベル: worker(スロットのインデックス、例: "0", "1") |
oxphp_worker_uptime_seconds |
gauge | 各ワーカーが生成されてからの経過秒数。ラベル: worker |
oxphp_worker_requests_count |
gauge | 各ワーカーインスタンスが処理したリクエスト数。ラベル: worker |
ワーカーリクエスト処理時間のヒストグラム
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_worker_request_duration_us |
histogram | リクエストごとの PHP ハンドラーの実行時間(マイクロ秒、ワーカーモードのみ) |
バケットの境界値(マイクロ秒): 100, 250, 500, 1000, 2500, 5000, 10000, 25000, 50000, +Inf。
このヒストグラムは、キュー待機時間を除いた、PHP ハンドラーコールバック内で費やされた時間を測定します。遅いハンドラーを特定し、ワーカーモードでのテールレイテンシーを追跡するために使用します。
非同期プールメトリクス
これらのメトリクスには ASYNC_WORKERS に 0 以外の値を設定する必要があり、それぞれに独自の出力条件があります。カウンターは少なくとも 1 つのタスクがディスパッチまたは拒否された後にのみ出力され、_in_flight / _in_flight_limit のゲージはプールが処理中カウンターを初期化した時点で出力され、oxphp_async_output_discarded_bytes_total は一部の出力が破棄された後にのみ出力されます。
| メトリクス | 種類 | 説明 |
|---|---|---|
oxphp_async_tasks_dispatched_total |
counter | バックグラウンドプールにディスパッチされた非同期タスクの総数 |
oxphp_async_tasks_completed_total |
counter | 正常に完了した非同期タスク数 |
oxphp_async_tasks_failed_total |
counter | 例外をスローした非同期タスク数 |
oxphp_async_tasks_cancelled_total |
counter | キャンセルされた非同期タスク数 |
oxphp_async_tasks_rejected_total |
counter | ディスパッチ時に拒否された非同期タスク数。プールのキューが満杯だったか、処理中の上限(ASYNC_MAX_FIBERS × ASYNC_WORKERS)に達したためです |
oxphp_async_tasks_stranded_total |
counter | await_race / await_any のタイムアウトを過ぎても実行され続けたワーカー数。取り残された各タスクは RSHUTDOWN を最大 5 秒延長する可能性があります。 |
oxphp_async_tasks_in_flight |
gauge | 現在キュー内または実行中の非同期タスク数(プールが処理中カウンターを初期化すると出力されます) |
oxphp_async_tasks_in_flight_limit |
gauge | 同時実行可能な非同期タスクの最大数(ASYNC_MAX_FIBERS × ASYNC_WORKERS) |
oxphp_async_output_discarded_bytes_total |
counter | ワーカーのアイドル時に破棄された非同期タスク出力のバイト数(非同期タスク内の echo はそれを受け取るクライアントを持ちません) |
Grafana ダッシュボードのヒント
以下の PromQL クエリはダッシュボードの構築に役立ちます。
リクエストレート(1 秒あたりのリクエスト数):
rate(oxphp_requests_total[5m])平均レスポンスタイム(ミリ秒):
rate(oxphp_request_duration_us_sum[5m])
/ rate(oxphp_requests_total[5m]) / 1000p99 リクエスト処理時間(ミリ秒):
histogram_quantile(0.99, rate(oxphp_request_duration_us_bucket[5m])) / 1000エラーレート(5xx レスポンスの割合):
rate(oxphp_responses_by_status_total{status="5xx"}[5m])
/ rate(oxphp_requests_total[5m]) * 100ワーカープールの使用率:
oxphp_busy_workers / oxphp_workers_currentこれは 0 から 1 の間の真の比率です。1 に張り付いた値が続く場合、すべてのワーカーが占有されており、以降の到着はキューイングされています。rate(oxphp_admission_refused_total{reason=~"queue_full|wait_timeout|waiting_full|waiting_bytes"}[5m]) と組み合わせてそのバックログが拒否に転じているかを、oxphp_pending_requests と組み合わせてその深さを確認してください。
キューの飽和(1 秒あたりのドロップレート):
rate(oxphp_dropped_requests_total[5m])p99 キュー待機時間(マイクロ秒):
histogram_quantile(0.99, rate(oxphp_queue_wait_us_bucket[5m]))静的ファイルキャッシュのヒット率:
rate(oxphp_static_cache_hits_total[5m])
/ (rate(oxphp_static_cache_hits_total[5m]) + rate(oxphp_static_cache_misses_total[5m]))1 秒あたりの圧縮による節約バイト数:
rate(oxphp_compression_bytes_saved_total[5m])ワーカーモードの p99 レイテンシー(マイクロ秒):
histogram_quantile(0.99, rate(oxphp_worker_request_duration_us_bucket[5m]))ワーカーのリサイクルレート(1 分あたり):
rate(oxphp_worker_recycles_total[5m]) * 60ワーカーの平均メモリ使用量:
avg(oxphp_worker_memory_bytes)Prometheus のスクレイプ設定
prometheus.yml にスクレイプジョブを追加します。
scrape_configs:
- job_name: "oxphp"
scrape_interval: 15s
static_configs:
- targets: ["oxphp:9090"]Kubernetes のサービスディスカバリを使う場合:
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"関連情報
- ヘルスチェック — 内部サーバーの
/healthおよび/configエンドポイント - 設定リファレンス —
INTERNAL_ADDRを含むすべての環境変数 - グレースフルシャットダウン — コネクションのドレインが
oxphp_active_connectionsに与える影響 - ワーカーモード — 永続ワーカーとそれが出力するメトリクス