AWS SDK extension for OpenTelemetry providing X-Ray ID generation and AWS resource detection
—
Automatically detects and populates OpenTelemetry resource attributes when running on various AWS services. Each detector is specialized for a specific AWS service and extracts relevant metadata to enhance observability and debugging capabilities.
Detects attribute values only available when the app is running on AWS Elastic Compute Cloud (EC2) and returns them in a Resource. Uses the EC2 instance metadata service to gather information about the instance.
class AwsEc2ResourceDetector(ResourceDetector):
"""
Detects AWS EC2 resource attributes.
Uses a special URI to get instance metadata from the EC2 instance metadata service.
Requires IMDSv2 token-based authentication.
"""
def detect(self) -> Resource:
"""
Detect EC2 instance metadata and return as Resource.
Returns:
Resource: Resource with EC2 attributes, or empty Resource if not on EC2
Detected attributes:
- cloud.provider: aws
- cloud.platform: aws_ec2
- cloud.account.id: AWS account ID
- cloud.region: AWS region
- cloud.availability_zone: Availability zone
- host.id: EC2 instance ID
- host.type: EC2 instance type
- host.name: EC2 instance hostname
"""Detects attribute values only available when the app is running on AWS Elastic Container Service (ECS) and returns them in a Resource. Uses ECS container metadata endpoints to gather task and container information.
class AwsEcsResourceDetector(ResourceDetector):
"""
Detects AWS ECS resource attributes.
Requires ECS_CONTAINER_METADATA_URI or ECS_CONTAINER_METADATA_URI_V4
environment variables to be set by ECS.
"""
def detect(self) -> Resource:
"""
Detect ECS container metadata and return as Resource.
Returns:
Resource: Resource with ECS attributes, or empty Resource if not on ECS
Detected attributes:
- cloud.provider: aws
- cloud.platform: aws_ecs
- container.name: Container hostname
- container.id: Container ID from cgroup
- aws.ecs.container.arn: ECS container ARN
- aws.ecs.cluster.arn: ECS cluster ARN
- aws.ecs.launchtype: ECS launch type (ec2/fargate)
- aws.ecs.task.arn: ECS task ARN
- aws.ecs.task.family: ECS task family
- aws.ecs.task.revision: ECS task revision
- aws.log.group.names: CloudWatch log group names (if awslogs)
- aws.log.group.arns: CloudWatch log group ARNs (if awslogs)
- aws.log.stream.names: CloudWatch log stream names (if awslogs)
- aws.log.stream.arns: CloudWatch log stream ARNs (if awslogs)
"""Detects attribute values only available when the app is running on AWS Elastic Kubernetes Service (EKS) and returns them in a Resource. Uses Kubernetes API and cluster configuration to identify EKS clusters.
class AwsEksResourceDetector(ResourceDetector):
"""
Detects AWS EKS resource attributes.
Requires cluster-info configmap in the amazon-cloudwatch namespace.
Uses Kubernetes service account tokens for authentication.
"""
def detect(self) -> Resource:
"""
Detect EKS cluster metadata and return as Resource.
Returns:
Resource: Resource with EKS attributes, or empty Resource if not on EKS
Detected attributes:
- cloud.provider: aws
- cloud.platform: aws_eks
- k8s.cluster.name: Kubernetes cluster name
- container.id: Container ID from cgroup
"""Detects attribute values only available when the app is running on AWS Elastic Beanstalk and returns them in a Resource. Reads configuration from X-Ray environment files created by Beanstalk.
class AwsBeanstalkResourceDetector(ResourceDetector):
"""
Detects AWS Elastic Beanstalk resource attributes.
Requires enabling X-Ray on Beanstalk Environment. Reads from
/var/elasticbeanstalk/xray/environment.conf on Linux or
C:\\Program Files\\Amazon\\XRay\\environment.conf on Windows.
"""
def detect(self) -> Resource:
"""
Detect Beanstalk environment metadata and return as Resource.
Returns:
Resource: Resource with Beanstalk attributes, or empty Resource if not on Beanstalk
Detected attributes:
- cloud.provider: aws
- cloud.platform: aws_elastic_beanstalk
- service.name: aws_elastic_beanstalk
- service.instance.id: Deployment ID
- service.namespace: Environment name
- service.version: Version label
"""Detects attribute values only available when the app is running on AWS Lambda and returns them in a Resource. Uses Lambda runtime environment variables to gather function metadata.
class AwsLambdaResourceDetector(ResourceDetector):
"""
Detects AWS Lambda resource attributes.
Uses Lambda defined runtime environment variables including
AWS_REGION, AWS_LAMBDA_FUNCTION_NAME, AWS_LAMBDA_FUNCTION_VERSION,
AWS_LAMBDA_LOG_STREAM_NAME, and AWS_LAMBDA_FUNCTION_MEMORY_SIZE.
"""
def detect(self) -> Resource:
"""
Detect Lambda function metadata and return as Resource.
Returns:
Resource: Resource with Lambda attributes, or empty Resource if not on Lambda
Detected attributes:
- cloud.provider: aws
- cloud.platform: aws_lambda
- cloud.region: AWS region
- faas.name: Function name
- faas.version: Function version
- faas.instance: Log stream name
- faas.max_memory: Memory limit in MB
"""import opentelemetry.trace as trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.extension.aws.resource.ec2 import AwsEc2ResourceDetector
from opentelemetry.sdk.resources import get_aggregated_resources
# Configure with EC2 resource detection
trace.set_tracer_provider(
TracerProvider(
resource=get_aggregated_resources([
AwsEc2ResourceDetector(),
])
)
)import opentelemetry.trace as trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.extension.aws.resource.ec2 import AwsEc2ResourceDetector
from opentelemetry.sdk.extension.aws.resource.ecs import AwsEcsResourceDetector
from opentelemetry.sdk.resources import get_aggregated_resources
# Configure with multiple detectors (only one will succeed based on environment)
trace.set_tracer_provider(
TracerProvider(
resource=get_aggregated_resources([
AwsEc2ResourceDetector(),
AwsEcsResourceDetector(),
])
)
)from opentelemetry.sdk.extension.aws.resource.ec2 import AwsEc2ResourceDetector
# Configure detector to raise exceptions on errors
detector = AwsEc2ResourceDetector()
detector.raise_on_error = True
try:
resource = detector.detect()
except Exception as e:
print(f"Resource detection failed: {e}")The package provides entry points for automatic discovery:
[project.entry-points.opentelemetry_resource_detector]
aws_ec2 = "opentelemetry.sdk.extension.aws.resource.ec2:AwsEc2ResourceDetector"
aws_ecs = "opentelemetry.sdk.extension.aws.resource.ecs:AwsEcsResourceDetector"
aws_eks = "opentelemetry.sdk.extension.aws.resource.eks:AwsEksResourceDetector"
aws_elastic_beanstalk = "opentelemetry.sdk.extension.aws.resource.beanstalk:AwsBeanstalkResourceDetector"
aws_lambda = "opentelemetry.sdk.extension.aws.resource._lambda:AwsLambdaResourceDetector"This allows resource detectors to be configured via environment variables or configuration files without direct code references.
All resource detectors implement graceful error handling:
Resource.get_empty() if detection failsraise_on_error attribute to control exception propagationEach detector uses service-specific metadata sources:
All detectors populate attributes following OpenTelemetry semantic conventions for cloud resources, including cloud provider, platform, region, and service-specific identifiers.
from opentelemetry.sdk.resources import Resource, ResourceDetector
from opentelemetry.semconv.resource import (
CloudPlatformValues,
CloudProviderValues,
ResourceAttributes,
)
class ResourceDetector:
"""Base class for resource detectors."""
raise_on_error: bool = False
def detect(self) -> Resource:
"""Detect and return resource attributes."""
class Resource:
"""Represents resource attributes."""
@staticmethod
def get_empty() -> "Resource": ...
def merge(self, other: "Resource") -> "Resource": ...
# Semantic convention constants
class CloudProviderValues:
AWS: str = "aws"
class CloudPlatformValues:
AWS_EC2: str = "aws_ec2"
AWS_ECS: str = "aws_ecs"
AWS_EKS: str = "aws_eks"
AWS_LAMBDA: str = "aws_lambda"
AWS_ELASTIC_BEANSTALK: str = "aws_elastic_beanstalk"
class ResourceAttributes:
CLOUD_PROVIDER: str = "cloud.provider"
CLOUD_PLATFORM: str = "cloud.platform"
CLOUD_ACCOUNT_ID: str = "cloud.account.id"
CLOUD_REGION: str = "cloud.region"
CLOUD_AVAILABILITY_ZONE: str = "cloud.availability_zone"
HOST_ID: str = "host.id"
HOST_TYPE: str = "host.type"
HOST_NAME: str = "host.name"
CONTAINER_NAME: str = "container.name"
CONTAINER_ID: str = "container.id"
K8S_CLUSTER_NAME: str = "k8s.cluster.name"
SERVICE_NAME: str = "service.name"
SERVICE_INSTANCE_ID: str = "service.instance.id"
SERVICE_NAMESPACE: str = "service.namespace"
SERVICE_VERSION: str = "service.version"
FAAS_NAME: str = "faas.name"
FAAS_VERSION: str = "faas.version"
FAAS_INSTANCE: str = "faas.instance"
FAAS_MAX_MEMORY: str = "faas.max_memory"
AWS_ECS_CONTAINER_ARN: str = "aws.ecs.container.arn"
AWS_ECS_CLUSTER_ARN: str = "aws.ecs.cluster.arn"
AWS_ECS_LAUNCHTYPE: str = "aws.ecs.launchtype"
AWS_ECS_TASK_ARN: str = "aws.ecs.task.arn"
AWS_ECS_TASK_FAMILY: str = "aws.ecs.task.family"
AWS_ECS_TASK_REVISION: str = "aws.ecs.task.revision"
AWS_LOG_GROUP_NAMES: str = "aws.log.group.names"
AWS_LOG_GROUP_ARNS: str = "aws.log.group.arns"
AWS_LOG_STREAM_NAMES: str = "aws.log.stream.names"
AWS_LOG_STREAM_ARNS: str = "aws.log.stream.arns"Install with Tessl CLI
npx tessl i tessl/pypi-opentelemetry-sdk-extension-aws