Architecture
Telescope Inspect is a read-only view over Telescope's own storage. One Artisan command, one pipeline, no background processes.
Pipeline
telescope:inspect flags
|
InspectFilters CLI flags to a validated value object (exit 2 on garbage)
|
EntryRepository bounded SQL against telescope_entries
| newest-first, capped by scan_limit, parameterized
|
ContentNormalizer raw content JSON to stable per-type fields
|
Analyzers request / query / exception / job aggregation
|
InspectionResult typed result object
|
HumanPresenter terminal tables JsonPresenter --json / --ndjson envelope
The Artisan command (src/Commands/InspectCommand.php) is a thin wrapper. Everything above it is plain PHP you can call directly:
use MrPunyapal\TelescopeInspect\TelescopeInspector;
use MrPunyapal\TelescopeInspect\Filters\InspectFilters;
$result = app(TelescopeInspector::class)->inspect(
InspectFilters::fromArray(['types' => ['request'], 'last' => '1h'])
);
This is the intended integration point for tooling built on top (MCP servers, IDE plugins, dashboards).
Storage access rules
- Read-only: the package never inserts, updates, or deletes Telescope rows.
- Bounded scans: every listing and analysis reads at most
scan_limitrows (default 5000, clamped to 100..50000), newest first. A huge production table cannot produce an unbounded query. - Parameterized SQL only: all queries go through Laravel's query builder; no string interpolation.
- Type partitioning: one bounded fetch is split in memory per type rather than issuing a query per selected type.
Normalization
Each of the 18 entry types has a fixed field map defined in ContentNormalizer. Raw Telescope content payloads vary by Telescope version and watcher configuration; normalization guarantees consumers always see the same keys for a type, with absent values as null. Sensitive fields are dropped before presentation unless --full or redact_sensitive: false.
Analysis scope
Analyzers run over the most recent matching entries within the resolved time window, independent of the listing --limit. The N+1 detector is a heuristic: identical normalized SQL executing at least 10 times inside one request batch. It is reported as "likely", never as fact.
The JSON contract
JsonPresenter emits a versioned envelope (schema_version). Within 1.x, existing keys keep their meaning and new keys may be added; breaking changes bump the major version. See JSON output.
Testing approach
The Pest suite boots Orchestra Testbench with real Telescope migrations on SQLite and inserts realistic rows via tests/Fixtures/EntryFactory.php, then asserts on actual command output. Storage is never mocked, so SQL, normalization, and analysis are exercised end to end.
What the package deliberately does not do
- No writes, pruning, or pausing of Telescope; use the shipped
telescope:clear,telescope:prune,telescope:pause,telescope:resume. - No network calls, telemetry, or license checks.
- No dashboard UI; the JSON envelope exists so tools can build their own.