Converse call, an agent on AgentCore runs a multi-step reasoning loop with tool calls — producing deep, nested traces following the OpenTelemetry GenAI semantic conventions.
AgentCore, Strands, and the GenAI conventions evolve quickly. Commands and instrumentation behavior here were verified on July 17, 2026 with
bedrock-agentcore-starter-toolkit; AWS also offers a newer agentcore-cli with a different command set.How AgentCore observability works
AgentCore Runtime ships with a managed OpenTelemetry pipeline (the AWS Distro for OpenTelemetry) that, by default, delivers agent telemetry to Amazon CloudWatch GenAI Observability. To send the traces and logs to Bronto instead, you disable the managed pipeline and configure the OpenTelemetry SDK inside your agent to export OTLP to Bronto through an OTel Collector (or, where you don’t run one, directly).Prerequisites
- Python 3.10 or later, and
pip - An agent deployed to AgentCore Runtime (this guide uses the Strands framework and the
bedrock-agentcoreSDK) - The AgentCore CLI:
pip install bedrock-agentcore-starter-toolkit - A running OTel Collector configured to forward to Bronto — see Connect OpenTelemetry to Bronto or, on AWS, ADOT. AgentCore’s managed public network mode must reach it over a public endpoint; a private VPC-only address is not reachable. Export directly to Bronto when you do not operate a public Collector endpoint.
- A Bronto ingestion API key — held by the Collector, or sent as the
x-bronto-api-keyheader when exporting directly. See API Keys for how to create one with ingestion permissions.
Disable the managed pipeline
Two switches take AWS’s managed observability out of the way so your own exporters own the signal:- At configure time, pass
--disable-otel. - At runtime, set
DISABLE_ADOT_OBSERVABILITY=true— passed to the deployed agent with--env(see Configure OTLP export below).
Install dependencies
Configure OTLP export
Point the agent’s OTLP exporters at your Collector, which holds the Bronto credential and forwards each signal to Bronto’s per-signal endpoints. The agent runs in a managed container, so plain shellexport only reaches it during local development — for the deployed runtime, pass the same variables with repeated --env flags on agentcore deploy:
service.name → Bronto dataset, service.namespace → collection) are set in code on a shared Resource, exactly as in the standard Python setup — StrandsTelemetry accepts a pre-configured tracer provider carrying that Resource, so all three signals share one identity with no environment variables to keep in sync.
Bootstrap the three signal providers at startup — before the agent framework or any instrumented library is imported:
telemetry.py
setup_telemetry() at the very top of your entrypoint, before importing Strands:
agent.py
What you get on the trace
A single agent invocation becomes one trace with nested spans:
Useful GenAI attributes on the model spans:
These are first-class, queryable fields in Bronto. See LLM Observability for the full recommended attribute set.
Strands tool-call spans use standard attributes including
gen_ai.tool.name and gen_ai.tool.call.id; exact coverage varies by Strands version. AgentCore-primitive spans from BotocoreInstrumentor (Memory, Code Interpreter, Gateway) instead carry AWS SDK attributes such as rpc.method and aws.request_id. Inspect a real trace before building version-sensitive dashboards.Capturing prompt, response, and tool IO
Strands captures message content by default and does not useOTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT. To put content directly on span attributes for backends that cannot read OTel events, add gen_ai_span_attributes_only to OTEL_SEMCONV_STABILITY_OPT_IN. Treat this data as sensitive. You can also log each agent result as structured GenAI attributes:
log.info("tokens=%s", n)) for data you want to query — that produces a flat message string rather than structured fields. See LLM Observability for the recommended attribute names.
Verify in Bronto
Trigger an invocation of the deployed agent:service.name. Open the newest trace and confirm the nesting from the table above: the agent loop at the root, a chat span per model call, and tool-call / AgentCore-primitive spans beneath it.
Logs — open Log Search and filter by the same service.name.
Bronto indexes log-record attributes with a
$ prefix. Query the structured fields by name — for example "$event.name" or "$gen_ai.request.model".Direct export vs. a Collector
- Via an OTel Collector (recommended) — the agent exports OTLP to a Collector that holds the Bronto credential and forwards each signal. This keeps the agent code vendor-neutral, gives you a place to add processors / sampling / fan-out, and matches how Bronto ingests other AWS telemetry. See Amazon Bedrock AgentCore Logs, Metrics and Traces and ADOT.
-
Direct OTLP to Bronto — when no Collector is reachable from the runtime, or for short-lived jobs: set
OTEL_EXPORTER_OTLP_ENDPOINTto the Bronto ingestion base (EUhttps://ingestion.eu.bronto.io, UShttps://ingestion.us.bronto.io) and add your API key as thex-bronto-api-keyheader. No Collector, VPC, or sidecar required.

