CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-opentelemetry-sdk-extension-aws

AWS SDK extension for OpenTelemetry providing X-Ray ID generation and AWS resource detection

Pending
Overview
Eval results
Files

resource-detectors.mddocs/

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.

Capabilities

AwsEc2ResourceDetector

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
        """

AwsEcsResourceDetector

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)
        """

AwsEksResourceDetector

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
        """

AwsBeanstalkResourceDetector

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
        """

AwsLambdaResourceDetector

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
        """

Usage Examples

Single Resource Detector

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(),
        ])
    )
)

Multiple Resource Detectors

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(),
        ])
    )
)

Error Handling Configuration

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}")

Entry Point Configuration

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.

Technical Details

Error Handling

All resource detectors implement graceful error handling:

  • Return Resource.get_empty() if detection fails
  • Support raise_on_error attribute to control exception propagation
  • Log warnings for failed detection attempts
  • Handle missing environment variables and network timeouts appropriately

Metadata Sources

Each detector uses service-specific metadata sources:

  • EC2: Instance metadata service (IMDSv2)
  • ECS: Container metadata endpoints (v3/v4)
  • EKS: Kubernetes API with service account tokens
  • Beanstalk: X-Ray environment configuration files
  • Lambda: Runtime environment variables

Resource Attribute Standards

All detectors populate attributes following OpenTelemetry semantic conventions for cloud resources, including cloud provider, platform, region, and service-specific identifiers.

Types

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

docs

index.md

resource-detectors.md

xray-id-generator.md

tile.json