Appearance
Telescope
Laravel Telescope: every request, query, job, email and exception of the site, one by one, for debugging.
kitloom/telescope · admins: kitloom/telescope-filament, kitloom/telescope-nova
Video lessons
Recorded in the Filament admin; the Nova admin works the same way.
Laravel Telescope on a kitloom site. Telescope writes down what the site does, one thing at a time, with its details: each request with its headers, input, answer and time; each database query with its SQL and the line that ran it; each queued job with its data and whether it failed; each exception with its stack trace; outgoing HTTP calls, scheduled tasks, notifications. You open an entry and see everything that happened in that request or job. It is the tool for "why was this page slow at 14:02" and "what exactly did this job get".
This module brings Telescope in, lets into its dashboard the users whose role allows it, keeps out what a CMS would flood it with, names the site's pages and modules on the entries, keeps secrets out of what is stored, prunes old entries every night, and adds Telescope → Settings to the admin. The admin section is kitloom/telescope-filament or kitloom/telescope-nova.
Telescope, Pulse, Horizon, Emails
| Module | What it shows | Use it for |
|---|---|---|
| Telescope | Every recorded request, query, job, exception — one by one, with their data | Finding out why one thing went wrong or was slow |
| Pulse | Totals and averages over hours and days: slowest pages, queries, jobs, servers | Seeing how the site does in general |
| Horizon | The workers of a queue on Redis | Running and watching queue workers |
| Emails | Every email the site sent, with its body | Checking what a customer received |
Telescope sees jobs on any queue, the database queue included.
Setting it up
- Activate the module on the Modules screen.
- Run
php artisan migrate: it creates Telescope's tables (wp_telescope_entries,wp_telescope_entries_tags,wp_telescope_monitoring) with the site's table prefix.php artisan telescope:installis not needed — it would publish a migration and a provider the module replaces. - Open the admin: the "Telescope" section has the dashboard, and its badge says recording.
The dashboard is at /telescope (TELESCOPE_PATH changes it). Its styles and scripts come from the package itself: nothing to publish or build.
What is recorded
On a site whose APP_ENV is local, everything Telescope records. Anywhere else, what Telescope → Settings asks for:
| Kept | How |
|---|---|
| A request that took longer than Slow request (1000 ms) | With everything recorded during it: its queries, models, views, cache, events |
| A request that answered 4xx or 5xx (a 404, a server error) | The same |
| An exception | With the request or job it was thrown in |
| A query that took longer than Slow query (100 ms) | With the request or job that ran it |
| A queued job | Its line alone. Telescope learns that a job failed by updating the line it wrote when the job was queued, so every job is listed |
| A scheduled task, an outgoing HTTP request, a notification | Each alone |
| An email | Only with Record emails on: kitloom/emails keeps the log of sent mail already |
Turn Record everything on to record every request and query while you look into something, then off again: on a busy site the table grows by hundreds of megabytes a day.
Never recorded, whatever the settings say:
- a page the page cache answered (the
X-Site-Cache: hitanswer) — it drew nothing worth looking at; pages served straight from the cache's files never reach Laravel at all; - Livewire's requests (the Filament admin's polling,
/livewire…), the admin bar's own calls (/wp-json/admin-bar/v1/…), files served through PHP (.css,.js, images, fonts); - Telescope's own dashboard.
More paths and extensions are added under ignore in the configuration.
Names on the entries
Telescope tags entries so the dashboard can find them. Besides its own (the signed-in user, the model), the module adds:
template:single-book,template:page,template:front-page,template:search,template:404… on a request and an exception of a site page — the template the page resolved to, as Pulse names it (every page goes through one route, so the route says nothing);post:12,term:5,user:7— the record the page shows;module:bookings,module:webhooks… on a job, a notification or an email of a kitloom module.
Type a tag into a list's search on the dashboard: template:search lists the slow searches, post:12 every recorded visit of that post.
Secrets
Telescope stores what a request sent. The module hides, as ********:
password,password_confirmation,current_password,_token,pwd,pass1,pass2, and theCookie,Set-Cookie,Authorization,X-CSRF-Token,X-XSRF-Tokenheaders;- any parameter, header or JSON key whose name looks like a secret — containing
pass,pwd,secret,token,salt,dsn,credential,private,license, or ending inkeyorauth(api_key,x-api-key,basic_auth) — in the site's requests and in outgoing HTTP alike: an SMTP password saved on a settings page, an API key sent to a service,?token=in an address.
The patterns are secret in the configuration. Other data — names, emails, addresses in a form, the data of a job — is stored as sent: that is what makes Telescope useful, and why only administrators open it.
Settings
Telescope → Settings. An empty number uses the configuration's value, shown in the field.
| Setting | Default | What |
|---|---|---|
| Record | on | Off — nothing new is stored; the dashboard keeps what it has |
| Record everything | off | Every request, query, job and event, not only problems |
| Slow request | 1000 ms | A request that takes longer is kept with its queries; 0 keeps every one |
| Slow query | 100 ms | Telescope's own threshold (it also tags such a query slow) |
| Keep entries | 48 hours | Older entries are deleted every night |
| Record emails | off | kitloom/emails keeps the log of sent mail |
A save applies from the next request or job, under Octane and in a running queue worker too. Telescope's dashboard has a Pause button of its own; the badge says paused for either.
The badge in the admin
| Badge | What it means | What to do |
|---|---|---|
| recording | Telescope records what the settings ask for | — |
| recording everything | Every request and query is stored: "Record everything" is on, or APP_ENV=local | Turn "Record everything" off when you are done |
| paused | Recording is off in the settings, or paused on the dashboard | Turn "Record" on, or press Resume on the dashboard |
| off | TELESCOPE_ENABLED=false in the environment: no recording, no dashboard | Change it in .env |
| tables missing | Telescope's tables are not in the database | php artisan migrate |
Who opens the dashboard
/telescope opens for users whose role has the Open the Telescope dashboard permission (view_telescope). Administrators have it from the start. Entries carry request bodies, emails and job payloads, so give it with care. Everyone else gets "403 Forbidden", in every environment, local included. The settings page asks for Manage settings (manage_options).
An application that decides this itself with Telescope::auth() sets kitloom-telescope.authorize to false.
Pruning and storage
The module schedules php artisan telescope:prune --hours=<Keep entries> daily, on one server of several (a lock in the cache, so several servers need a shared cache store). The server runs php artisan schedule:run every minute. php artisan telescope:clear empties the tables at once.
What it costs: with the default settings, a few rows per problem; with "Record everything", every query of every request — tens of rows per page view, a response body of up to 64 KB each (TELESCOPE_RESPONSE_SIZE_LIMIT). Keep the hours short on a busy site.
The environment
| Variable | Default | What |
|---|---|---|
TELESCOPE_ENABLED | true | false turns Telescope off altogether: no recording, no dashboard, no cost. No setting overrides it |
TELESCOPE_PATH | telescope | The dashboard's address |
TELESCOPE_DOMAIN | — | A domain of its own for the dashboard |
TELESCOPE_*_WATCHER | true | Turns one of Telescope's watchers off (TELESCOPE_MODEL_WATCHER=false …) |
Telescope's own configuration (php artisan vendor:publish --tag=telescope-config) lists every watcher and its options; see Telescope's docs.
Octane and queues
Under Octane Telescope records each request on its own and stores it when the request ends. The module's filters read the settings each time and keep nothing between requests. In a queue worker each job is recorded and stored on its own.
Deactivating the module
Deactivating Telescope on the Modules screen also stops loading laravel/telescope: the dashboard, its routes, the recording and the telescope:* commands go with the module (unless the application requires laravel/telescope in its own composer.json). Its tables stay; activating the module brings everything back.
Configuration
php artisan vendor:publish --tag=kitloom-telescope-config writes kitloom-telescope.php:
| Key | Default | What |
|---|---|---|
authorize | true | The module decides who opens the dashboard (view_telescope) |
filter | true | The module decides what is kept (above); false leaves it to Telescope and the application |
ignore.paths, ignore.extensions | Livewire, the admin bar, static files | Requests never recorded |
secret | *pass*, *token*, *key … | Names hidden in stored requests |
slow_request_ms, prune_hours | 1000, 48 | What an empty setting stands for |
prune | true | telescope:prune daily |
ai.register | true | The telescope_report tool for AI agents |
filament.register, nova.register | true | The "Telescope" section of each admin |
AI agents
With kitloom/ai installed, an agent whose user has view_telescope calls telescope_report (the last 1–168 hours, 24 by default): exceptions grouped by class and line with how often, the slowest requests with their path, status and template, failed jobs with their module and error, slow queries grouped by shape. It never gets request bodies, headers, sessions, emails or job data; the values in a query become ?.
For developers
Kitloom\Telescope\TelescopeDashboard (bound per request) is what the admins read: status() (recording, paused, off, tables-missing), label(), tone() (success, warning, danger), explanation(), url(), allows($user), hasTables(). It asks nothing of the database while Telescope is off. Kitloom\Telescope\Recording decides what is kept (keepsEntry(), batch()), Kitloom\Telescope\TelescopeSettings reads the options, Kitloom\Telescope\Testing\TelescopeTestCase boots the skeleton with Telescope on for a test.