Issue trackers (GitHub / Sentry / Linear)
Issue trackers
Issue trackers are a fourth signal alongside metrics, traces and logs — the
same connection + driver pattern, behind an IssuesSource contract. Configure
one and an Issues page appears in the sidebar, listing open issues/PRs next
to the telemetry so a spike and its ticket live together.
Set the driver on the issues connection (nothing shows until you do):
GitHub
TELEMETRY_UI_ISSUES_DRIVER=github
TELEMETRY_UI_GITHUB_REPO=cboxdk/laravel-telemetry-ui
TELEMETRY_UI_ISSUES_TOKEN=ghp_… # repo scope; a fine-grained read-only token is enough
Lists issues and pull requests for the repo (PRs are badged separately).
Sentry
'issues' => [
'driver' => 'sentry',
'org' => 'cbox',
'project' => 'web',
'url' => 'https://sentry.io', // or your self-hosted URL
'token' => env('TELEMETRY_UI_ISSUES_TOKEN'), // auth token, project:read
],
The closest fit to the built-in Exceptions view — issue groups with event counts and first/last seen.
Linear
'issues' => [
'driver' => 'linear',
'token' => env('TELEMETRY_UI_ISSUES_TOKEN'), // Linear API key (sent as-is, not Bearer)
'team' => 'CBOX', // optional team key filter
],
Queried over Linear's GraphQL API.
Verification status
Honest state of what has been exercised against real APIs, so you know what to trust in this alpha:
| Tracker | Read | Create |
|---|---|---|
| GitHub | ✅ live-verified | ✅ live-verified |
| Linear | ✅ live-verified (auth, filter, field mapping) | ✅ live-verified |
| Sentry | ⚠️ tested against realistic fixtures, not yet against a live instance | n/a (read-only) |
All three have unit tests over realistic payloads. Sentry's response shape is coded from its API docs; if you run it against a live project and something is off, please open an issue.
Adding your own tracker
Implement Cbox\TelemetryUi\Contracts\IssuesSource (list issues with a
state/search filter, plus label() and url()), then teach the manager the
driver:
$this->callAfterResolving(ConnectionManager::class, function ($manager) {
$manager->extend('jira', fn (array $config) => new JiraSource(...));
});
Config driver => 'jira' and the Issues page uses it. The action side —
creating a ticket from an exception, posting to Slack — is a deliberate future
layer on top of this read side.
Creating tickets from exceptions
Trackers that can write (GitHub, Linear — not Sentry) implement the optional
Cbox\TelemetryUi\Contracts\CreatesIssues capability. When one is configured,
the Exceptions table shows a + ticket action per class: it opens a compose
form in the drawer, prefilled with the analysis (exception class, occurrence
count, period, scope and a deep-link to the error traces). Edit and submit, and
the drawer lands on the freshly created ticket — never leaving the dashboard.
-
GitHub needs a token with issue write (repo scope, or a fine-grained token with Issues: read & write).
-
Linear needs the team's UUID to create:
'issues' => [ 'driver' => 'linear', 'token' => env('TELEMETRY_UI_ISSUES_TOKEN'), 'team' => 'CBOX', // team key, for filtering 'team_id' => env('TELEMETRY_UI_LINEAR_TEAM_ID'), // team UUID, for creating ],
Relations
Issues aren't a dead end — they cross-link with the telemetry:
- Issue → trace. Clicking an issue opens it in the slide-in drawer (title, labels, author, full body) without leaving the list. Any 32-hex trace id in the title/body becomes a link that opens the trace waterfall in the same drawer.
- Exception → issue. The Exceptions table shows a "⧉ issues" link per class (when a tracker is configured) that jumps to the Issues page pre-searched for that exception, so a spike lands on its ticket.
- Labels/tags. Click a label on any issue to filter the list by it, or use the label dropdown; the filter is URL-backed so the view is shareable.