-
-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Context
AI agents (Junior, Warden) need to self-diagnose by reviewing Sentry traces. Today sentry trace view --json dumps the full nested span tree (up to 10,000 spans) — unusable for an LLM context window. There's no way to list/filter/drill-into individual spans. We need span as a first-class entity with list and view subcommands.
Agent Self-Diagnosis Workflow
# 1. Overview: what happened in this trace?
sentry trace view <trace-id> --json
# 2. List + filter spans
sentry span list <trace-id> --json -q "op:db.* duration:>100ms" --sort duration
# 3. Drill into specific spans (multiple IDs, like log view)
sentry span view <span-id> <span-id> --trace <trace-id> --json
# 4. Correlated logs (already exists)
sentry trace logs <trace-id> --jsonsentry span list
Follows existing target resolution pattern used across the CLI.
Usage:
sentry span list <trace-id> # auto-detect org/project
sentry span list <org>/<project> <trace-id> # explicit org and project
sentry span list <project> <trace-id> # find project across all orgs
Flags:
| Flag | Type | Default | Description |
|---|---|---|---|
--query / -q |
string | — | Filter spans locally (Sentry-style syntax: op:db.* duration:>100ms) |
--limit / -n |
number | 50 | Max spans (1–10000) |
--sort / -s |
time | duration |
time |
Chronological or slowest-first |
--json |
boolean | — | Injected by buildCommand |
--fields |
string[] | — | Injected by buildCommand |
--fresh / -f |
boolean | false | Bypass cache |
Query syntax (client-side filtering on fetched trace data):
op:db.query— exact op matchop:db.*orop:db— prefix match (db matches db.query, db.redis)duration:>100ms— min duration filterduration:<1s— max duration filterproject:backend— filter by project slug- Multiple terms AND together:
op:db duration:>100ms
JSON output:
Human output: Table with columns Span ID | Op | Description | Duration | Depth.
sentry span view <span-id> [<span-id>...] --trace <trace-id>
Follows log view multi-ID pattern. Span ID is the primary entity (positional). --trace is a required flag (existing convention from log list --trace).
Usage:
sentry span view <span-id> --trace <trace-id> # single, auto-detect
sentry span view <span-id> <span-id> --trace <trace-id> # multiple
sentry span view <org>/<project> <span-id> --trace <trace-id> # explicit target
sentry span view <project> <span-id> --trace <trace-id> # project search
Flags:
| Flag | Type | Default | Description |
|---|---|---|---|
--trace |
string (required) | — | Trace ID (validated via validateTraceId) |
--spans |
number | 3 | Children depth (reuse spansFlag) |
--web / -w |
boolean | false | Open trace in browser |
--json |
boolean | — | Injected |
--fields |
string[] | — | Injected |
--fresh / -f |
boolean | false | Bypass cache |
Key feature: ancestor chain. When viewing a span, show the full path from root → parent → this span, so the agent sees the full context of where this span sits in the trace.
Human output (single span):
## Span `abc123def456ab01`
Op: db.query
Description: SELECT * FROM users WHERE id = ?
Duration: 1.82s
Project: backend
Transaction: GET /api/users
Started: 2024-01-15 10:30:45
### Trace Context
Trace ID: ed29abc871c4475b...
### Ancestors (root → this span)
http.server — GET /api/users (2.4s)
└─ middleware — authMiddleware (45ms)
└─ handler — getUserHandler (1.9s)
└─ ▶ db.query — SELECT * FROM users (1.82s)
### Children (3)
├─ db.query — SELECT * FROM user_settings (245ms)
├─ cache.get — user:preferences:123 (12ms)
└─ http.client — POST analytics.example.com/event (89ms)
For multiple spans: separate with --- dividers (same as log view).
JSON output (multiple spans):
[
{
"span_id": "abc123",
"op": "db.query",
"description": "SELECT * FROM users WHERE id = ?",
"duration_ms": 1823,
"start_timestamp": 1710000000.123,
"project_slug": "backend",
"transaction": "GET /api/users",
"depth": 2,
"ancestors": [
{ "span_id": "root1", "op": "http.server", "description": "GET /api/users" },
{ "span_id": "mid1", "op": "middleware", "description": "authMiddleware" }
],
"children": [
{ "span_id": "child1", "op": "db.query", "description": "SELECT...", "duration_ms": 245 }
]
}
]Design Decisions
- Standard target resolution —
[<org>/<project>]or<project>positional, same as trace view, event view, etc. --traceas flag on span view — matches existinglog list --traceconvention; keeps span ID as the primary entity- Query-based filtering over dash-dash flags —
-q "op:db duration:>100ms"instead of--op db --min-duration 100; minimizes flag proliferation - Ancestor chain in span view — agents need to understand WHERE in the trace a span lives, not just the span in isolation
- Multiple span IDs — follows
log viewpattern; agents often want to compare a few spans - Return-based output — uses the new
OutputConfig/CommandOutputpattern from recent refactor
{ "data": [ { "span_id": "abc123", "parent_span_id": "...", "op": "db.query", "description": "SELECT * FROM users", "duration_ms": 1823, "start_timestamp": 1710000000.123, "project_slug": "backend", "transaction": "GET /api/users", "depth": 2, "child_count": 0 } ], "hasMore": false, "totalSpans": 8432, "matchedSpans": 42 }