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_tokensgen_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.
Theme
Light