Default: no-op
WithoutWithObservabilityConfig or WithTracer, the agent uses built-in no-op tracers. Zero overhead.
Wire OTLP (recommended)
Requires a running OpenTelemetry-compatible collector (e.g. OpenTelemetry Collector or Jaeger). Quick local setup:WithObservabilityConfig:
Insecure: true disables TLS on the collector connection. Use only in development or trusted internal networks. Omit it (defaults to TLS) for production OTLP endpoints.| Field | Description |
|---|---|
Endpoint | OTLP collector URL — e.g. collector:4317 (gRPC) or http://collector:4318 (HTTP) |
Protocol | OTLPProtocolGRPC (default) or OTLPProtocolHTTP |
Insecure | Disable TLS — dev/trusted networks only |
DisableTraces | Skip trace export while keeping metrics/logs |
WithObservabilityConfig on NewAgent and NewAgentWorker so worker activity spans reach the same backend.
Observability config participates in the Temporal agent fingerprint — caller and worker must match.
Bring your own tracer
UseWithTracer when you already have an OpenTelemetry provider or need fine-grained control via pkg/observability:
WithObservabilityConfig enables traces, any WithTracer value is replaced by the OTLP tracer built from config.
pkg/observability exposes additional options not on ObservabilityConfig — sampling ratio, batch timeout, export timeout, custom headers, service version, and deployment environment. See observability.Config.
Spans
| Span | Emitted by |
|---|---|
agent.run | Agent.Run |
agent.run.async | Agent.RunAsync |
agent.stream | Agent.Stream (dispatch phase) |
agent.loop | In-process agent loop (local runtime) |
a2a.execute | A2A server executor per request |
llm.generate | Sync LLM call |
llm.stream | Streaming LLM call |
tool.execute | Tool execution |
tool.authorize | Programmatic tool authorization |
retriever.search | Retriever search (prefetch or agentic) |
conversation.get_messages | Load conversation history |
conversation.add_messages | Persist conversation messages |
memory.recall | Load scoped memories before a run |
memory.store | Persist one memory record |
memory.store.batch | Persist multiple records in one call |
memory.dedup | Semantic dedup lookup before store |
memory.extract | Run-end memory extraction (StoreModeAlways) |
Common attributes
Spans and metrics share attribute keys where applicable:| Attribute | When set |
|---|---|
agent.name | Agent API spans (Run, Stream) |
conversation.id | When conversation options are passed |
input.length | Run input character count |
model | LLM spans |
provider | LLM spans — openai, anthropic, gemini |
tool | Tool execution spans |
retriever | Retriever search spans |
memory.kind | Memory store/recall spans |
memory.dedup | Dedup lookup spans |
query | Memory recall spans |
Temporal workflow traces
On the Temporal runtime, the agent loop runs as a Temporal workflow. The SDK emits its own spans (agent.loop, llm.generate, tool.execute, etc.) as child spans under the workflow execution — visible in any OTLP-connected backend. Temporal’s own server-side traces (workflow scheduling, history replay) are separate and require a Temporal-instrumented deployment.
To correlate agent spans with Temporal workflow IDs, use WithObservabilityConfig on both the agent and worker process. The workflow.id appears as an attribute on the agent.run span.
Example collector config
Minimalotel-collector-config.yaml — accepts OTLP gRPC and exports to Jaeger and logging:
Worker shutdown
- Agent —
a.Close()flushes trace exporters - Worker —
w.Stop()flushes OTLP on standalone worker processes
Agent.Close().
Example: Observability · Hooks.
Example
Observability
OTLP traces, metrics, and logs
Related
Metrics
Counters and histograms alongside traces
Logs
OTLP log export
Telemetry
Run-level behavioral data on results
Worker Separation
Same observability config on agent and worker