cboxdk / laravel-telemetry-ui
Laravel-native observability UI for cboxdk/laravel-telemetry: a versioned JSON API plus a React SPA that queries Tempo, Loki and Prometheus/Mimir directly.
Requires
- php: ^8.3|^8.4|^8.5
- cboxdk/laravel-telemetry: ^2.5
- illuminate/contracts: ^12.0|^13.0
- illuminate/http: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- laravel/mcp: ~0.8.2 || ^0.9 || ^1.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- v2.5.3
- v2.5.2
- v2.5.1
- v2.5.0
- v2.4.1
- v2.4.0
- v2.3.0
- v2.2.0
- v2.1.1
- v2.1.0
- dev-main / 2.0.x-dev
- v2.0.1
- v2.0.0
- 1.x-dev
- v1.9.0
- v1.8.0
- v1.7.0
- v1.6.0
- v1.5.0
- v1.4.1
- v1.4.0
- v1.3.0
- v1.2.0
- v1.1.0
- v1.0.0
- v0.4.0
- v0.3.0
- v0.2.1
- v0.2.0
- v0.1.0-alpha.6
- v0.1.0-alpha.5
- v0.1.0-alpha.4
- v0.1.0-alpha.3
- v0.1.0-alpha.2
- dev-fix/preserve-spankind
- dev-fix/outgoing-groupby-presence
- dev-fix/outgoing-kind-in-explore
- dev-fix/outgoing-hosts-and-transfer-phases
- dev-fix/filter-bar-keys
- dev-fix/portable-metrics-probe
- dev-feat/v2-spa
This package is auto-updated.
Last update: 2026-09-25 07:34:20 UTC
README
Grafana-replacement observability UI for Laravel — queries your existing
Tempo (traces), Loki (logs) and Prometheus/Mimir (metrics) directly. No
agent, no vendor cloud, no data leaves your infrastructure. The presentation
counterpart to
cboxdk/laravel-telemetry,
schema-aware of every metric and span attribute it emits.
v2 replaces the Livewire UI with a versioned JSON API and a React app the package serves itself. Coming from 1.x? Read UPGRADE.md and the CHANGELOG first.
Why not just Grafana?
Grafana is generic; this dashboard knows what a Laravel app is. Routes, jobs, scheduled tasks, queries, cache stores and users are first-class concepts, cross-linked across signals — click a slow route, see its traces; open a trace, see the queries, the trace-correlated logs, and the host it ran on. And it lives inside your app: your auth, your gate, and actions a read-only dashboard can't do (open a ticket from an exception, talk to it over MCP).
Highlights
- JSON API + SPA — a versioned JSON API under
{path}/api/v2and a React app that talks to it over plainfetch. The built app is committed topublic/buildand served by the package, so hosts need no Node toolchain. - Explore — one surface over requests, traces, logs and errors: filter by
any attribute (
where[]=http.route=/checkout), group by any key, a time × latency heatmap on top, a virtualised result list below. - Dimensions — declare the attributes that matter to you
(
TelemetryUi::dimension('billing.customer_id', label: 'Customer')) and they show up as facets, group-by options, filter chips and clickable chips, with an optional link back into your app. Show names instead of ids (TelemetryUi::resolve('user.id', User::class, 'name')), or read a dimension out of another attribute when a routing layer encodes it there (from: 'http.route', pattern: 'portal:{value}'). - Entity pages — a route, query, job, host, user or customer is a page that tells a story: RED, trend with deploys, where failures concentrate, correlated error groups, slowest and failing traces. Raw attributes come last.
- Laravel-shaped screens — Dashboard, Requests, Jobs, Queues, Commands, Scheduled Tasks, Exceptions, Queries, Cache, Outgoing, Mail & Notifications, Hosts, Logs, System, Web Vitals, Analytics, plus a full trace waterfall.
- Signal correlation — a trace shows the host/runtime signals recorded around it (CPU, load, memory, network, RSS), each flagged against its typical baseline ("Host CPU 95%, typical 30%").
- Annotations — deploy/incident/scaling/version markers on every chart,
written through the telemetry pipeline (
telemetry-ui:annotate) and auto-detected for un-announced deploys (telemetry-ui:scan-versions). - Issue trackers — GitHub, Sentry and Linear as a fourth signal; create a ticket from an error group without leaving the drawer.
- MCP server — metrics, traces, logs and the correlation tools over the
Model Context Protocol (
php artisan mcp:start telemetry-ui, or HTTP with OAuth + Dynamic Client Registration) for agent-driven incident RCA. - Fleet-aware & autodetecting — a service/environment switcher scopes every
screen; optional schema families (e.g.
cboxdk/statamic-telemetry) light up their own pages when their metrics exist. - Extensible in PHP — add pages and panels with plain PHP classes that
return a typed payload (
Ui::table(),Ui::stats(), a chart), or declare a chart over any metric withTelemetryUi::metricPanel()— no class, which is how a sidecar in another language gets its own page. No JS build on your side. - Embeddable — mount panels, Explore, entity pages and traces as React
components inside your own React/Inertia app. They ship inside the composer
package, so npm installs them from
vendor/; no registry. - Fast to work in — filter-bar value typeahead, ⌘K, keyboard triage (
j/kthrough traces,[/]to step the time window), saved views, the compiled TraceQL/LogQL behind any view with copy-as-curl, and no dead ends: every number that names a subset opens it. - Inert when idle — boot registers class-string maps only; disable with one env var.
Install
composer require cboxdk/laravel-telemetry-ui
PHP 8.3+, Laravel 12 or 13. No Node toolchain — the UI ships prebuilt.
cboxdk/laravel-telemetry is a hard dependency — it defines the schema this
UI reads, and provides the write path for annotations (the dashboard also
instruments its own stack).
TELEMETRY_UI_METRICS_URL=http://prometheus:9090 TELEMETRY_UI_TEMPO_URL=http://tempo:3200 TELEMETRY_UI_LOKI_URL=http://loki:3100
Already run a Grafana Cloud / hosted LGTM stack? Point at the datasource proxy instead — see connect through a Grafana proxy.
Then visit /telemetry-ui. The SPA and its assets are served by the package —
no publishing, no npm step. Access is gated by the viewTelemetryUi gate,
which allows only the local environment by default — open it up in your
app:
Gate::define('viewTelemetryUi', fn ($user) => $user?->isAdmin() ?? false);
Documentation
Full documentation lives in docs/:
- Getting started
- Connections · Configuration reference · Signal correlation
- Pages & panels · Dimensions & Explore · JSON API
- Cookbook: Grafana proxy · annotations · MCP · embed in your own app
- Extending: developer integrations (start here) · custom panels · custom detail pages · custom drivers · issue trackers
- Design direction · ADRs · Roadmap
Development
composer check # pint + phpstan (level 8) + pest — must pass npm install npm test # vitest (SPA unit tests) npm run build # typecheck + vite build into public/build (commit the result)
The SPA source lives in resources/app/. After any UI change, run
npm run build and commit public/build — hosts install the package without
Node, so the built assets are part of the release.
License
MIT — see LICENSE.md.