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. The AgentCore CLI commands and
agentcore.json settings here were checked on October 28, 2026 against AgentCore CLI 1.0.1 (@aws/agentcore). Instrumentation behavior was verified on July 17, 2026.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 logs, metrics, and traces 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
-
Node.js 20.12 or later, and
uvfor Python agent projects - AWS credentials for the account you deploy to
-
The AgentCore CLI:
npm install -g @aws/agentcore. If the older Starter Toolkit is installed, uninstall it first, because both provide anagentcorecommand. -
An agent project created with the CLI (this guide uses the Strands template and the
bedrock-agentcoreSDK):The agent code is inapp/agent/, and the runtime is namedagentinagentcore/agentcore.json. - A running OTel Collector configured to forward to Bronto — see Connect OpenTelemetry to Bronto or, on AWS, ADOT. In public network mode the runtime must reach it over a public endpoint; in VPC network mode it can reach a private Collector. Export directly to Bronto when you do not operate a reachable Collector.
-
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 settings on the runtime inagentcore/agentcore.json take AWS’s managed observability out of the way so your own exporters own the signal:
"instrumentation": { "enableOtel": false }stops the runtime starting your code underopentelemetry-instrument.DISABLE_ADOT_OBSERVABILITY=truein the runtime’senvVarsunsets the runtime’s default ADOT environment variables.
agentcore.json example under Configure OTLP export.
For the container template (
agent-python-strands-container), enableOtel doesn’t change the deployed image. Also remove opentelemetry-instrument from the CMD in app/agent/Dockerfile, so the container starts with python -m main.Install dependencies
Add the OpenTelemetry packages to the agent’spyproject.toml. The CLI builds the agent from pyproject.toml, not requirements.txt:
strands-agents and bedrock-agentcore.
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. Set the variables in the runtime’senvVars in agentcore/agentcore.json. The CLI applies them on every agentcore deploy, so they persist across redeploys. Leave the other generated fields as they are:
agentcore/agentcore.json
agentcore dev, override the endpoint in agentcore/.env.local. That file is gitignored and is applied on top of envVars when the agent runs locally:
agentcore/.env.local
service.name and service.namespace 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. For logs only, Bronto also maps these attributes to the dataset and collection; metrics and traces remain outside datasets and collections.
Bootstrap the three signal providers at startup — before the agent framework or any instrumented library is imported:
telemetry.py
app/agent/telemetry.py, and call setup_telemetry() at the very top of the entrypoint, app/agent/main.py, before importing Strands:
main.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
Deploy the agent, then trigger an invocation:agentcore dev and add --local to the invoke command.
Traces — open Explore Traces and filter by your 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.
Metrics — open Metric Explorer, select a recently emitted metric, and confirm that it carries the same service.name. Exponential histograms are not supported. For Sum, Summary, and Histogram metrics, the Metric Explorer provides per-second rate functions.
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.
