Konfiguracja collectora
phpray-collector to niewielki daemon Go. Odczytuje ślady z pamięci współdzielonej lub plików, zapisuje dane, obsługuje retencję i alerty oraz udostępnia lokalne API i dashboard. Plik konfiguracji: /etc/phpray/collector.toml; inny wskazujesz przez --config.
collector.toml
Instalator zapisuje /etc/phpray/collector.toml; każdy klucz poniżej jest opcjonalny i pokazany z wartością domyślną.
[input]
jsonl_path = "/tmp/phpray.jsonl" # where the extension appends JSONL records (output_mode = file)
shm_path = "/dev/shm/phpray" # ring buffer (output_mode = ring); a glob such as "/run/phpray/ring-*" reads one ring per PHP-FPM pool
control_path = "/dev/shm/phpray-control" # on-demand profiling table, read by the extension at request start
[storage]
db_path = "/var/lib/phpray/traces.db" # SQLite: traces, queries, aggregates, alerts
[collector]
mode = "auto" # auto | ring | jsonl (auto prefers the ring buffer when it exists)
poll_interval_ms = 100
flush_interval_s = 5
batch_size = 50
agg_interval_s = 60 # per-minute aggregates
[retention]
days = 30 # purge traces and aggregates older than this
max_mb = 4096 # hard cap on the database file: the oldest traces are purged beyond it (0 = off)
[logging]
level = "info"
quiet = false
[auth]
secret = "" # JWT secret; empty = dashboard/API without login (keep it on 127.0.0.1)
[server]
da_data_path = "" # DirectAdmin: /usr/local/directadmin/data, maps users to domains
[cloud]
enabled = false
endpoint = "https://app.phpray.dev"
server_key = "" # prk_… from your PHPRay Cloud account (one per server)
buffer.max_mb = 32 # disk buffer while the console is unreachable; oldest batches dropped first
buffer.dir = "" # default: <db dir>/cloud-buffer
traces.sample_rate = 100 # % of normal/full/alert traces shipped (the console may lower it)
control = true # long-poll /v1/control for "profile this URL" messages
[cloud.privacy]
mask_host = false # send the site id instead of the hostname
Adres nasłuchu dashboardu/API nie jest w pliku: to flaga -addr polecenia phpray-collector serve w unicie systemd (opcja --listen instalatora). Komentarze w linii po wartości są dozwolone.
Wiele buforów pierścieniowych (wzorzec w shm_path)
Od collectora 0.15 shm_path może być wzorcem. Użyj go, gdy rozszerzenie pisze jeden ring na tożsamość — phpray.shm_path = "/run/phpray/ring-%u" w php.ini (%u = uid, %g = gid, rozszerzenie 0.15+) — dzięki czemu ślady każdej puli PHP-FPM leżą w pliku, który otworzy tylko ten użytkownik i root:
[input]
shm_path = "/run/phpray/ring-*"
- Collector przeszukuje wzorzec co 5 s: ring, który się pojawił (pula obsłużyła pierwsze żądanie), jest otwierany i zapisywany w logu, ring, którego plik zniknął, jest zamykany i zapisywany w logu, a plik odtworzony z nowym i-węzłem — otwierany ponownie.
- Wszystkie pasujące ringi są czytane w jednej pętli; przepełnienia raportowane są osobno dla każdego.
mode = "auto"imode = "ring"korzystają z tego zbioru; wzorzec nigdy nie schodzi do JSONL.mode = "jsonl"ignorujeshm_path.- Wzorzec bez dopasowań to normalny stan na świeżym serwerze;
phpray statuswypisuje znalezione pliki, a przy działającej usłudze także ringi, które collector ma otwarte.
Bez wzorca collector czyta pojedynczy plik tak jak dotąd.
Przyjmowanie śladów po HTTP (POST /api/v1/ingest)
Od collectora 0.15 lokalne API przyjmuje też partie śladów po HTTP. Korzysta z tego wtyczka WordPress w trybie collector i może korzystać dowolny agent zewnętrzny; rekordy trafiają na tę samą ścieżkę co ślady z ringu i z JSONL: dashboard na żywo, SQLite, CLI oraz — przy włączonym [cloud] — wysyłka do Cloud, z site_id wziętym z rekordu.
- Treść: koperta partii z protokołu ingest
{"batch_id":"b_…","sent_at":<unix ms>,"agent":"wp-plugin/0.1.1","traces":[…]}albo goła tablica JSON z rekordami śladów.Content-Type: application/json, opcjonalnieContent-Encoding: gzip. - Rekordy: rekord śladu, opcjonalnie z
site_id.tsw sekundach (milisekundy są przeliczane). Rekord bezhostiurialbo niebędący obiektem jest pomijany i liczony wdropped; reszta partii jest przyjmowana. - Dostęp: przy ustawionym
[auth] secretżądanie wymaga tokenu dashboardu (Authorization: Bearer <jwt>, wystawianego przezphpray token); bez sekretu wysyłać mogą tylko klienci z127.0.0.1/::1— pozostali dostają403. - Limity: 8 MB na treść (po dekompresji) i 500 rekordów na partię, oba zwracają
413; niepoprawny JSON —400. - Idempotencja:
batch_idwidziany w ciągu ostatnich 24 h dostaje202zaccepted: 0iduplicate: true, nic nie jest zapisywane dwa razy. - Odpowiedź:
202 {"accepted": N, "dropped": M, "dropped_quota": 0, "server_time": <unix ms>}.
curl -s -X POST http://127.0.0.1:9191/api/v1/ingest \
-H 'Content-Type: application/json' \
-d '{"batch_id":"b_test","sent_at":1789737600000,"agent":"curl/1",
"traces":[{"ts":1789737600,"host":"shop.example","uri":"/checkout/","method":"GET",
"status":200,"duration_ms":312.5,"level":"normal"}]}'
# {"accepted":1,"dropped":0,"dropped_quota":0,"server_time":1789737600123}
Liczniki: GET /api/v1/health → ingest (batches, traces, dropped, duplicates, rejected), /metrics → phpray_ingest_* oraz phpray status.
Uruchamianie
systemctl enable --now phpray-collector
systemctl status phpray-collector
phpray status # one-line view: collector, shm, dashboard, cloud
Logi
- journald:
journalctl -u phpray-collector - plik awaryjny, tylko bez journald:
/var/log/phpray/collector.log - baza śladów:
/var/lib/phpray/phpray.db— pojedynczy plik SQLite - surowe ślady przy
output_mode=file:/var/lib/phpray/traces/*.jsonl
Limity dysku
[retention].max_mb (domyślnie 4 GB) ogranicza rozmiar SQLite. Po przekroczeniu collector usuwa najstarsze rekordy, aż baza mieści się w limicie. Okna traces_days i aggregates_days działają niezależnie: decyduje limit osiągnięty wcześniej. Bufor Cloud ma oddzielny limit [cloud].buffer.max_mb (domyślnie 32 MB); usuwa najstarsze ślady, nigdy agregaty.
docs-site/docs/configuration/collector.md · PHPRay 0.14Wersja polska jest tłumaczeniem angielskiego oryginału; parametry i przykłady kodu pozostają w oryginalnej składni.