trustportidentity / beacon-laravel
Official TrustPort Beacon APM and Telemetry SDK for Laravel
Package info
github.com/trustportidentity/beacon-laravel
pkg:composer/trustportidentity/beacon-laravel
Requires
- php: ^8.2
- ext-curl: *
- illuminate/http: ^10.0 || ^11.0 || ^12.0
- illuminate/support: ^10.0 || ^11.0 || ^12.0
Requires (Dev)
- orchestra/testbench: ^8.0 || ^9.0 || ^10.0
- phpunit/phpunit: ^10.5 || ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-11-11 20:52:56 UTC
README
Official TrustPort Beacon APM SDK for Laravel.
Install
composer require trustportidentity/beacon-laravel
Package discovery auto-registers BeaconServiceProvider and the Beacon facade.
Configure
BEACON_INGEST_URL=https://beacon-api.trustportidentity.com BEACON_API_KEY=tb_live_your_tenant_key BEACON_SERVICE_NAME=billing-api BEACON_ENVIRONMENT=production
Register the middleware
// app/Http/Kernel.php use TrustPortIdentity\Beacon\BeaconMiddleware; protected $middleware = [ BeaconMiddleware::class, ];
Custom spans
use TrustPortIdentity\Beacon\Beacon; $span = Beacon::span('db.mysql.select_invoices', 'database'); $invoices = Invoice::where('status', 'pending')->get(); $span->setTag('rows', $invoices->count())->end();
Controlling ingest volume
Every trace is already batched (BEACON_BATCH_SIZE) instead of one network call per
request. In high-traffic services, also set BEACON_SAMPLE_RATE (0.0–1.0, default 1.0) to
trace only a fraction of requests — this is what actually keeps you inside your plan's
monthly quota. Exceptions and 5xx responses are always sent regardless of sampling; set
BEACON_ALWAYS_SEND_FROM_STATUS=400 to also keep every 4xx (useful for public APIs).
BEACON_SAMPLE_RATE=0.2
See the full guide at beacon.trustportidentity.com/help/laravel.
Migrating from Laravel Nightwatch
Beacon registers itself the way Nightwatch does: install the package, set the env vars, done.
composer remove laravel/nightwatchthencomposer require trustportidentity/beacon-laravel:^1.2- In
.env, replace theNIGHTWATCH_*variables with:BEACON_API_KEY=tb_live_... # your workspace key from Beacon BEACON_INGEST_URL=https://beacon-api.trustportidentity.com BEACON_SERVICE_NAME=my-app BEACON_ENVIRONMENT=production # label in Beacon (production/staging/local) BEACON_SAMPLE_RATE=1 # 0-1; replaces NIGHTWATCH_REQUEST_SAMPLE_RATE - Stop the Nightwatch agent (
php artisan nightwatch:agent): Beacon has no agent process. php artisan config:clearandphp artisan queue:restart.
What you get with no code changes: every HTTP request (route, status, redacted headers, the signed-in user from any
guard including Sanctum), database queries with slow-query / N+1 / duplicate detection, queue jobs, cache hits and
misses, and log lines as breadcrumbs, plus unhandled exceptions. Health checks (up, health, api/health) are not
traced; change with BEACON_IGNORE_PATHS. Set BEACON_AUTO_MIDDLEWARE=false if you register
TrustPortIdentity\Beacon\BeaconMiddleware yourself.
Errors: what is captured (v1.2+)
| Situation | Captured as |
|---|---|
| Exception in a web request (including ones Laravel turns into a 500 page/JSON) | The request trace, with the user, route and stack trace |
| Exception in a queue job | A QUEUE trace with the failure |
| Exception in artisan / scheduler / console code | A CLI trace |
Exceptions you report($e) or that Laravel logs |
Same as above, marked handled |
| PHP fatals: memory exhausted, max execution time, parse errors | A FatalError trace, flushed from a shutdown handler |
| 404, validation, auth exceptions Laravel does not report | Not sent (no noise) |
Opt out with BEACON_CAPTURE_EXCEPTIONS=false / BEACON_CAPTURE_FATALS=false. Errors are never sampled away.
Sampling, noise and privacy
- Sampling:
BEACON_SAMPLE_RATE(0-1) applies to normal requests. Requests that throw, and every response with status ≥BEACON_ALWAYS_SEND_FROM_STATUS(default 500), are always sent. A 5xx returned without an exception is reported asHTTP <status>: <message from the response>. Low-traffic apps should use1; a low rate means most requests never appear in the dashboard. - Noisy endpoints (cron pings, webhooks): exclude with
BEACON_IGNORE_PATHS, comma separated,*wildcard, e.g.up,health,api/health,api/send_*_mails. - Always redacted, no setting needed:
Authorization,Cookie,Set-Cookie,X-Api-Key, CSRF/XSRF headers, and the value of any query parameter whose name containstoken,secret,password,auth,signature,sessionor is a key (key,cron_key,api_key). Other parameters (page,keyword) are kept. BEACON_SANITIZE_PII=trueadditionally scrubs card-number-like values from URLs and messages.
Troubleshooting
| Symptom | Check |
|---|---|
| Only a few requests show up | Sample rate below 1, or the path is in BEACON_IGNORE_PATHS |
| Nothing shows up | BEACON_API_KEY unset, config cached (php artisan config:clear), or the server cannot reach BEACON_INGEST_URL |
| A fatal/exception is missing | Upgrade to ^1.2; fatals need BEACON_CAPTURE_FATALS not false |
| Requests have no user | The app authenticates in a way Laravel's guards do not see; call Beacon::identify(...) yourself |
| Works locally, not in a queue worker | Run php artisan queue:restart after changing .env |
Telemetry is silent until BEACON_API_KEY is set, so the package can ship to every environment safely.
Run the package tests with composer install && ./vendor/bin/phpunit.