Konfiguracja - PHP
Na tej stronie Opcje, które warto znać
Opcje, które warto znać
| Opcja | Domyślnie | Znaczenie |
|---|---|---|
environment | null | kolumna środowiska w panelu |
release | null | wersja wdrożonej aplikacji |
error_types | error_reporting() | które błędy PHP stają się zdarzeniami |
sample_rate | 1.0 | udział wysyłanych zdarzeń błędów |
traces_sample_rate | 0.0 | udział wysyłanych transakcji; 0 wyłącza pomiar |
send_default_pii | false | dołącza identyfikator i e-mail użytkownika, adres IP i user agenta |
enable_compression | true | pakuje ciało żądania gzipem |
send_after_response | true na WWW, false w CLI | kolejkuje zdarzenia i wysyła po odpowiedzi |
max_request_body_size | medium | none, small, medium albo always |
in_app_exclude | [] | ścieżki, których ramki są oznaczane jako kod obcy |
before_send | identyczność | ostatnia szansa, żeby zmienić albo odrzucić zdarzenie |
Środowiska
Każde środowisko powinno raportować pod jednoznaczną nazwą - production, staging, preview. Nazwa jest kolumną w panelu i filtrem na liście błędów, więc bez niej awaria z produkcji wygląda dokładnie tak samo jak błąd wywołany w testach. Środowisko lokalne zostaw bez poświadczeń: bez tokenu i klucza integracja ładuje się i milczy, więc nie musisz jej wyłączać osobnym warunkiem.
in_app_exclude decyduje o czytelności stosu
To najbardziej niedoceniana opcja w tym SDK. Ramki spod ścieżek wymienionych w in_app_exclude są oznaczane jako kod obcy, więc panel pokazuje miejsce awarii w Twojej aplikacji, a nie najgłębszą ramkę w bibliotece:
init([
'in_app_exclude' => [__DIR__.'/../vendor'],
]);
Bez tego każdy błąd wygląda, jakby powstał w vendor/ - a do Jiry i Notion trafia właśnie istotny fragment stosu, czyli ramki oznaczone jako kod aplikacji.
Kiedy zdarzenia wychodzą
Domyślnie po odpowiedzi. Zdarzenia są kolejkowane w czasie żądania i wysyłane z uchwytu zamknięcia, gdy PHP-FPM albo LiteSpeed zamknął już połączenie z przeglądarką - wolny albo niedostępny monitoring nie opóźnia wtedy strony dla odwiedzającego. Tam, gdzie SAPI nie umie zamknąć połączenia wcześniej (na przykład mod_php), kolejka i tak jest opróżniana przy zamknięciu, więc wysyłka nie dzieje się w środku obsługi żądania.
Kolejka trzyma najwyżej 50 zdarzeń na żądanie; nadwyżka jest odrzucana, bo powtórzone zdarzenia i tak są grupowane po odcisku palca. 'send_after_response' => false przełącza na wysyłkę w miejscu wywołania; w CLI jest to domyślne, bo długo żyjący worker nie powinien trzymać raportów do końca procesu.
Transakcje HTTP
use Dock\Ray\Framework\HttpTransaction;
$transaction = HttpTransaction::start('GET /checkout', $url, 'GET');
$transaction->measureHandling('app.handle');
// ... obsługa żądania ...
$transaction->finish($response->getStatusCode());
Pierwszy argument to wzorzec trasy, nie konkretny adres: GET /orders/{order}, a nie GET /orders/8123. Inaczej lista transakcji rozsypie się na tysiące pozycji. Transakcje wychodzą tylko przy traces_sample_rate większym od zera.
Wzbogacanie zdarzeń
use Dock\Ray\Breadcrumb;
use function Dock\Ray\{addBreadcrumb, configureScope};
addBreadcrumb(new Breadcrumb(
Breadcrumb::LEVEL_INFO,
Breadcrumb::TYPE_DEFAULT,
'auth',
'User logged in'
));
configureScope(function (\Dock\Ray\State\Scope $scope) {
$scope->setTag('feature', 'payments');
$scope->setUser(['id' => 42, 'email' => 'user@example.com']);
});
Tagi są najtańszym sposobem, żeby odfiltrować w panelu jeden obszar aplikacji. Dane użytkownika ustawiaj świadomie - to dane osobowe, a send_default_pii jest domyślnie wyłączone nie bez powodu.
Błędy przeglądarki
Przeglądarka nie może uwierzytelnić się wprost w DockRayu, bo klucz prywatny musi zostać na serwerze. SDK daje więc skrypt kolektora i normalizator po stronie serwera, a droga zdarzenia wygląda tak:
przeglądarka → Twoja aplikacja → DockRay
(bez klucza) (klucz projektu)
use Dock\Ray\Browser\BrowserEvent;
use Dock\Ray\Browser\Collector;
// Renderowanie strony: wskaż kolektorowi własny endpoint.
$config = Collector::config(endpoint: '/errors/browser', token: $csrfToken);
// Collector::scriptPath() zwraca plik do zaserwowania albo wstawienia.
// Odbiór zgłoszenia: wszystko w $payload jest niezaufane.
$event = BrowserEvent::fromArray($payload, $referer, $userAgent);
if ($event !== null) {
$hub->captureEvent($event);
}
fromArray() zwraca null dla wszystkiego, czego nie potrafi zamienić w zdarzenie, i przycina każdy zachowany ciąg. Bramki endpointu piszesz sam - token CSRF, limit rozmiaru ciała i limit na adres IP to dokładnie to, czego używają nasze wtyczki. Sam kolektor też się ogranicza: jedno zgłoszenie na odrębny błąd na odsłonę i dziesięć na odsłonę, z odsianym ResizeObserver loop i Script error. z obcej domeny.
Ochrona klucza prywatnego
Klucz prywatny jest sekretem projektu, a nie identyfikatorem. Trzymaj go w zmiennych środowiskowych, w menedżerze sekretów albo w konfiguracji serwera - nigdy w repozytorium, w logach, na zrzucie ekranu ani w kodzie wysyłanym do przeglądarki. Jeden projekt może mieć wiele kluczy, więc produkcja i środowisko testowe powinny dostać osobne: każdy odwołuje się niezależnie, bez przerywania raportowania z pozostałych. Podejrzenie ujawnienia klucza jest wystarczającym powodem, aby go odwołać i wygenerować nowy.