Protokół ingest
Protokół komunikacji agentów (collectora, wtyczki WordPress i integracji zewnętrznych) z konsolą. Poniżej znajduje się pełna specyfikacja spec/ingest-v1.md w polskim tłumaczeniu technicznym.
Protokół ingest PHPRay v1 — projekt z 18.09.2026
Jak dane trafiają z serwera do konsoli. Dotyczy collectora w Go (phpray-collector), wtyczki WordPress i każdego agenta zewnętrznego. Konsole: PHPRay Cloud (https://app.phpray.dev) i Host Edition (self-hosted, to samo API). Status: draft — zamrożenie razem z collectorem 0.14.
1. Zasady
- Tylko połączenia wychodzące. Agent otwiera połączenie HTTPS do konsoli. Konsola nie łączy się z serwerem. Bez portów przychodzących, SSH i dostępu do powłoki.
- Agregaty zawsze, ślady selektywnie. Co minutę agent wysyła niewielkie agregaty każdego serwisu. Pojedyncze ślady wysyłane są dla poziomów
normal/full/alert. Po przekroczeniu limitu planu konsola stosuje próbkowanie. - Minimalizacja danych. SQL jest wysyłany jako fingerprint: liczby i literały tekstowe są zastępowane. URI zachowuje nazwy parametrów, a wartości zamienia na
*. Nie są wysyłane treści żądań ani odpowiedzi, cookies i nagłówki pozaHost. Nazwy hostów można pseudonimizować dla serwisu przezprivacy.mask_host. - Idempotencja i kontrolowany bufor. Paczki mają
batch_id; konsola usuwa duplikaty przez 24 godziny. Gdy wysyłka jest niemożliwa, agent przechowuje na dysku maksymalniebuffer.max_mb(domyślnie 32 MB). W pierwszej kolejności usuwa najstarsze ślady, nigdy agregaty.
2. Tożsamość
| Obiekt | Identyfikator | Pochodzenie |
|---|---|---|
| Konto agencji / operatora | account_id |
konsola |
| Serwer | server_key = prk_<32 hex> |
utworzony w konsoli, wklejany do collector.toml ([cloud] server_key) lub ustawień wtyczki WP |
| Serwis | site_id = sha1(host + \0 + docroot)[:16] |
obliczany przez agenta; wtyczka WP używa hosta z home_url() oraz ABSPATH |
| Agent | agent = collector/0.14.0 lub wp-plugin/0.1.0 |
stały dla danego buildu |
server_key należy do dokładnie jednego konta i serwera. Rotacja klucza w konsoli unieważnia stary klucz po 24-godzinnym okresie przejściowym.
3. Endpointy
Wszystkie żądania: Authorization: Bearer <server_key>, Content-Type: application/json, opcjonalnie Content-Encoding: gzip (zalecane powyżej 8 KB). Odpowiedzi są w JSON. Agent wysyła sent_at (czas Unix w ms). Konsola porządkuje rekordy według czasu odbioru i zwraca server_time, aby agent mógł odnotować rozbieżność zegarów.
POST /v1/aggregates
Jedno żądanie na minutę na serwer; po awarii można połączyć dane z kilku minut w paczkę.
{
"batch_id": "b_<uuid>", "sent_at": 1789737600000, "agent": "collector/0.14.0",
"server": {"hostname_hash": "<sha1[:16]>", "php_versions": ["8.3.33"], "os": "linux-amd64"},
"minutes": [
{"ts": 1789737540, "site_id": "…", "host": "shop.example", "app": "wordpress",
"requests": 412, "errors_5xx": 3, "errors_php": 7, "profiled": 12,
"duration_ms": {"avg": 231.4, "p50": 198.0, "p95": 640.2, "max": 3120.5},
"cpu_ms": {"avg": 91.2}, "memory_mb": {"avg": 42.1, "max": 128.0},
"db": {"queries": 40120, "ms": 18200.4, "n1_requests": 5},
"http": {"calls": 63, "ms": 9120.0, "errors": 2},
"levels": {"summary": 380, "normal": 27, "full": 4, "alert": 1},
"components": [{"name": "plugins/woocommerce", "incl_ms": 1201.5, "self_ms": 640.1, "calls": 18800}],
"top_uris": [{"uri": "/checkout/", "requests": 31, "p95_ms": 1120.0}]}
]
}
Odpowiedź: 202 {"accepted": 3, "duplicates": 0, "server_time": …}.
POST /v1/traces
Paczki do 500 śladów: niezmieniony rekord JSONL z rozszerzenia lub wtyczki WP z dodatkowym site_id. Wysyłka najwyżej co 5 sekund lub natychmiast dla poziomu alert.
{"batch_id": "b_<uuid>", "sent_at": …, "agent": "…",
"traces": [ { "site_id": "…", "ts": …, "host": "…", "uri": "…", "level": "full", … } ]}
Odpowiedź: 202 {"accepted": 120, "dropped_quota": 0}. Gdy dropped_quota > 0, konsola próbkuje dane. Agent powinien obniżyć traces.sample_rate do wartości procentowej z nagłówka X-PHPRay-Trace-Sample do czasu kolejnej paczki przyjętej w całości.
GET /v1/control
Long polling do 25 sekund dla komunikatów sterujących skierowanych do serwera. Tak polecenie „profiluj URL X przez 10 minut” z konsoli lub przyszłej integracji DirectAdmin trafia do rozszerzenia bez edycji php.ini:
{"server_time": …, "messages": [
{"id": "m_1", "type": "profile", "site_id": "…", "url_prefix": "/checkout/",
"sample_rate": 100, "until": 1789738200},
{"id": "m_2", "type": "config", "site_id": "…", "traces": {"sample_rate": 10}}
]}
Collector zapisuje komunikaty profile w tablicy sterującej pamięci współdzielonej, odczytywanej przez rozszerzenie podczas RINIT (docroot → {url_prefix, sample_rate, until}). Wtyczka WP stosuje je we własnym procesie. Agent potwierdza odbiór przez POST /v1/control/ack {"ids": ["m_1"]}.
GET /v1/health
200 {"ok": true, "account": "…", "server": "…", "plan": "studio", "quota": {"traces_per_day": 200000, "used": 84121}}. Używane przez phpray status oraz ekran ustawień wtyczki WP („połączono jako…”).
4. Błędy i limity
| Kod | Znaczenie | Zachowanie agenta |
|---|---|---|
| 401 | błędny lub unieważniony klucz | wstrzymaj wysyłkę; pokaż problem w phpray status i dashboardzie |
| 402 | wyczerpany lub nieopłacony plan | wysyłaj agregaty, wstrzymaj ślady i pokaż problem |
| 413 | za duża paczka | podziel paczkę na pół i ponów wysyłkę |
| 429 | limit częstotliwości (Retry-After) |
odczekaj przed ponowieniem, nadal buforuj |
| 5xx | problem konsoli | wykładnicze opóźnienie ponowień od 5 s do 5 min; nadal buforuj |
Limity bezwzględne: agregaty — 1 żądanie/min/serwer, do 10 w serii po awarii; ślady — 500 rekordów lub 4 MB w paczce, 12 paczek/min/serwer. Limit serwisów planu egzekwowany jest na podstawie site_id.
5. Domyślna prywatność — po stronie agenta, przed wysyłką
- SQL → fingerprint;
queries[].sqlnie zawiera literałów. Ścieżki ramek backtrace są skracane odwp-content/lubvendor/, bez bezwzględnej ścieżki katalogu domowego. - URI: ścieżka i parametry z zamaskowanymi wartościami (
?utm_source=*&page=*). Żądania objęteignore_urisnie są wysyłane. hostmoże zostać zastąpiony przezsite_id, gdy dla serwisu ustawionoprivacy.mask_host = true.- Bez adresów IP odwiedzających, identyfikatorów użytkowników, cookies, treści i nagłówków poza wyjątkiem Host opisanym w zasadach.
- Błędy: komunikat skrócony do 200 znaków; ścieżki skrócone jak wyżej. Skrócenie komunikatu nie jest automatyczną anonimizacją wszystkich sekretów.
6. Wersjonowanie
Po zamrożeniu /v1 pozostaje stabilne; dopuszczalne są tylko nowe pola. Zmiany niezgodne trafiają do /v2 z 12 miesiącami równoległego wsparcia. Agenci wysyłają agent; konsola może odrzucić niewspieraną wersję kodem 426.
docs-site/docs/cloud/ingest.md · PHPRay 0.14Wersja polska jest tłumaczeniem angielskiego oryginału; parametry i przykłady kodu pozostają w oryginalnej składni.