Telescope for Laravel
Install inverge/nexus and every request, job, command and scheduled task is recorded — nothing to wire.
Install
composer require inverge/nexusNEXUS_API_KEY=nxs_live_xxx
NEXUS_SERVICE_NAME=orders-api # how this app is named in traces (defaults to APP_NAME)
# NEXUS_TELESCOPE_ENABLED=false # switch it off
# NEXUS_TELESCOPE_SAMPLE_RATE=0.2 # override the console's sample rateThat's all. The service provider registers itself and Telescope starts recording. Open Telescope in the console and make a request.
What is recorded
Requests (route, controller, headers, payload, response, user, session), and the phases of each — boot, global middleware, route middleware, controller, response — plus every:
| Watcher | Records |
|---|---|
queries | SQL, bindings, duration, connection, and the file:line in your app that ran it |
models | created / updated / deleted / retrieved, with counts |
events | dispatched events and their listeners |
jobs, batches | dispatch and execution, joining the dispatching request's trace on any worker |
commands, schedule | artisan commands and scheduled tasks as their own journeys |
http | outgoing Laravel HTTP client calls (with a traceparent) |
cache, redis | hits, misses, writes, forgets; Redis commands |
mail, notifications | what was sent, to whom, through which channel |
gates | authorization checks and results |
views, dumps | rendered views; dump() output |
exceptions, logs | filed in Nexus Errors / Logs as well |
middleware | per-middleware timing |
Configure
Publish the config to tune it:
php artisan vendor:publish --tag=nexus-config'telescope' => [
'service' => env('NEXUS_SERVICE_NAME', env('APP_NAME')),
'release' => env('NEXUS_RELEASE'),
'sample_rate' => env('NEXUS_TELESCOPE_SAMPLE_RATE'), // null = console setting
'timeout' => env('NEXUS_TELESCOPE_TIMEOUT', 3.0), // delivery, after the response
'ignore_paths' => ['/telescope*', '/horizon*', '/_debugbar*', '/pulse*', '/up'],
'ignore_commands' => ['queue:work', 'horizon', 'schedule:run', 'tinker', /* … */],
'redact_keys' => [], // passwords, tokens and cookies always are
'capture_response_bodies' => true, // JSON decoded, HTML summarised
'body_size_limit' => 64, // KB
'locations' => true, // file:line for queries, gates, dumps
'max_entries' => 2000, // per journey; the rest are counted
'watchers' => [
'requests' => true, 'middleware' => true, 'queries' => true, 'models' => true,
'events' => true, 'jobs' => true, 'batches' => true, 'commands' => true,
'schedule' => true, 'exceptions' => true, 'logs' => true, 'http' => true,
'cache' => true, 'redis' => true, 'mail' => true, 'notifications' => true,
'gates' => true, 'views' => true, 'dumps' => true,
],
],queue:work, horizon and schedule:run are ignored as commands on purpose —
the jobs and tasks they run are recorded individually.
Performance
- The journey is delivered in
terminate()— after the response has been sent under PHP-FPM — so users don't wait for it. Works under Octane. - Sampled-out journeys are discarded locally.
Your own entries
use Inverge\Nexus\Telescope\Telescope;
$t = app(Telescope::class); // or type-hint Telescope in a constructor
$quote = $t->span('price lookup', fn () => $pricing->quote($order));
$t->tag('vip', 'checkout-v2');
$t->user(['id' => (string) $user->id, 'email' => $user->email]); // automatic for authenticated users
$t->record('event', ['name' => 'OrderPriced', 'payload' => $quote]);Monitored tags
Tags you add — or the automatic Auth:<user id> tag — can be monitored in
Telescope → Settings: journeys carrying them are always kept, whatever the
sample rate. Useful while debugging one customer.
