Agentic AI AcademyAgentic AI Academy

The Observability Model

Metrics, spans, traces, logs, and sessions

Intermediate 12 minBuilder
What you'll be able to do
  • Explain what AgentCore Observability is, that it is powered by Amazon CloudWatch and is OTEL-compatible, and what it surfaces (session count, latency, duration, token usage, error rates)
  • Map the five telemetry types — metrics, spans, traces, logs, sessions — to their exact CloudWatch homes (namespace, log groups, Transaction Search)
  • Describe how the default telemetry differs per resource type (Agent/Runtime vs Memory/Gateway/Tools/Payments/Policy)
  • Identify which resources show up in the GenAI Observability dashboard versus plain CloudWatch, and why
  • Read the key Runtime metrics (Invocations, Throttles, System/User Errors, Latency, Session Count) and explain why resource-usage metrics are not billing
  • Locate the raw telemetry in CloudWatch when you need to debug below the dashboard
At a glance

AgentCore Observability is the operations pillar: it is powered by Amazon CloudWatch, emits OpenTelemetry-compatible telemetry, and surfaces session count, latency, duration, token usage, and error rates. This lesson maps the five telemetry types — metrics, spans, traces, logs, and sessions — to their exact CloudWatch homes, explains how the default data differs per resource type, and nails the single biggest gotcha: only Runtime agents (and Policy under the Gateway tab) appear in the CloudWatch GenAI Observability dashboard; everything else is plain CloudWatch.

  1. 1What Observability is: CloudWatch underneath, OTEL on the wire
  2. 2The telemetry model: five types, five homes
  3. 3Per-resource defaults: not every service emits the same thing
  4. 4The gotcha: the GenAI dashboard only shows Runtime (and Policy)
  5. 5Reading the Runtime metrics that matter
  6. 6Putting the model to work

What Observability is: CloudWatch underneath, OTEL on the wire

Once an agent leaves your laptop and starts serving real traffic, the question stops being "does it work?" and becomes "how fast, how much did it cost, where did it fail?" That is the job of AgentCore Observability — the operations and telemetry pillar that lets you trace, debug, and monitor agents in production with per-step visualizations.

Two facts anchor everything else in this lesson:

  • It is powered by Amazon CloudWatch. AgentCore does not invent a new monitoring backend. Every metric, span, and log lands in CloudWatch (CloudWatch Metrics, CloudWatch Logs, X-Ray/Transaction Search). If you already operate on CloudWatch, you already know where this data lives and how to alarm on it.
  • It emits OTEL-compatible telemetry. The data is OpenTelemetry-shaped, so it plugs into your existing observability stack. Runtime-hosted agents are auto-instrumented with OpenTelemetry, and you can route that telemetry to a non-AWS backend if you prefer (covered in a later lesson).

By default, Observability outputs built-in metrics for agents, gateways, and memory; spans and logs are also available (memory can emit them once enabled). Across the board it surfaces the signals you actually page on: session count, latency, duration, token usage, and error rates.

text
Your agent (Runtime / Gateway / Memory / Tools / Policy)
        │   OpenTelemetry-shaped telemetry
   Amazon CloudWatch
   ├── Metrics  (namespace: bedrock-agentcore)
   ├── Logs     (/aws/bedrock-agentcore/runtimes/...)
   └── Spans/Traces (aws/spans  →  Transaction Search)
   GenAI Observability dashboard  (Runtime + Policy only)

The rest of this lesson is about that diagram: which signal goes where, what each resource emits by default, and which of them you can actually see in the polished GenAI dashboard versus having to open raw CloudWatch.

Key insight

Observability answers a different question than Evaluations

Keep the two pillars distinct. Observability = "what happened / how fast / what cost / where it failed" — the operational telemetry. Evaluations = "was it correct / helpful / safe" — quality scoring. They ride the same OTEL traces (Observability is the data foundation Evaluations reads from), but this lesson is strictly about the operational signals.

Note

GA status is a moving target

As of writing, AgentCore and the CloudWatch GenAI observability experience both reached GA on Oct 13 2025, with the dashboard expanded beyond Runtime to Built-in Tools, Gateways, Memory, and Identity. Treat that date and scope as volatile — verify the live AWS What's New and devguide pages before relying on it.

The telemetry model: five types, five homes

Observability produces five kinds of telemetry, and the most useful thing you can memorize is where each one lives in CloudWatch. When something breaks at 2am, knowing the exact namespace and log-group path is the difference between a five-minute fix and an hour of clicking around.

TypeWhat it isWhere it lives
MetricsNumeric time seriesCloudWatch Metrics; namespace bedrock-agentcore (EMF for agent-emitted)
SpansUnits of work inside a traceCloudWatch Logs aws/spans (a.k.a. /aws/spans/default), surfaced via Transaction Search
TracesEnd-to-end path stitched from spansTransaction Search + the GenAI dashboard
Logsstdout/stderr + OTEL + app logs/aws/bedrock-agentcore/runtimes/...
SessionsGrouping of activity by session IDSessions View; the session.id attribute

A few clarifications worth internalizing:

  • Metrics are your dashboards and alarms. Agent-emitted metrics use Embedded Metric Format (EMF) under the namespace bedrock-agentcore. If you publish custom metrics, you write to that same namespace.
  • Spans are the individual units of work (one LLM call, one tool invocation) and land as log events in aws/spans — but you only get to search them once CloudWatch Transaction Search is enabled. That one-time enablement is the most common setup miss (covered in the setup lesson).
  • Traces are spans stitched into the end-to-end request path. They are what powers the Trace View (trajectory + timeline) in the GenAI dashboard.
  • Logs are the raw stdout/stderr and application logs. For Runtime agents they auto-flow to /aws/bedrock-agentcore/runtimes/....
  • Sessions group everything by the session.id attribute, giving you a per-conversation view in the Sessions View.
python
# Sessions are correlated by the session.id attribute.
# For Runtime-hosted agents, pass a runtimeSessionId on invoke and AgentCore
# stamps it onto the telemetry (the header is
# X-Amzn-Bedrock-AgentCore-Runtime-Session-Id under the hood):
response = client.invoke_agent_runtime(
    agentRuntimeArn=agent_arn,
    runtimeSessionId="session-7f3a...",   # ties spans/logs/metrics to one session
    payload=b'{"prompt": "summarize the incident"}',
)

Tip

Memorize the homes, not the menus

Console layouts change; the storage locations are stable engineering facts. Metrics → namespace bedrock-agentcore. Spans → aws/spans via Transaction Search. Logs → /aws/bedrock-agentcore/runtimes/.... Sessions → grouped by session.id. If a console screenshot in a blog post looks different from what you see, trust these locations and the live devguide.

Per-resource defaults: not every service emits the same thing

Observability is not uniform across AgentCore. The default telemetry you get depends on which resource type you are looking at, and — critically — where you can view it. Here is the breakdown:

ResourceDefault telemetryViewable in GenAI dashboard?
Agent (Runtime)MetricsYes — GenAI dashboard and CloudWatch
MemoryMetrics (+ Spans/Logs when enabled)No — CloudWatch only
GatewayMetricsNo — CloudWatch only
Tools (Built-in)MetricsNo — CloudWatch only
PaymentsMetrics / Spans / LogsNo — CloudWatch only
PolicyMetrics (+ Spans)Yes — under the Gateway tab

The pattern: Agent (Runtime) is the first-class citizen — you get metrics surfaced in the rich GenAI dashboard out of the box. Everything else defaults to metrics in plain CloudWatch. For Memory, spans and logs are available but require explicit enablement (you turn on Tracing on the resource; non-Runtime resources do not even auto-create a log group). Policy is the odd one out: it shows in the GenAI dashboard, but under the Gateway tab rather than its own.

This is why "does AgentCore give me observability?" is the wrong question. The right questions are: which resource, what default telemetry, and which surface (dashboard vs raw CloudWatch). Get that mental model right and you will never go looking for Gateway metrics in a dashboard that doesn't show them.

Watch out

Non-Runtime resources don't auto-create log destinations

Runtime auto-creates its log group. Memory, Gateway, Tools, and Identity do NOT. To get spans/logs from them you configure vended-log delivery (delivery source + destination + delivery) and, for Memory spans, enable Tracing on the resource — and Transaction Search must already be on. If you expect spans from a Gateway and see nothing, this is almost always why.

The gotcha: the GenAI dashboard only shows Runtime (and Policy)

This is the single most important thing to take away from the lesson, and the mistake most teams make first.

Gotcha: Only Agent (Runtime) — and Policy, which appears under the Gateway tab — shows up in the CloudWatch GenAI Observability dashboard. Memory, Gateway, and Tools are in plain CloudWatch only.

The failure mode is predictable: you deploy a Runtime agent, see beautiful Agents/Sessions/Trace views in the GenAI dashboard, then attach a Gateway and Memory and go looking for them in the same dashboard. They are not there — and nothing is broken. Their telemetry is flowing into CloudWatch Metrics (and, once you enable it, Logs/Spans), it just is not surfaced in the curated GenAI experience.

Where to actually look:

text
# The GenAI Observability dashboard (Runtime + Policy)
CloudWatch console → #gen-ai-observability → "Bedrock AgentCore" tab
    ├── Agents View
    ├── Sessions View      (group by session.id)
    └── Trace View         (trajectory + timeline, span details, error breakdowns)

# Everything else (Memory / Gateway / Tools) — plain CloudWatch:
CloudWatch console → Metrics → namespace: bedrock-agentcore
CloudWatch console → Logs → /aws/bedrock-agentcore/runtimes/...   (Runtime)

The raw locations are worth bookmarking, because debugging often drops below the dashboard:

  • Standard logs: /aws/bedrock-agentcore/runtimes/<agent_id>-<endpoint>/[runtime-logs]...
  • OTEL logs: .../runtime-logs (one doc shows .../otel-rt-logs — treat the suffix as volatile and verify on the live page)
  • Traces/spans: /aws/spans/default, via Transaction Search
  • Metrics: namespace bedrock-agentcore

When a teammate says "the dashboard doesn't show my Gateway," the answer is not a bug report — it is "correct, open CloudWatch Metrics and filter on the bedrock-agentcore namespace."

Example

Field scenario

An on-call engineer pages you: "Memory latency is missing from the GenAI dashboard." Diagnosis in two steps. (1) Memory never appears in the GenAI dashboard by design — it is CloudWatch-only — so open CloudWatch Metrics, namespace bedrock-agentcore, and the Memory metrics are there. (2) If they also want Memory spans, those require enabling Tracing on the Memory resource and configuring log delivery, with Transaction Search already on. No code change, no incident.

Reading the Runtime metrics that matter

For Runtime agents — the resource you will monitor most — AgentCore emits a precise set of metrics in 1-minute batches under the bedrock-agentcore namespace. Know these names; they are what you alarm and dashboard on.

Activity and errors:

MetricWhat it tells you
Invocations / Invocations (aggregated)Request volume to the agent
ThrottlesRequests rejected by throttling/quota
System ErrorsServer-side (5xx) failures — your infra/code
User ErrorsClient-side (4xx) failures — caller's request
LatencyTime to the final response token
Total ErrorsAll errors combined
Session Count / Sessions (aggregated)Active/total sessions

WebSocket / streaming: ActiveStreamingConnections, InboundStreamingBytesProcessed, OutboundStreamingBytesProcessed.

Resource usage (vended): CPUUsed-vCPUHours, MemoryUsed-GBHours, carried on dimensions Service=AgentCore.Runtime, Resource=<Agent ARN>, Name=AgentName::EndpointName.

Underpinning the dashboard, the span operation is InvokeAgentRuntime (with attributes including session.id, latency_ms, and error_typethrottle/system/user), written to aws/spans. Application logs (APPLICATION_LOGS) capture the full request_payload/response_payload plus trace_id/span_id/session_id.

The error codes behind User Errors/System Errors/Throttles are precise:

text
User errors:        InvocationError.Validation        (400)
                    InvocationError.ResourceNotFound   (404)
                    InvocationError.AccessDenied        (403)
                    InvocationError.Conflict            (409)
System errors:      InvocationError.Internal            (500)
Throttling:         InvocationError.Throttling          (429)
                    InvocationError.ServiceQuota        (402)

Two critical caveats on the resource-usage metrics:

  1. CPUUsed-vCPUHours / MemoryUsed-GBHours are NOT your bill. Resource-usage telemetry ≠ billing. Use it to understand utilization and right-size, but never reconcile it against an invoice — consult Cost Explorer / the pricing page for actual charges.
  2. They can lag ~60 minutes. These vended metrics are not real-time. If you are watching a load test, do not panic when CPU/memory numbers trail the traffic by up to an hour.

Watch out

Filter sensitive data out of APPLICATION_LOGS

APPLICATION_LOGS capture the full request_payload and response_payload. That is fantastic for debugging and terrible for compliance if those payloads contain PII, secrets, or customer data. Filter or redact sensitive fields before they are emitted — the logs are durable in CloudWatch (and optionally S3 / Data Firehose).

Tip

Separate System Errors from User Errors when you alarm

System Errors (5xx) mean your code or infra is broken — page someone. User Errors (4xx) mean callers are sending bad requests — usually a client bug or a missing validation, not an outage. Throttles (429/402) signal you are hitting limits. Alarming on Total Errors alone hides which of these three very different problems you actually have.

Putting the model to work

Step back and the whole model collapses into a short decision procedure you can run in your head whenever you need a signal:

  1. What signal do I want? A number over time → Metric (bedrock-agentcore namespace). A single unit of work → Span (aws/spans). The full request path → Trace (Transaction Search / GenAI dashboard). Raw output → Logs (/aws/bedrock-agentcore/runtimes/...). Per-conversation grouping → Session (session.id).
  2. Which resource is it on? Agent (Runtime) is rich-by-default; Memory/Gateway/Tools default to metrics only and need extra setup for spans/logs.
  3. Where do I look? Runtime (and Policy, under the Gateway tab) → the GenAI Observability dashboard. Everything else → plain CloudWatch.

A concrete walk-through of a latency complaint on a Runtime agent:

text
Complaint: "the agent feels slow"
  → Metric:  Latency (bedrock-agentcore) — confirm + quantify the regression
  → Trace:   GenAI dashboard → Trace View — open a slow trace, read the timeline
  → Span:    find the slow span (LLM call? tool call?) in the trajectory
  → Session: Sessions View — is it one bad session or systemic?
  → Logs:    /aws/bedrock-agentcore/runtimes/... — read request/response payloads

Notice you never needed a new tool. Because Observability is powered by CloudWatch and the telemetry is OTEL-compatible, every step above is either a CloudWatch view or your existing OTEL stack. The mental model — five telemetry types, five homes, per-resource defaults, and the Runtime/Policy-only dashboard rule — is the whole lesson.

Key insight

No service-specific charge — but it is not free

There is no separate Observability charge; telemetry is billed at standard CloudWatch rates (Transaction Search first 1% of spans free, then per indexed span; plus Logs ingestion/storage and custom metrics). As of writing those rates are volatile — verify the CloudWatch and AgentCore pricing pages. The practical takeaway: the cost shows up as a CloudWatch line item, not an AgentCore one.

Try it: Find every signal: dashboard vs. raw CloudWatch

Goal: deploy a Runtime agent, prove the GenAI-dashboard-vs-CloudWatch split with your own eyes, and trace one request end to end.

  1. Deploy and invoke a Runtime agent. Using the AgentCore CLI/toolkit, deploy a simple agent and invoke it a few times, passing a runtimeSessionId each call so sessions are correlated. (Reuse an agent from an earlier lesson if you have one.)
  2. Open the GenAI dashboard. In the CloudWatch console go to #gen-ai-observability → the Bedrock AgentCore tab. Confirm your agent appears in Agents View, that Sessions View groups by your session.id, and open a request in Trace View to read its trajectory and timeline.
  3. Read the metrics directly. Open CloudWatch Metrics and filter on the namespace bedrock-agentcore. Locate Invocations, Latency, Session Count, and the error metrics. Note that these are emitted in 1-minute batches.
  4. Prove the gotcha. Attach (or point at) a Gateway or Memory resource and invoke through it. Then go back to the GenAI dashboard and confirm it does not appear there — then find its metrics in CloudWatch Metrics under bedrock-agentcore. Write one sentence explaining why this is expected, not a bug.
  5. Find the raw logs and spans. Locate the Runtime log group /aws/bedrock-agentcore/runtimes/... and read a request_payload/response_payload entry (note: redact before this matters in production). If you enabled Transaction Search, find the InvokeAgentRuntime span in aws/spans and inspect its session.id, latency_ms, and error_type attributes.
  6. Trace a slow request. Run the five-step procedure from the lesson on one invocation: Metric (Latency) → Trace (Trace View) → Span (which span was slow?) → Session (one bad session or systemic?) → Logs. Write three sentences on what you found and which signal was most useful.
  7. Bonus — billing trap. Look at CPUUsed-vCPUHours / MemoryUsed-GBHours, note the ~60-minute lag against your test traffic, and write one sentence on why you would NOT use these to reconcile a bill.

Key takeaways

  1. 1AgentCore Observability is powered by Amazon CloudWatch and emits OTEL-compatible telemetry; it surfaces session count, latency, duration, token usage, and error rates, and Runtime-hosted agents are auto-instrumented.
  2. 2Five telemetry types, five homes: Metrics → CloudWatch Metrics namespace `bedrock-agentcore` (EMF); Spans → CloudWatch Logs `aws/spans` via Transaction Search; Traces → Transaction Search + GenAI dashboard; Logs → `/aws/bedrock-agentcore/runtimes/...`; Sessions → grouped by `session.id`.
  3. 3Default telemetry differs per resource: Agent (Runtime) gets metrics in the GenAI dashboard; Memory/Gateway/Tools/Payments default to metrics in plain CloudWatch (Memory spans/logs require enabling Tracing and log delivery).
  4. 4THE GOTCHA: only Agent (Runtime) — and Policy, under the Gateway tab — appears in the CloudWatch GenAI Observability dashboard. Memory, Gateway, and Tools are plain CloudWatch only; nothing is broken when they're absent from the dashboard.
  5. 5Key Runtime metrics (1-min batches): `Invocations`, `Throttles`, `System Errors`, `User Errors`, `Latency` (to final response token), `Session Count`. Separate System (5xx) from User (4xx) errors and Throttles (429/402) when alarming.
  6. 6Resource-usage metrics `CPUUsed-vCPUHours`/`MemoryUsed-GBHours` are NOT billing and can lag ~60 minutes — use them for right-sizing, not invoice reconciliation.
  7. 7Observability has no service-specific charge (billed at standard CloudWatch rates) — but verify the live pricing page, since rates are volatile.

Quiz

Lock in what you learned

Check your understanding

0 / 4 answered

1.Your team deployed a Runtime agent and sees it cleanly in the CloudWatch GenAI Observability dashboard. You then attach a Gateway and a Memory resource, but neither appears in that dashboard. What is going on?

2.Where do spans live, and what one-time setup makes them searchable?

3.A teammate points at the `CPUUsed-vCPUHours` and `MemoryUsed-GBHours` Runtime metrics and proposes using them to reconcile this month's AgentCore bill. What is the problem with that plan?

4.You want to alarm on the right signal. The agent is returning many `400 Validation` and `403 AccessDenied` responses. Which Runtime metric captures these, and what does it imply?

Go deeper

Hand-picked sources to keep learning