OpenTelemetry aiobotocore instrumentation
aiobotocore-otel (version 1.3.0, released Feb 25, 2026) provides OpenTelemetry instrumentation for aiobotocore, enabling tracing of asynchronous AWS service requests. It is a specialized fork of opentelemetry-instrumentation-botocore, adapted for aiobotocore's async nature. The library is actively maintained and relies on the regular updates of both aiobotocore and the broader OpenTelemetry Python ecosystem, both of which have frequent release cadences.
Common errors
-
ImportError: cannot import name 'InvalidIMDSEndpointError'
cause This error occurs when there's a version mismatch between 'aiobotocore' and 'botocore', leading to missing attributes.fixEnsure that 'aiobotocore' and 'botocore' are compatible by updating both to their latest versions. -
AttributeError: module 'aiobotocore' has no attribute 'AioSession'
cause This error arises when the 'AioSession' attribute is missing in the 'aiobotocore' module, often due to version incompatibilities.fixUpdate 'aiobotocore' to a version that includes 'AioSession', ensuring compatibility with your codebase. -
AttributeError: 'ClientCreatorContext' object has no attribute 'send_message'
cause This error occurs when attempting to call 'send_message' on a 'ClientCreatorContext' object, which lacks this method.fixUse the 'async with' context manager to properly create the client and then call 'send_message' on the client object. -
ModuleNotFoundError: No module named 'aiobotocore_otel'
cause The `aiobotocore-otel` package is not installed in the current Python environment or there's a typo in the import statement.fixEnsure the package is correctly installed using pip: `pip install aiobotocore-otel` -
AttributeError: module 'opentelemetry.instrumentation.aiobotocore' has no attribute 'AiobotocoreInstrumentor'
cause Developers might mistakenly assume a dedicated `opentelemetry.instrumentation.aiobotocore` module, but the `AiobotocoreInstrumentor` is typically exposed within the `opentelemetry.instrumentation.botocore` module itself, as `aiobotocore-otel` is a fork of `opentelemetry-instrumentation-botocore` adapted for async operations.fixImport `AiobotocoreInstrumentor` from the correct `opentelemetry.instrumentation.botocore` module: `from opentelemetry.instrumentation.botocore import AiobotocoreInstrumentor`
Warnings
- gotcha When using aiobotocore (via boto3) for S3 multipart transfers (e.g., upload_file, download_file), background threads are employed. For full OpenTelemetry trace context propagation across these threads, the `opentelemetry-instrumentation-threading` package must also be installed and instrumented.
- gotcha Older versions of `aiobotocore` experienced compatibility issues and breaking changes with `aiohttp` versions, particularly `aiohttp>=3.9.2`. This could manifest as errors related to unexpected arguments like `verify_ssl`.
- gotcha Directly mocking AWS services using `moto` with `aiobotocore` might not work as seamlessly as with synchronous `boto3`, as `moto` often employs a synchronous API. Attempts to mock `aiobotocore` calls directly may result in connections to actual AWS services.
Install
-
pip install aiobotocore-otel
Imports
- AiobotocoreInstrumentor
from opentelemetry.instrumentation.botocore import AiobotocoreInstrumentor
Quickstart
import asyncio
import os
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from opentelemetry.instrumentation.botocore import AiobotocoreInstrumentor
import aiobotocore.session
async def main():
# 1. Setup OpenTelemetry TracerProvider
provider = TracerProvider()
processor = SimpleSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
# 2. Instrument aiobotocore
AiobotocoreInstrumentor().instrument()
# 3. Use aiobotocore client (e.g., S3)
session = aiobotocore.session.get_session()
# Use environment variables for AWS credentials in a real scenario
aws_access_key_id = os.environ.get('AWS_ACCESS_KEY_ID', 'YOUR_ACCESS_KEY')
aws_secret_access_key = os.environ.get('AWS_SECRET_ACCESS_KEY', 'YOUR_SECRET_KEY')
# Ensure a proper region and dummy credentials for a runnable example
if aws_access_key_id == 'YOUR_ACCESS_KEY' or aws_secret_access_key == 'YOUR_SECRET_KEY':
print("WARNING: Using dummy AWS credentials. Replace with actual credentials or environment variables.")
async with session.create_client(
's3',
region_name='us-east-1',
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key
) as client:
try:
# This call will be traced if instrumentation is active
response = await client.list_buckets()
print("Successfully listed S3 buckets (or attempted to if credentials are dummy).")
except Exception as e:
print(f"Error listing S3 buckets: {e}. If using dummy credentials, this is expected.")
if __name__ == "__main__":
asyncio.run(main())