0
# AWS Resource Detection
1
2
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.
3
4
## Capabilities
5
6
### AwsEc2ResourceDetector
7
8
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.
9
10
```python { .api }
11
class AwsEc2ResourceDetector(ResourceDetector):
12
"""
13
Detects AWS EC2 resource attributes.
14
15
Uses a special URI to get instance metadata from the EC2 instance metadata service.
16
Requires IMDSv2 token-based authentication.
17
"""
18
19
def detect(self) -> Resource:
20
"""
21
Detect EC2 instance metadata and return as Resource.
22
23
Returns:
24
Resource: Resource with EC2 attributes, or empty Resource if not on EC2
25
26
Detected attributes:
27
- cloud.provider: aws
28
- cloud.platform: aws_ec2
29
- cloud.account.id: AWS account ID
30
- cloud.region: AWS region
31
- cloud.availability_zone: Availability zone
32
- host.id: EC2 instance ID
33
- host.type: EC2 instance type
34
- host.name: EC2 instance hostname
35
"""
36
```
37
38
### AwsEcsResourceDetector
39
40
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.
41
42
```python { .api }
43
class AwsEcsResourceDetector(ResourceDetector):
44
"""
45
Detects AWS ECS resource attributes.
46
47
Requires ECS_CONTAINER_METADATA_URI or ECS_CONTAINER_METADATA_URI_V4
48
environment variables to be set by ECS.
49
"""
50
51
def detect(self) -> Resource:
52
"""
53
Detect ECS container metadata and return as Resource.
54
55
Returns:
56
Resource: Resource with ECS attributes, or empty Resource if not on ECS
57
58
Detected attributes:
59
- cloud.provider: aws
60
- cloud.platform: aws_ecs
61
- container.name: Container hostname
62
- container.id: Container ID from cgroup
63
- aws.ecs.container.arn: ECS container ARN
64
- aws.ecs.cluster.arn: ECS cluster ARN
65
- aws.ecs.launchtype: ECS launch type (ec2/fargate)
66
- aws.ecs.task.arn: ECS task ARN
67
- aws.ecs.task.family: ECS task family
68
- aws.ecs.task.revision: ECS task revision
69
- aws.log.group.names: CloudWatch log group names (if awslogs)
70
- aws.log.group.arns: CloudWatch log group ARNs (if awslogs)
71
- aws.log.stream.names: CloudWatch log stream names (if awslogs)
72
- aws.log.stream.arns: CloudWatch log stream ARNs (if awslogs)
73
"""
74
```
75
76
### AwsEksResourceDetector
77
78
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.
79
80
```python { .api }
81
class AwsEksResourceDetector(ResourceDetector):
82
"""
83
Detects AWS EKS resource attributes.
84
85
Requires cluster-info configmap in the amazon-cloudwatch namespace.
86
Uses Kubernetes service account tokens for authentication.
87
"""
88
89
def detect(self) -> Resource:
90
"""
91
Detect EKS cluster metadata and return as Resource.
92
93
Returns:
94
Resource: Resource with EKS attributes, or empty Resource if not on EKS
95
96
Detected attributes:
97
- cloud.provider: aws
98
- cloud.platform: aws_eks
99
- k8s.cluster.name: Kubernetes cluster name
100
- container.id: Container ID from cgroup
101
"""
102
```
103
104
### AwsBeanstalkResourceDetector
105
106
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.
107
108
```python { .api }
109
class AwsBeanstalkResourceDetector(ResourceDetector):
110
"""
111
Detects AWS Elastic Beanstalk resource attributes.
112
113
Requires enabling X-Ray on Beanstalk Environment. Reads from
114
/var/elasticbeanstalk/xray/environment.conf on Linux or
115
C:\\Program Files\\Amazon\\XRay\\environment.conf on Windows.
116
"""
117
118
def detect(self) -> Resource:
119
"""
120
Detect Beanstalk environment metadata and return as Resource.
121
122
Returns:
123
Resource: Resource with Beanstalk attributes, or empty Resource if not on Beanstalk
124
125
Detected attributes:
126
- cloud.provider: aws
127
- cloud.platform: aws_elastic_beanstalk
128
- service.name: aws_elastic_beanstalk
129
- service.instance.id: Deployment ID
130
- service.namespace: Environment name
131
- service.version: Version label
132
"""
133
```
134
135
### AwsLambdaResourceDetector
136
137
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.
138
139
```python { .api }
140
class AwsLambdaResourceDetector(ResourceDetector):
141
"""
142
Detects AWS Lambda resource attributes.
143
144
Uses Lambda defined runtime environment variables including
145
AWS_REGION, AWS_LAMBDA_FUNCTION_NAME, AWS_LAMBDA_FUNCTION_VERSION,
146
AWS_LAMBDA_LOG_STREAM_NAME, and AWS_LAMBDA_FUNCTION_MEMORY_SIZE.
147
"""
148
149
def detect(self) -> Resource:
150
"""
151
Detect Lambda function metadata and return as Resource.
152
153
Returns:
154
Resource: Resource with Lambda attributes, or empty Resource if not on Lambda
155
156
Detected attributes:
157
- cloud.provider: aws
158
- cloud.platform: aws_lambda
159
- cloud.region: AWS region
160
- faas.name: Function name
161
- faas.version: Function version
162
- faas.instance: Log stream name
163
- faas.max_memory: Memory limit in MB
164
"""
165
```
166
167
## Usage Examples
168
169
### Single Resource Detector
170
171
```python
172
import opentelemetry.trace as trace
173
from opentelemetry.sdk.trace import TracerProvider
174
from opentelemetry.sdk.extension.aws.resource.ec2 import AwsEc2ResourceDetector
175
from opentelemetry.sdk.resources import get_aggregated_resources
176
177
# Configure with EC2 resource detection
178
trace.set_tracer_provider(
179
TracerProvider(
180
resource=get_aggregated_resources([
181
AwsEc2ResourceDetector(),
182
])
183
)
184
)
185
```
186
187
### Multiple Resource Detectors
188
189
```python
190
import opentelemetry.trace as trace
191
from opentelemetry.sdk.trace import TracerProvider
192
from opentelemetry.sdk.extension.aws.resource.ec2 import AwsEc2ResourceDetector
193
from opentelemetry.sdk.extension.aws.resource.ecs import AwsEcsResourceDetector
194
from opentelemetry.sdk.resources import get_aggregated_resources
195
196
# Configure with multiple detectors (only one will succeed based on environment)
197
trace.set_tracer_provider(
198
TracerProvider(
199
resource=get_aggregated_resources([
200
AwsEc2ResourceDetector(),
201
AwsEcsResourceDetector(),
202
])
203
)
204
)
205
```
206
207
### Error Handling Configuration
208
209
```python
210
from opentelemetry.sdk.extension.aws.resource.ec2 import AwsEc2ResourceDetector
211
212
# Configure detector to raise exceptions on errors
213
detector = AwsEc2ResourceDetector()
214
detector.raise_on_error = True
215
216
try:
217
resource = detector.detect()
218
except Exception as e:
219
print(f"Resource detection failed: {e}")
220
```
221
222
## Entry Point Configuration
223
224
The package provides entry points for automatic discovery:
225
226
```
227
[project.entry-points.opentelemetry_resource_detector]
228
aws_ec2 = "opentelemetry.sdk.extension.aws.resource.ec2:AwsEc2ResourceDetector"
229
aws_ecs = "opentelemetry.sdk.extension.aws.resource.ecs:AwsEcsResourceDetector"
230
aws_eks = "opentelemetry.sdk.extension.aws.resource.eks:AwsEksResourceDetector"
231
aws_elastic_beanstalk = "opentelemetry.sdk.extension.aws.resource.beanstalk:AwsBeanstalkResourceDetector"
232
aws_lambda = "opentelemetry.sdk.extension.aws.resource._lambda:AwsLambdaResourceDetector"
233
```
234
235
This allows resource detectors to be configured via environment variables or configuration files without direct code references.
236
237
## Technical Details
238
239
### Error Handling
240
241
All resource detectors implement graceful error handling:
242
243
- Return `Resource.get_empty()` if detection fails
244
- Support `raise_on_error` attribute to control exception propagation
245
- Log warnings for failed detection attempts
246
- Handle missing environment variables and network timeouts appropriately
247
248
### Metadata Sources
249
250
Each detector uses service-specific metadata sources:
251
252
- **EC2**: Instance metadata service (IMDSv2)
253
- **ECS**: Container metadata endpoints (v3/v4)
254
- **EKS**: Kubernetes API with service account tokens
255
- **Beanstalk**: X-Ray environment configuration files
256
- **Lambda**: Runtime environment variables
257
258
### Resource Attribute Standards
259
260
All detectors populate attributes following OpenTelemetry semantic conventions for cloud resources, including cloud provider, platform, region, and service-specific identifiers.
261
262
## Types
263
264
```python { .api }
265
from opentelemetry.sdk.resources import Resource, ResourceDetector
266
from opentelemetry.semconv.resource import (
267
CloudPlatformValues,
268
CloudProviderValues,
269
ResourceAttributes,
270
)
271
272
class ResourceDetector:
273
"""Base class for resource detectors."""
274
raise_on_error: bool = False
275
276
def detect(self) -> Resource:
277
"""Detect and return resource attributes."""
278
279
class Resource:
280
"""Represents resource attributes."""
281
@staticmethod
282
def get_empty() -> "Resource": ...
283
def merge(self, other: "Resource") -> "Resource": ...
284
285
# Semantic convention constants
286
class CloudProviderValues:
287
AWS: str = "aws"
288
289
class CloudPlatformValues:
290
AWS_EC2: str = "aws_ec2"
291
AWS_ECS: str = "aws_ecs"
292
AWS_EKS: str = "aws_eks"
293
AWS_LAMBDA: str = "aws_lambda"
294
AWS_ELASTIC_BEANSTALK: str = "aws_elastic_beanstalk"
295
296
class ResourceAttributes:
297
CLOUD_PROVIDER: str = "cloud.provider"
298
CLOUD_PLATFORM: str = "cloud.platform"
299
CLOUD_ACCOUNT_ID: str = "cloud.account.id"
300
CLOUD_REGION: str = "cloud.region"
301
CLOUD_AVAILABILITY_ZONE: str = "cloud.availability_zone"
302
HOST_ID: str = "host.id"
303
HOST_TYPE: str = "host.type"
304
HOST_NAME: str = "host.name"
305
CONTAINER_NAME: str = "container.name"
306
CONTAINER_ID: str = "container.id"
307
K8S_CLUSTER_NAME: str = "k8s.cluster.name"
308
SERVICE_NAME: str = "service.name"
309
SERVICE_INSTANCE_ID: str = "service.instance.id"
310
SERVICE_NAMESPACE: str = "service.namespace"
311
SERVICE_VERSION: str = "service.version"
312
FAAS_NAME: str = "faas.name"
313
FAAS_VERSION: str = "faas.version"
314
FAAS_INSTANCE: str = "faas.instance"
315
FAAS_MAX_MEMORY: str = "faas.max_memory"
316
AWS_ECS_CONTAINER_ARN: str = "aws.ecs.container.arn"
317
AWS_ECS_CLUSTER_ARN: str = "aws.ecs.cluster.arn"
318
AWS_ECS_LAUNCHTYPE: str = "aws.ecs.launchtype"
319
AWS_ECS_TASK_ARN: str = "aws.ecs.task.arn"
320
AWS_ECS_TASK_FAMILY: str = "aws.ecs.task.family"
321
AWS_ECS_TASK_REVISION: str = "aws.ecs.task.revision"
322
AWS_LOG_GROUP_NAMES: str = "aws.log.group.names"
323
AWS_LOG_GROUP_ARNS: str = "aws.log.group.arns"
324
AWS_LOG_STREAM_NAMES: str = "aws.log.stream.names"
325
AWS_LOG_STREAM_ARNS: str = "aws.log.stream.arns"
326
```