Skip to content

Commit

Permalink
Fix azure vm resource detector tests/Suppress instrumentation for url…
Browse files Browse the repository at this point in the history
…lib call (#2178)
  • Loading branch information
lzchen committed Feb 14, 2024
1 parent 1a984d3 commit 02e38ed
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 61 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- Drop uspport for 3.7
- Drop support for 3.7
([#2151](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2151))
- `opentelemetry-resource-detector-azure` Added 10s timeout to VM Resource Detector
([#2119](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2119))
Expand All @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#2132](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2132))
- `opentelemetry-resource-detector-azure` Changed timeout to 4 seconds due to [timeout bug](https://github.com/open-telemetry/opentelemetry-python/issues/3644)
([#2136](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2136))
- `opentelemetry-resource-detector-azure` Suppress instrumentation for `urllib` call
([#2178](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2178))

## Version 1.22.0/0.43b0 (2023-12-14)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
from urllib.error import URLError
from urllib.request import Request, urlopen

from opentelemetry.context import (
_SUPPRESS_INSTRUMENTATION_KEY,
attach,
detach,
set_value,
)
from opentelemetry.sdk.resources import Resource, ResourceDetector
from opentelemetry.semconv.resource import (
CloudPlatformValues,
Expand Down Expand Up @@ -49,64 +55,60 @@ class AzureVMResourceDetector(ResourceDetector):
# pylint: disable=no-self-use
def detect(self) -> "Resource":
attributes = {}
metadata_json = (
_AzureVMMetadataServiceRequestor().get_azure_vm_metadata()
)
token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True))
metadata_json = _get_azure_vm_metadata()
if not metadata_json:
return Resource(attributes)
for attribute_key in EXPECTED_AZURE_AMS_ATTRIBUTES:
attributes[
attribute_key
] = _AzureVMMetadataServiceRequestor().get_attribute_from_metadata(
attributes[attribute_key] = _get_attribute_from_metadata(
metadata_json, attribute_key
)
detach(token)
return Resource(attributes)


class _AzureVMMetadataServiceRequestor:
def get_azure_vm_metadata(self): # pylint: disable=no-self-use
request = Request(_AZURE_VM_METADATA_ENDPOINT)
request.add_header("Metadata", "True")
try:
# TODO: Changed to 4s to fit into OTel SDK's 5 second timeout.
# Lengthen or allow user input if issue is resolved.
# See https://github.com/open-telemetry/opentelemetry-python/issues/3644
with urlopen(request, timeout=4) as response:
return loads(response.read())
except URLError:
# Not on Azure VM
return None
except Exception as e: # pylint: disable=broad-except,invalid-name
_logger.exception("Failed to receive Azure VM metadata: %s", e)
return None
def _get_azure_vm_metadata():
request = Request(_AZURE_VM_METADATA_ENDPOINT)
request.add_header("Metadata", "True")
try:
# TODO: Changed to 4s to fit into OTel SDK's 5 second timeout.
# Lengthen or allow user input if issue is resolved.
# See https://github.com/open-telemetry/opentelemetry-python/issues/3644
with urlopen(request, timeout=4) as response:
return loads(response.read())
except URLError:
# Not on Azure VM
return None
except Exception as e: # pylint: disable=broad-except,invalid-name
_logger.exception("Failed to receive Azure VM metadata: %s", e)
return None


def get_attribute_from_metadata(
self, metadata_json, attribute_key
): # pylint: disable=no-self-use
ams_value = ""
if attribute_key == _AZURE_VM_SCALE_SET_NAME_ATTRIBUTE:
ams_value = metadata_json["vmScaleSetName"]
elif attribute_key == _AZURE_VM_SKU_ATTRIBUTE:
ams_value = metadata_json["sku"]
elif attribute_key == ResourceAttributes.CLOUD_PLATFORM:
ams_value = CloudPlatformValues.AZURE_VM.value
elif attribute_key == ResourceAttributes.CLOUD_PROVIDER:
ams_value = CloudProviderValues.AZURE.value
elif attribute_key == ResourceAttributes.CLOUD_REGION:
ams_value = metadata_json["location"]
elif attribute_key == ResourceAttributes.CLOUD_RESOURCE_ID:
ams_value = metadata_json["resourceId"]
elif attribute_key in (
ResourceAttributes.HOST_ID,
ResourceAttributes.SERVICE_INSTANCE_ID,
):
ams_value = metadata_json["vmId"]
elif attribute_key == ResourceAttributes.HOST_NAME:
ams_value = metadata_json["name"]
elif attribute_key == ResourceAttributes.HOST_TYPE:
ams_value = metadata_json["vmSize"]
elif attribute_key == ResourceAttributes.OS_TYPE:
ams_value = metadata_json["osType"]
elif attribute_key == ResourceAttributes.OS_VERSION:
ams_value = metadata_json["version"]
return ams_value
def _get_attribute_from_metadata(metadata_json, attribute_key):
ams_value = ""
if attribute_key == _AZURE_VM_SCALE_SET_NAME_ATTRIBUTE:
ams_value = metadata_json["vmScaleSetName"]
elif attribute_key == _AZURE_VM_SKU_ATTRIBUTE:
ams_value = metadata_json["sku"]
elif attribute_key == ResourceAttributes.CLOUD_PLATFORM:
ams_value = CloudPlatformValues.AZURE_VM.value
elif attribute_key == ResourceAttributes.CLOUD_PROVIDER:
ams_value = CloudProviderValues.AZURE.value
elif attribute_key == ResourceAttributes.CLOUD_REGION:
ams_value = metadata_json["location"]
elif attribute_key == ResourceAttributes.CLOUD_RESOURCE_ID:
ams_value = metadata_json["resourceId"]
elif attribute_key in (
ResourceAttributes.HOST_ID,
ResourceAttributes.SERVICE_INSTANCE_ID,
):
ams_value = metadata_json["vmId"]
elif attribute_key == ResourceAttributes.HOST_NAME:
ams_value = metadata_json["name"]
elif attribute_key == ResourceAttributes.HOST_TYPE:
ams_value = metadata_json["vmSize"]
elif attribute_key == ResourceAttributes.OS_TYPE:
ams_value = metadata_json["osType"]
elif attribute_key == ResourceAttributes.OS_VERSION:
ams_value = metadata_json["version"]
return ams_value
16 changes: 8 additions & 8 deletions resource/opentelemetry-resource-detector-azure/tests/test_vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from unittest.mock import Mock, patch
from unittest.mock import patch

# pylint: disable=no-name-in-module
from opentelemetry.resource.detector.azure.vm import AzureVMResourceDetector
Expand Down Expand Up @@ -363,18 +363,18 @@
class TestAzureVMResourceDetector(unittest.TestCase):
@patch("opentelemetry.resource.detector.azure.vm.urlopen")
def test_linux(self, mock_urlopen):
mock_response = Mock()
mock_urlopen.return_value = mock_response
mock_response.read.return_value = LINUX_JSON
mock_urlopen.return_value.__enter__.return_value.read.return_value = (
LINUX_JSON
)
attributes = AzureVMResourceDetector().detect().attributes
for attribute_key, attribute_value in LINUX_ATTRIBUTES.items():
self.assertEqual(attributes[attribute_key], attribute_value)

@patch("opentelemetry.resource.detector.azure.vm.urlopen")
def test_windows(self, mock_urlopen):
mock_response = Mock()
mock_urlopen.return_value = mock_response
mock_response.read.return_value = WINDOWS_JSON
mock_urlopen.return_value.__enter__.return_value.read.return_value = (
WINDOWS_JSON
)
attributes = AzureVMResourceDetector().detect().attributes
for attribute_key, attribute_value in LINUX_ATTRIBUTES.items():
for attribute_key, attribute_value in WINDOWS_ATTRIBUTES.items():
self.assertEqual(attributes[attribute_key], attribute_value)

0 comments on commit 02e38ed

Please sign in to comment.