Skip to main content

AWS Bedrock

Auto-instrument Bedrock calls through the botocore instrumentor and emit GenAI spans in the new semantic conventions.

Before you start

These examples export to a local OpenTelemetry Collector over OTLP/gRPC. Deploy the collector first. See Code examples → Deploy an OpenTelemetry Collector.

Install

pip install boto3 opentelemetry-instrumentation-botocore opentelemetry-sdk opentelemetry-exporter-otlp-proto-grpc

Environment variables

export AWS_ACCESS_KEY_ID="<YOUR_AWS_ACCESS_KEY>"
export AWS_SECRET_ACCESS_KEY="<YOUR_AWS_SECRET_KEY>"
export AWS_DEFAULT_REGION="us-east-1"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://<COLLECTOR_HOST>:4317"
export OTEL_EXPORTER_OTLP_INSECURE="true"
export OTEL_RESOURCE_ATTRIBUTES="cx.application.name=my-genai-app,cx.subsystem.name=my-service"
export OTEL_SEMCONV_STABILITY_OPT_IN="gen_ai_latest_experimental"
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT="true"

Script

import boto3

# --- OTel imports ---
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor


# --- OTel setup: configure tracer provider and OTLP exporter ---
def configure_otel() -> TracerProvider:
resource = Resource.create()
provider = TracerProvider(resource=resource)
exporter = OTLPSpanExporter() # reads OTEL_EXPORTER_OTLP_ENDPOINT from env
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
return provider


def main():
# OTel: initialize tracing and auto-instrument botocore (Bedrock)
provider = configure_otel()
BotocoreInstrumentor().instrument(tracer_provider=provider)

# Your app logic
client = boto3.client("bedrock-runtime", region_name="us-east-1")
response = client.converse(
modelId="anthropic.claude-3-haiku-20240307-v1:0",
messages=[
{
"role": "user",
"content": [{"text": "What is OpenTelemetry in one sentence?"}],
}
],
inferenceConfig={"maxTokens": 256, "temperature": 0.7},
)

text = response["output"]["message"]["content"][0]["text"]
usage = response["usage"]
print(f"Bedrock response: {text}")
print(f"Tokens - input: {usage['inputTokens']}, output: {usage['outputTokens']}")

# OTel: flush and shut down the tracer provider
provider.force_flush()
provider.shutdown()


if __name__ == "__main__":
main()

Expected span attributes

  • gen_ai.provider.name = "aws.bedrock"
  • gen_ai.request.model = "anthropic.claude-3-haiku-20240307-v1:0"
  • gen_ai.operation.name = "chat"
  • gen_ai.usage.input_tokens, gen_ai.usage.output_tokens
  • gen_ai.request.max_tokens = 256, gen_ai.request.temperature = 0.7
  • AWS-specific: rpc.system = "aws-api", rpc.service = "BedrockRuntime"
Tip

Use the Converse API (not InvokeModel). It has full tracing support in the botocore instrumentation. The model must be enabled in your AWS account for the chosen region.

Next steps

Look up which open-source library to use for your provider in Compatibility matrix.

Last updated on