mrpunyapal/telescope-inspect

Query Laravel Telescope data from Artisan: readable tables for people, stable versioned JSON for scripts, CI, agents, and tooling.

Maintainers

Package info

github.com/MrPunyapal/telescope-inspect

Homepage

pkg:composer/mrpunyapal/telescope-inspect

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 4

Open Issues: 0

v0.2.0 2026-08-24 16:12 UTC

This package is auto-updated.

Last update: 2026-08-24 18:42:21 UTC


README

Latest Version on Packagist Total Downloads CI License PHP Laravel Telescope Laravel Boost

Query Laravel Telescope data from the command line. It prints readable summaries for people and JSON for scripts, CI jobs, and other tools.

Telescope records a lot. Answering questions like "which routes were slow this hour" or "what keeps failing on the queue" usually means clicking through the dashboard or writing SQL against telescope_entries. This package gives you a command for it:

php artisan telescope:inspect --requests --last=1h
Requests · showing 50 of 184 · last 1h
--------------------------------------

 Avg 1.12s · P95 3.80s · Statuses: 200×171   500×9   302×4

 Method  URI                       Reqs   Avg     P95     Avg queries
 GET     /orders                   42     842ms   1.70s   38
 POST    /checkout                 17     1.94s   3.80s   61

Installation

Requires PHP 8.3 or newer, Laravel 11, 12, or 13, and Laravel Telescope ^5.0 with its migrations run.

composer require --dev mrpunyapal/telescope-inspect

The service provider is discovered automatically. Nothing else to configure.

Usage

Run it with no arguments for an overview of entry counts per type:

php artisan telescope:inspect

Pick entry types with flags:

php artisan telescope:inspect --requests --last=1h          # slow requests
php artisan telescope:inspect --queries --min-duration=500  # heavy queries
php artisan telescope:inspect --exceptions --last=24h       # recent exceptions
php artisan telescope:inspect --jobs --failed --last=24h    # failed jobs

All 18 Telescope entry types are supported: requests, queries, exceptions, jobs, commands, schedule, cache, dumps, events, gates, http (outgoing client requests), logs, mail, models, notifications, redis, views, batches. Each type has a fixed set of normalized fields; see the field reference.

Filters

Filter Example
Time window --last=15m · --from=2026-08-01 · --to="2026-08-02 14:30"
Limit --limit=100
Duration --min-duration=250 (milliseconds)
Route --route="*orders*" or --route=OrderController@store
HTTP --method=GET,POST · --status=500,404
Queue --failed · --connection=redis
Free text --search=checkout (matches tags or content)

Filters combine. For example:

php artisan telescope:inspect --http --status=500 --method=POST --last=6h

Single entries

php artisan telescope:inspect --show=<uuid>

Prints every normalized field for one entry. Sensitive fields need --full.

Batch replay

Every entry Telescope records during one request or job shares a batch id. Replay the whole lifecycle in recording order:

php artisan telescope:inspect --batch=<batch-id>

Watching live traffic

php artisan telescope:inspect --exceptions --watch

Prints new entries as they arrive. Add --ndjson for machine-consumable lines.

Analysis

Selecting requests, queries, exceptions, or jobs adds summaries:

  • Requests: average and P95 duration, status codes, slowest routes, queries per route.
  • Queries: slowest queries with caller location, most repeated SQL patterns, and likely N+1 detection (identical SQL repeated within one request). The N+1 check is a heuristic and is labeled as such.
  • Exceptions: signatures grouped by class, file, and line, with counts.
  • Jobs: status and queue distribution, failures with exception messages.

JSON

Add --json for machine-readable output. The output is valid JSON with no formatting or extra text on stdout (diagnostics go to stderr as plain text), and a versioned envelope keeps scripts stable across releases. The full machine-checkable contract lives in schema/telescope-inspect-v1.schema.json:

php artisan telescope:inspect --requests --queries --exceptions --jobs --last=1h --json
{
    "schema_version": "1.0",
    "command": "telescope:inspect",
    "generated_at": "2026-08-22T12:00:00.000000Z",
    "filters": { "types": ["request"], "last": "1h", "limit": 50 },
    "summary": {
        "total_entries_in_window": 184,
        "entries_by_type": { "request": 42 },
        "analysis": {
            "request": {
                "avg_duration_ms": 1120.5,
                "p95_duration_ms": 3800,
                "routes": [{ "uri": "/orders", "requests": 42, "avg_queries_per_request": 38 }]
            }
        }
    },
    "violations": [],
    "items": [{ "uuid": "...", "type": "request", "duration_ms": 842 }]
}

The envelope is versioned. Within schema version 1.x, existing keys keep their meaning and new keys may appear.

There is also --ndjson for one compact JSON object per line, which is convenient with tools like jq:

php artisan telescope:inspect --queries --last=1h --ndjson | jq 'select(.duration_ms > 500)'

AI agents

If the command runs under an AI coding agent (Claude Code, Cursor, OpenCode, Codex, Copilot and others, detected with laravel/agent-detector), output switches to the JSON contract automatically, so an agent can run the same command a human would and still get parseable data. The envelope carries an agent key naming what was detected.

Force human tables with --human, or disable the behavior entirely with the auto_json_for_agents config key.

Laravel Boost

The package ships a Boost skill (resources/boost/skills/telescope-inspect) that teaches agents when and how to use these commands, how to read the JSON envelope, and how to interpret the N+1 evidence. It installs automatically with php artisan boost:install in any Laravel project that has this package installed.

Exit codes

Code Meaning
0 Success
1 Runtime failure (missing Telescope tables, unknown UUID)
2 Invalid usage (bad filter values or combinations)
3 Issues found via --fail-on

Finding issues does not fail the command unless you pass --fail-on:

php artisan telescope:inspect --fail-on=exceptions,failed-jobs --last=15m
php artisan telescope:inspect --fail-on=slow-queries --min-duration=1000 --last=1h

Privacy

Telescope already masks configured hidden parameters before storing anything. This package additionally omits fields that tend to contain sensitive values (request payloads, headers, sessions, query strings, query bindings, stack traces, cache values, dumped variables, Redis command arguments) from all output. Pass --full when you actually need them, and treat that output as secret. The package makes no network requests.

Configuration

Defaults work without publishing anything. If you want to change redaction, truncation, scan limits, or the slow threshold:

php artisan vendor:publish --tag=telescope-inspect-config

See docs/configuration for the available keys.

Supported versions

Package Versions
PHP ^8.3
Laravel ^11.0 | ^12.0 | ^13.0
Laravel Telescope ^5.0

Composer resolves the intersection automatically: Laravel 12 needs Telescope 5.5+, Laravel 13 needs 5.18+. CI runs the full matrix on Linux and Windows (including lowest-bound installs and PHP 8.5) plus a MySQL integration job; everything else is SQLite-based. Only long-stable Telescope APIs are used (Storage\EntryModel, Contracts\EntriesRepository).

How it works

A read-only pipeline over Telescope's own tables: bounded SQL fetch, content normalization, per-type analyzers, then presentation. Full reference in docs/architecture.

Telescope storage
      ↓
EntryRepository          SQL filtering, bounded scans
      ↓
ContentNormalizer        raw content arrays to stable normalized fields
      ↓
Analyzers                request, query, exception, job aggregation
      ↓
InspectionResult         typed result object
      ↓
HumanPresenter · JsonPresenter

The Artisan command is a thin wrapper around TelescopeInspector::inspect(InspectFilters): InspectionResult. If you want to build tooling on top (an MCP server, an IDE plugin), use that service instead of querying Telescope yourself.

Scans are bounded (scan_limit, default 5000 newest rows) and long values are truncated (value_limit, default 1000 characters), so large Telescope tables stay safe to query.

Testing

composer test       # Pest suite against Testbench and real Telescope migrations
composer analyse    # PHPStan / Larastan level 6
composer lint       # Pint
composer check      # all of the above plus composer validate

Tests insert realistic Telescope rows into Telescope's actual migrations and query them back. Storage is not mocked.

Contributing

See CONTRIBUTING.md and the documentation site.

Security

Report vulnerabilities privately as described in SECURITY.md.

Changelog

Notable changes are listed in CHANGELOG.md.

License

MIT. See LICENSE.