Skip to content

feat(tracing): add opt-in long-running session spans#98

Open
schemaitat wants to merge 2 commits into
DEVtheOPS:mainfrom
schemaitat:feat/long-running-session-spans
Open

feat(tracing): add opt-in long-running session spans#98
schemaitat wants to merge 2 commits into
DEVtheOPS:mainfrom
schemaitat:feat/long-running-session-spans

Conversation

@schemaitat

@schemaitat schemaitat commented Jul 6, 2026

Copy link
Copy Markdown

Summary

  • Adds OPENCODE_LONG_RUNNING_SESSION_SPANS (and the matching longRunningSessionSpans plugin option) to keep one root opencode.session span open for a primary session's entire lifetime — from session.created through session.deleted — instead of starting a new root span for every turn.
  • With the flag enabled, every turn's LLM and tool spans nest under the same long-lived session span across 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.
  • Off by default, preserving current per-turn root span behavior. Subagent sessions are unaffected by the flag — they already nest under their parent session's trace for the parent's lifetime.
  • Adds handleSessionDeleted to finalize the long-lived session span and clear per-session totals on session.deleted (previously only handled on session.idle).

Test plan

  • bun run typecheck
  • bun run lint
  • bun run check:jsdoc-coverage
  • bun test (312 pass)
  • Added/updated tests covering: flag off (default, no change to existing behavior), flag on (root span persists across idle, later turns' LLM/tool spans nest under it, span finalized only on deletion), and session.deleted cleanup of totals/span.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a new setting to keep session tracing spans open for the full lifetime of a session.
    • Session spans can now continue across idle periods and close when the session is deleted.
  • Bug Fixes

    • Preserved accumulated session data across idle events so later activity can continue from the same session span.
    • Improved span cleanup at shutdown and session deletion.
  • Documentation

    • Updated the configuration docs with the new setting, behavior, and usage guidance.

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>
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@schemaitat, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 34 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 18cc2d8c-e56c-464b-90eb-d7a7e5ed1a65

📥 Commits

Reviewing files that changed from the base of the PR and between 14643b9 and 4bf139f.

📒 Files selected for processing (3)
  • src/handlers/session.ts
  • src/index.ts
  • tests/handlers/session.test.ts
📝 Walkthrough

Walkthrough

Adds an OPENCODE_LONG_RUNNING_SESSION_SPANS config option that keeps a root opencode.session span open across a primary session's full lifetime instead of per turn. Session lifecycle handlers, shutdown logic, and tests are updated to defer span finalization to a new handleSessionDeleted handler.

Changes

Long-running session spans feature

Layer / File(s) Summary
Config and type definitions
src/config.ts, src/types.ts, tests/config.test.ts
longRunningSessionSpans boolean added to PluginConfig, OtelPluginOptions, and HandlerContext; loadConfig() resolves it from options or the env var, with default-false and override tests.
Session handler lifecycle
src/handlers/session.ts, tests/handlers/session.test.ts
handleSessionCreated attaches a long-lived root span for primary sessions when enabled; handleSessionIdle no longer clears totals/ends the span; new handleSessionDeleted finalizes attributes, status, and cleanup.
Plugin wiring and shutdown
src/index.ts
Wires session.deleted to handleSessionDeleted, passes the flag into HandlerContext, logs when enabled, and finalizes all open session spans during shutdown.
Span lifecycle tests and helpers
tests/handlers/spans.test.ts, tests/helpers.ts
makeCtx gains the new flag; tests cover span nesting/persistence across session.created/idle/deleted and disabled-trace scenarios.
Documentation
README.md
Adds TOC entry, config table rows, and a new section explaining the long-running session spans behavior.

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
Loading

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: dialupdisaster

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: an opt-in feature for long-running session spans in tracing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/handlers/session.ts (1)

247-270: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider emitting an OTel log record for session.deleted, matching session.created/session.idle.

Both handleSessionCreated and handleSessionIdle call ctx.emitLog(...) to produce an OTel log record in addition to the internal plugin log. handleSessionDeleted only calls ctx.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

📥 Commits

Reviewing files that changed from the base of the PR and between 127f38a and 14643b9.

📒 Files selected for processing (9)
  • README.md
  • src/config.ts
  • src/handlers/session.ts
  • src/index.ts
  • src/types.ts
  • tests/config.test.ts
  • tests/handlers/session.test.ts
  • tests/handlers/spans.test.ts
  • tests/helpers.ts

Comment thread src/handlers/session.ts
Comment thread src/index.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>
schemaitat added a commit to schemaitat/opencode-otel-observability that referenced this pull request Jul 6, 2026
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant