Skip to content

fix: include sandbox id in session logs#575

Closed
ColeMurray wants to merge 2 commits into
mainfrom
fix/session-sandbox-logger-context
Closed

fix: include sandbox id in session logs#575
ColeMurray wants to merge 2 commits into
mainfrom
fix/session-sandbox-logger-context

Conversation

@ColeMurray
Copy link
Copy Markdown
Owner

@ColeMurray ColeMurray commented Apr 29, 2026

Summary

  • Add sandbox_id to the session Durable Object logger context when an existing sandbox row is available during initialization.
  • Refresh the DO logger context after sandbox spawn and sandbox WebSocket connect so subsequent logs include the Modal sandbox ID.
  • Include sandbox_id directly on sandbox event, prompt completion, and callback background error logs.

Tests

  • npm test -w @open-inspect/control-plane -- sandbox-events
  • npm run typecheck -w @open-inspect/control-plane

Created with Open-Inspect

Summary by CodeRabbit

  • Chores
    • Enhanced logging so sandbox identifiers are consistently attached to session requests and sandbox events for improved correlation and observability.
    • Logging can now be updated at runtime across session components, ensuring logs reflect current sandbox context throughout request handling and event processing.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 29, 2026

📝 Walkthrough

Walkthrough

Session logging was made dynamically rebindable to include sandbox_id context: the DO updates its child logger when sandbox IDs change and propagates the new logger to lifecycle, WebSocket, event processor, participant/callback/message-queue services; fetch() preserves and restores logger context across requests.

Changes

Cohort / File(s) Summary
Durable Object (Session) — logger anchoring
packages/control-plane/src/session/durable-object.ts
Adds loggerSandboxId state, refreshLoggerSandboxId() to create/re-anchor child logger with sandbox_id, preserves pre-request logger during fetch() and restores or rebinds consumers post-request when sandbox/correlation context changes.
Sandbox event processing
packages/control-plane/src/session/sandbox-events.ts
Adds setLog(log: Logger); threads sandboxId into heartbeat/token/non-completion logs and into structured error/prompt completion logs for event-level correlation.
Lifecycle manager
packages/control-plane/src/sandbox/lifecycle/manager.ts
Makes manager logger mutable and adds setLog(log: Logger) so the session-scoped lifecycle manager can receive updated logger instances at runtime.
Session services (workers of logger)
packages/control-plane/src/session/websocket-manager.ts, packages/control-plane/src/session/participant-service.ts, packages/control-plane/src/session/callback-notification-service.ts, packages/control-plane/src/session/message-queue.ts
Change log fields from readonly to mutable and add setLog(log: Logger) on each class (and interface update for WebSocket manager) so the DO can rebind these components to the child logger containing sandbox_id.

Sequence Diagram

sequenceDiagram
    participant DO as DurableObject(SessionDO)
    participant Repo as Repository
    participant Manager as SandboxLifecycleManager
    participant WS as SessionWebSocketManager
    participant Event as SessionSandboxEventProcessor
    participant Service as Participant/Callback/Queue

    DO->>Repo: repository.getSandbox() (maybe modal_sandbox_id)
    Repo-->>DO: sandbox_id?
    DO->>DO: refreshLoggerSandboxId()
    DO->>Manager: manager.setLog(childLogger)
    DO->>WS: ws.setLog(childLogger)
    DO->>Event: eventProc.setLog(childLogger)
    DO->>Service: participant/callback/queue.setLog(childLogger)

    alt HTTP fetch request
        DO->>DO: save current loggerSandboxId
        DO->>DO: handle request (may change sandbox)
        DO->>Repo: repository.getSandbox() (post-request)
        DO-->>DO: new sandbox_id?
        alt changed
            DO->>DO: re-anchor child logger
            DO->>Manager: manager.setLog(newChild)
            DO->>WS: ws.setLog(newChild)
            DO->>Event: eventProc.setLog(newChild)
            DO->>Service: participant/callback/queue.setLog(newChild)
        else unchanged
            DO->>DO: restore original logger
        end
    end

    Event->>Event: process sandbox event (heartbeat/token/prompt)
    Event->>DO: logs include sandbox_id
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰
Logs hop from burrow to sky so wide,
Sandbox IDs tucked safe inside,
Child log springs when the sandbox calls,
Rebound through sockets, queues, and halls,
A traceable trail where rabbits bide.

🚥 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 'fix: include sandbox id in session logs' accurately summarizes the main change: adding sandbox_id context to session logging across multiple components.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/session-sandbox-logger-context

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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

@github-actions
Copy link
Copy Markdown

Terraform Validation Results

Step Status
Format
Init
Validate

Note: Terraform plan was skipped because secrets are not configured. This is expected for external contributors. See docs/GETTING_STARTED.md for setup instructions.

Pushed by: @ColeMurray, Action: pull_request

Copy link
Copy Markdown
Contributor

@open-inspect open-inspect Bot left a comment

Choose a reason for hiding this comment

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

Summary

This PR updates session and sandbox-event logging so sandbox_id is carried more consistently through Durable Object initialization, sandbox spawn/connect transitions, and a few key event/error logs. I reviewed both changed files in context and did not find any blocking correctness, security, performance, or maintainability issues.

  • PR Title and number: fix: include sandbox id in session logs (#575)
  • Author: @ColeMurray
  • Files changed: 2
  • Diff stats: +30 / -8

Critical Issues

  • None.

Suggestions

  • None.

Nitpicks

  • None.

Positive Feedback

  • The fetch() logger restoration logic preserves request-scoped correlation while still updating the base logger when the sandbox ID becomes available mid-request.
  • The added sandbox_id fields target the highest-value logs (prompt.complete, background callback errors, and session lifecycle logs) without widening the scope unnecessarily.
  • Verification passed: npm test -w @open-inspect/control-plane -- sandbox-events and npm run typecheck -w @open-inspect/control-plane.

Questions

  • None.

Verdict

  • Approve: Ready to merge.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/control-plane/src/session/durable-object.ts`:
- Around line 773-779: The current refreshLoggerSandboxId replaces this.log but
leaves long-lived collaborators (those constructed earlier that captured the
original logger) unchanged; update the code so that when refreshLoggerSandboxId
runs it also rebinds or updates all logger-dependent singletons/helpers (the
instances that captured the logger at construction) by either (A) refactoring
those helpers to accept a getLog() callback and pass a closure that returns
this.log, or (B) storing and iterating a registry of logger consumers and
calling a provided setLog(newLog) on each; modify refreshLoggerSandboxId to call
that registry or callback so every consumer receives the new child logger and
the sandbox_id context is applied consistently.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: cbef8e5d-cdd7-49e7-bf5e-4f84717f83e3

📥 Commits

Reviewing files that changed from the base of the PR and between 352bda0 and 3a9c950.

📒 Files selected for processing (2)
  • packages/control-plane/src/session/durable-object.ts
  • packages/control-plane/src/session/sandbox-events.ts

Comment thread packages/control-plane/src/session/durable-object.ts
@github-actions
Copy link
Copy Markdown

Terraform Validation Results

Step Status
Format
Init
Validate

Note: Terraform plan was skipped because secrets are not configured. This is expected for external contributors. See docs/GETTING_STARTED.md for setup instructions.

Pushed by: @open-inspect[bot], Action: pull_request

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
packages/control-plane/src/session/durable-object.ts (1)

784-791: ⚠️ Potential issue | 🟠 Major

Rebind currently misses PresenceService logger consumer.

PresenceService is created with log: this.log (Line 257-268) but is not updated in rebindLoggerConsumers(), so its logs can keep stale context after sandbox_id changes.

Suggested follow-up
  private rebindLoggerConsumers(): void {
    this._wsManager?.setLog(this.log);
    this._lifecycleManager?.setLog(this.log);
    this._participantService?.setLog(this.log);
    this._callbackService?.setLog(this.log);
    this._messageQueue?.setLog(this.log);
    this._sandboxEventProcessor?.setLog(this.log);
+   this._presenceService?.setLog(this.log);
  }

Also add setLog(log: Logger) to PresenceService if it does not already exist.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/control-plane/src/session/durable-object.ts` around lines 784 - 791,
The rebindLoggerConsumers method omits the PresenceService causing its logger to
remain stale; update rebindLoggerConsumers to call
this._presenceService?.setLog(this.log) alongside the other consumers, and if
PresenceService lacks a setLog(log: Logger) method, implement it (e.g., store
the new logger and use it for subsequent logging) so PresenceService's logs
reflect the current sandbox context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/control-plane/src/session/durable-object.ts`:
- Around line 784-791: The rebindLoggerConsumers method omits the
PresenceService causing its logger to remain stale; update rebindLoggerConsumers
to call this._presenceService?.setLog(this.log) alongside the other consumers,
and if PresenceService lacks a setLog(log: Logger) method, implement it (e.g.,
store the new logger and use it for subsequent logging) so PresenceService's
logs reflect the current sandbox context.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ebafb3f9-cc22-44d5-9a54-f7ef7f23ac12

📥 Commits

Reviewing files that changed from the base of the PR and between 3a9c950 and 50eb184.

📒 Files selected for processing (7)
  • packages/control-plane/src/sandbox/lifecycle/manager.ts
  • packages/control-plane/src/session/callback-notification-service.ts
  • packages/control-plane/src/session/durable-object.ts
  • packages/control-plane/src/session/message-queue.ts
  • packages/control-plane/src/session/participant-service.ts
  • packages/control-plane/src/session/sandbox-events.ts
  • packages/control-plane/src/session/websocket-manager.ts

@ColeMurray ColeMurray closed this Apr 29, 2026
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