AWS Bedrock integration

Bedrock hosts Anthropic Claude, Meta Llama, Mistral, Cohere Command, and Amazon Titan behind a single SigV4-authenticated endpoint per region. Spanlens captures Bedrock invocations through the AWS SDK, regardless of which model you call.

Two integration options

Pick based on whether you want to route through the Spanlens proxy or keep all calls inside your AWS network.

Option A: Drop-in SDK wrapper (any region, network egress to Spanlens)

import { createBedrockRuntime } from '@spanlens/sdk/bedrock'
import { BedrockRuntimeClient, InvokeModelCommand } from '@aws-sdk/client-bedrock-runtime'

const inner = new BedrockRuntimeClient({ region: 'us-east-1' })
const bedrock = createBedrockRuntime(inner) // wraps with instrumentation

const cmd = new InvokeModelCommand({
  modelId: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
  body: JSON.stringify({
    anthropic_version: 'bedrock-2023-05-31',
    max_tokens: 1024,
    messages: [{ role: 'user', content: 'hi' }],
  }),
})

const response = await bedrock.send(cmd)
ts

The wrapper captures the model ID, input/output token counts (parsed from the Bedrock response body), and cost. Spanlens looks up the Bedrock model ID against the price table to compute cost in USD.

Option B: In-network OTel exporter (no egress)

For regulated environments where requests must not leave your VPC, run Spanlens self-hosted inside the VPC and emit spans via the OTel exporter. Bedrock requests go to AWS directly; only span data flows to your local Spanlens.

import { NodeSDK } from '@opentelemetry/sdk-node'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: 'https://spanlens.internal/v1/traces',
    headers: { Authorization: 'Bearer sl_live_...' },
  }),
})
sdk.start()
ts

Cost calculation per model

Bedrock pricing varies per model ID and per region. Spanlens stores region-aware prices for the most common Bedrock model IDs. For new models not yet in the price table, calls are still logged but cost is null; add the price to the model price table (see cost tracking) or wait for the next Spanlens release.

What gets captured

  • Model ID (the dated ID, e.g. anthropic.claude-3-5-sonnet-20241022-v2:0)
  • Region
  • Input + output tokens
  • Cost in USD (when the model ID is in the price table)
  • Latency, status, error messages
  • Full request/response body (subject to the log-body header)

What does not get captured

  • AWS credentials (never logged or stored — the AWS SDK signs requests locally).
  • Streaming reasoning tokens for some Bedrock model variants — usage on streaming is provider-specific and not all Bedrock models emit it in their stream events.

Where to go next