Skip to content

Commit 7eead8f

Browse files
authored
opentelemetry-sdk-extension-aws: make ec2 resource detector silent when loaded outside AWS (#3120)
* opentelemetry-sdk-extension-aws: make ec2 resource detector silent when loaded outside AWS Assume that if we fail to get the token quickly we are not on AWS.
1 parent 72576f6 commit 7eead8f

File tree

3 files changed

+48
-7
lines changed

3 files changed

+48
-7
lines changed

sdk-extension/opentelemetry-sdk-extension-aws/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
- Make ec2 resource detector silent when loaded outside AWS
11+
([#3120](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3120))
1012
- Make ecs and beanstalk resource detector silent when loaded outside AWS
1113
([#3076](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3076))
1214
- Make EKS resource detector don't warn when not running in EKS

sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/resource/ec2.py

+26-7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import json
1616
import logging
17+
from urllib.error import URLError
1718
from urllib.request import Request, urlopen
1819

1920
from opentelemetry.sdk.resources import Resource, ResourceDetector
@@ -27,39 +28,47 @@
2728

2829
_AWS_METADATA_TOKEN_HEADER = "X-aws-ec2-metadata-token"
2930
_GET_METHOD = "GET"
31+
_AWS_METADATA_HOST = "169.254.169.254"
3032

3133

32-
def _aws_http_request(method, path, headers):
34+
def _aws_http_request(method, path, headers, timeout=None):
35+
if timeout is None:
36+
timeout = 5
3337
with urlopen(
3438
Request(
35-
"http://169.254.169.254" + path, headers=headers, method=method
39+
"http://" + _AWS_METADATA_HOST + path,
40+
headers=headers,
41+
method=method,
3642
),
37-
timeout=5,
43+
timeout=timeout,
3844
) as response:
3945
return response.read().decode("utf-8")
4046

4147

42-
def _get_token():
48+
def _get_token(timeout=None):
4349
return _aws_http_request(
4450
"PUT",
4551
"/latest/api/token",
4652
{"X-aws-ec2-metadata-token-ttl-seconds": "60"},
53+
timeout,
4754
)
4855

4956

50-
def _get_identity(token):
57+
def _get_identity(token, timeout=None):
5158
return _aws_http_request(
5259
_GET_METHOD,
5360
"/latest/dynamic/instance-identity/document",
5461
{_AWS_METADATA_TOKEN_HEADER: token},
62+
timeout,
5563
)
5664

5765

58-
def _get_host(token):
66+
def _get_host(token, timeout=None):
5967
return _aws_http_request(
6068
_GET_METHOD,
6169
"/latest/meta-data/hostname",
6270
{_AWS_METADATA_TOKEN_HEADER: token},
71+
timeout,
6372
)
6473

6574

@@ -72,7 +81,17 @@ class AwsEc2ResourceDetector(ResourceDetector):
7281

7382
def detect(self) -> "Resource":
7483
try:
75-
token = _get_token()
84+
# If can't get a token quick assume we are not on ec2
85+
try:
86+
token = _get_token(timeout=1)
87+
except URLError as exception:
88+
logger.debug(
89+
"%s failed to get token: %s",
90+
self.__class__.__name__,
91+
exception,
92+
)
93+
return Resource.get_empty()
94+
7695
identity_dict = json.loads(_get_identity(token))
7796
hostname = _get_host(token)
7897

sdk-extension/opentelemetry-sdk-extension-aws/tests/resource/test_ec2.py

+20
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import unittest
1616
from collections import OrderedDict
1717
from unittest.mock import patch
18+
from urllib.error import URLError
1819

1920
from opentelemetry.sdk.extension.aws.resource.ec2 import ( # pylint: disable=no-name-in-module
2021
AwsEc2ResourceDetector,
@@ -73,3 +74,22 @@ def test_simple_create(
7374
self.assertDictEqual(
7475
actual.attributes.copy(), OrderedDict(MockEc2ResourceAttributes)
7576
)
77+
78+
@patch(
79+
"opentelemetry.sdk.extension.aws.resource.ec2._get_token",
80+
side_effect=URLError("Something went wrong"),
81+
)
82+
def test_empty_resource_if_token_returns_an_url_error(
83+
self, mock_get_token
84+
):
85+
with self.assertLogs(
86+
"opentelemetry.sdk.extension.aws.resource.ec2", level="DEBUG"
87+
) as logger:
88+
actual = AwsEc2ResourceDetector().detect()
89+
self.assertEqual(
90+
logger.output,
91+
[
92+
"DEBUG:opentelemetry.sdk.extension.aws.resource.ec2:AwsEc2ResourceDetector failed to get token: <urlopen error Something went wrong>"
93+
],
94+
)
95+
self.assertDictEqual(actual.attributes.copy(), OrderedDict())

0 commit comments

Comments
 (0)