feat(tracing): add opt-in long-running session spans#98
Conversation
Long-running opencode sessions currently get a new root opencode.session span per turn, so a session spanning many turns shows up as disconnected traces instead of one cohesive trace. Set OPENCODE_LONG_RUNNING_SESSION_SPANS to keep a single root span open for a primary session's entire lifetime (session.created through session.deleted), with every turn's LLM/tool spans nesting under it. Off by default to preserve existing behavior; subagent sessions already nest under their parent regardless of the flag. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 34 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds an ChangesLong-running session spans feature
Estimated code review effort: 3 (Moderate) | ~30 minutes Sequence Diagram(s)sequenceDiagram
participant OpenCode
participant PluginIndex as src/index.ts
participant SessionHandler as session.ts
participant OTEL as OTEL SDK
OpenCode->>PluginIndex: session.created event
PluginIndex->>SessionHandler: handleSessionCreated(ctx)
SessionHandler->>OTEL: start opencode.session span (root, long-lived)
OpenCode->>PluginIndex: session.idle event
PluginIndex->>SessionHandler: handleSessionIdle(ctx)
SessionHandler->>OTEL: update session totals attributes (span stays open)
OpenCode->>PluginIndex: session.deleted event
PluginIndex->>SessionHandler: handleSessionDeleted(ctx)
SessionHandler->>OTEL: set final attributes, status OK, end span
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/handlers/session.ts (1)
247-270: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider emitting an OTel log record for
session.deleted, matchingsession.created/session.idle.Both
handleSessionCreatedandhandleSessionIdlecallctx.emitLog(...)to produce an OTel log record in addition to the internal plugin log.handleSessionDeletedonly callsctx.log("debug", ...), so session deletion won't show up in exported OTel logs, breaking parity across the session lifecycle events.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/handlers/session.ts` around lines 247 - 270, handleSessionDeleted currently only writes the internal debug log, so it misses the OTel log record that session.created and session.idle emit. Update handleSessionDeleted in session.ts to also call ctx.emitLog for the session.deleted event, using the same sessionID payload and keeping the existing ctx.log("debug", ...) call so deletion is represented consistently across the session lifecycle.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/handlers/session.ts`:
- Around line 247-267: `handleSessionDeleted` finalizes the session span without
setting `agent.type`, so it can keep the initial placeholder value instead of
the last known agent type. Update the `handleSessionDeleted` flow in
`src/handlers/session.ts` to match the attribute handling used in
`handleSessionIdle`, and include `agent.type` in the `sessionSpan.setAttributes`
call when `totals` is available. Use the existing `AGENT_NAME` and
`totals.agentType` fields to keep the span attributes consistent across idle and
deleted session paths.
In `@src/index.ts`:
- Around line 179-192: The shutdown finalization loop in the session span
cleanup is missing the same agent type attribute as the deletion path. Update
the attribute-setting logic in the span finalization flow around the session
span iteration to include agent.type from the session totals, matching the
behavior in handleSessionDeleted in src/handlers/session.ts and keeping the two
code paths consistent.
---
Nitpick comments:
In `@src/handlers/session.ts`:
- Around line 247-270: handleSessionDeleted currently only writes the internal
debug log, so it misses the OTel log record that session.created and
session.idle emit. Update handleSessionDeleted in session.ts to also call
ctx.emitLog for the session.deleted event, using the same sessionID payload and
keeping the existing ctx.log("debug", ...) call so deletion is represented
consistently across the session lifecycle.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d487dbc8-1d4a-4351-8ab0-a7b76c843f95
📒 Files selected for processing (9)
README.mdsrc/config.tssrc/handlers/session.tssrc/index.tssrc/types.tstests/config.test.tstests/handlers/session.test.tstests/handlers/spans.test.tstests/helpers.ts
handleSessionDeleted and the shutdown finalization loop set agent name but not agent.type on the closing span, unlike handleSessionIdle. Also add the missing session.deleted OTLP log event, matching the pattern used by session.created/session.idle/session.error. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace the stale 2026-07-05 known-issue block. Document the opt-in OPENCODE_LONG_RUNNING_SESSION_SPANS flag, note the change lives in DEVtheOPS/opencode-plugin-otel#98 (unmerged), and that Trace Explorer works either way.
Summary
OPENCODE_LONG_RUNNING_SESSION_SPANS(and the matchinglongRunningSessionSpansplugin option) to keep one rootopencode.sessionspan open for a primary session's entire lifetime — fromsession.createdthroughsession.deleted— instead of starting a new root span for every turn.session.idle, so a long-running opencode session (many turns over minutes/hours) shows up as one cohesive trace in the backend instead of a series of disconnected per-turn traces.handleSessionDeletedto finalize the long-lived session span and clear per-session totals onsession.deleted(previously only handled onsession.idle).Test plan
bun run typecheckbun run lintbun run check:jsdoc-coveragebun test(312 pass)session.deletedcleanup of totals/span.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Documentation