Skip to content

Observability

AgentSessions emits structured log/slog events across the Sessions gRPC boundary, placement, controller, harness transport, and runtime backends. A request ID is propagated through gRPC metadata so one turn can be reconstructed across the host and harness processes. The reusable helpers and gRPC interceptors are exported from the public observability package.

Boundary operations (grpc and session) emit start and finish events at INFO. Internal placement, controller, and runtime operations emit the same pairs at DEBUG; their failures are promoted based on error_kind. At an INFO threshold, an internal failure can therefore appear without its debug start record. Stable fields are:

Field Meaning
component grpc, session, placement, controller, or a runtime such as runtime.substrate
operation Stable machine-readable operation name
phase start or finish
outcome success or error on finish events
duration_ms End-to-end operation duration on finish events
request_id Correlation ID propagated over gRPC
session_uid Session correlation where available
error_kind Stable error category; logs do not depend on parsing error text

Operations add bounded fields such as runtime, incarnation_id, actor, atespace, expected_last_seq, and record/effect counts. Placement records its capability decision and runtime backends record external lifecycle calls such as actor creation, resume, suspend, and deletion.

Library components default to a discard logger. The process that assembles them must inject one:

logger := slog.Default()
backend := local.New(harness, local.WithLogger(logger))
placer := placement.New(backend, model, placement.WithLogger(logger))
service := session.NewService(store, placer, session.WithLogger(logger))

Use observability.UnaryServerInterceptor and observability.StreamServerInterceptor on gRPC servers, and the corresponding client interceptors, to preserve request_id across process boundaries. cmd/agentctl and cmd/harnessnode provide reference wiring.

Use the grpc.Chain*Interceptor and grpc.WithChain*Interceptor options when composing these with authentication, tracing, or other interceptors.

Operational logs deliberately exclude:

  • message, prompt, and response contents
  • tool arguments and results
  • fence-token values
  • snapshot URIs
  • raw error strings, which may contain payload data

Use error_kind, gRPC status, identifiers, counts, and durations for diagnosis.