Skip to content

Correlate client-side command-stream cancellation with envd logs (shared request-id) #1877

Description

@AdaAibaby

Summary

When a command stream (Process.Start, most visibly commands.run) is cancelled from the client side, there is no shared identifier to join the client-side reason with the server-side (envd) log line. Operators can only correlate by sandbox id + timestamp, which is ambiguous under concurrency.

This is the client-side half of the observability gap that the server-side change e2b-dev/runtime#3647 starts to address.

Background

envd runs the guest process on a context decoupled from the streaming RPC (context.Background()-derived), so cancelling the stream does not kill the process — it runs to completion. A client that stops reading the stream (request timeout, a sibling task cancelling, the caller exiting, or an explicit disconnect()) therefore produces, on the server:

Process start (server stream end) error="context canceled" error_code=... operation_id=17

Two problems, one on each side:

  • Server (envd): the log line cannot know why the client went away. fix(envd): distinguish client-cancel from errors in process stream logging runtime#3647 improves this by downgrading client-cancel from ERROR to INFO, mapping the code correctly, and annotating the cancel phase — but it still cannot attribute the client reason.
  • Client (SDK): CommandHandle (_handle_events / wait / disconnect) logs nothing when the stream is cancelled or disconnected, even though the SDK already carries a logging.Logger via ConnectionConfig. And disconnect() explicitly stops reading without killing the process — exactly the "process exited 0 but no result was collected" case — with no client-side trace.

The correlation gap

  • The operation_id in envd logs is assigned server-side (AssignOperationID, a monotonic counter). The client never sees it.
  • envd does not read any client-supplied request/correlation header (AddRequestIDToContext only assigns its own).

So there is no id today that appears in both the SDK logs and the envd logs. Joining them requires one.

Proposal

  1. SDK generates a per-call correlation id and sends it as a request header (e.g. X-E2B-Request-Id) on the streaming RPCs.
  2. envd reads that header (falling back to its own assigned id when absent) and includes it in the stream log lines alongside operation_id.
  3. SDK logs the local cancel cause (timeout / sibling-cancel / caller-exit / explicit disconnect / RPC error) via the existing ConnectionConfig.logger, tagged with the same correlation id.

Result: the envd "server stream end" line and the SDK cancel log become joinable by id, and each line carries the half of the story the other side cannot see.

Scope / rollout

  • Cross-repo: SDK (this repo, e2b-dev/E2B) + envd (e2b-dev/runtime). Backward compatible — envd falls back to its own id when the header is absent, so older SDKs keep working.
  • Can land incrementally: (a) SDK-side cancel-cause logging alone is already useful (correlate by sandbox id + timestamp); (b) the shared header closes the loop.

Opening this to align on the header name and direction before implementing. Related server-side work: e2b-dev/runtime#3647.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    envdfeatureNew feature or requestsdkImprovements or additions to SDKs

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions