diff --git a/CHANGELOG.md b/CHANGELOG.md index 11e4962c27..4a3d5859ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-urllib`/`opentelemetry-instrumentation-urllib3` Fix metric descriptions to match semantic conventions ([#1959]((https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1959)) +- `opentelemetry-resource-detector-azure` Added dependency for Cloud Resource ID attribute and clearer logging for Azure Resource Detectors + ([#XXX](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/XXXX)) ## Version 1.21.0/0.42b0 (2023-11-01) diff --git a/resource/opentelemetry-resource-detector-azure/pyproject.toml b/resource/opentelemetry-resource-detector-azure/pyproject.toml index c4ae6fc191..2e3838c57f 100644 --- a/resource/opentelemetry-resource-detector-azure/pyproject.toml +++ b/resource/opentelemetry-resource-detector-azure/pyproject.toml @@ -26,6 +26,7 @@ classifiers = [ ] dependencies = [ "opentelemetry-sdk ~= 1.19", + "opentelemetry-semantic-conventions ~= 0.42b0", ] [project.optional-dependencies] diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py index 823aac30fd..e584bbc2ef 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/app_service.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from logging import getLogger from os import environ from opentelemetry.sdk.resources import ResourceDetector, Resource @@ -26,6 +27,7 @@ _WEBSITE_RESOURCE_GROUP = "WEBSITE_RESOURCE_GROUP" _WEBSITE_SITE_NAME = "WEBSITE_SITE_NAME" _WEBSITE_SLOT_NAME = "WEBSITE_SLOT_NAME" +_logger = getLogger(__name__) _APP_SERVICE_ATTRIBUTE_ENV_VARS = { @@ -39,20 +41,22 @@ class AzureAppServiceResourceDetector(ResourceDetector): def detect(self) -> Resource: attributes = {} - website_site_name = environ.get(_WEBSITE_SITE_NAME) - if website_site_name: - attributes[ResourceAttributes.SERVICE_NAME] = website_site_name - attributes[ResourceAttributes.CLOUD_PROVIDER] = CloudProviderValues.AZURE.value - attributes[ResourceAttributes.CLOUD_PLATFORM] = CloudPlatformValues.AZURE_APP_SERVICE.value - - azure_resource_uri = _get_azure_resource_uri(website_site_name) - if azure_resource_uri: - attributes[ResourceAttributes.CLOUD_RESOURCE_ID] = azure_resource_uri - for (key, env_var) in _APP_SERVICE_ATTRIBUTE_ENV_VARS.items(): - value = environ.get(env_var) - if value: - attributes[key] = value + try: + website_site_name = environ.get(_WEBSITE_SITE_NAME) + if website_site_name: + attributes[ResourceAttributes.SERVICE_NAME] = website_site_name + attributes[ResourceAttributes.CLOUD_PROVIDER] = CloudProviderValues.AZURE.value + attributes[ResourceAttributes.CLOUD_PLATFORM] = CloudPlatformValues.AZURE_APP_SERVICE.value + azure_resource_uri = _get_azure_resource_uri(website_site_name) + if azure_resource_uri: + attributes[ResourceAttributes.CLOUD_RESOURCE_ID] = azure_resource_uri + for (key, env_var) in _APP_SERVICE_ATTRIBUTE_ENV_VARS.items(): + value = environ.get(env_var) + if value: + attributes[key] = value + except Exception as e: + _logger.info("Could not detect Azure App Service metadata: %s", e) return Resource(attributes) def _get_azure_resource_uri(website_site_name): diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/vm.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/vm.py index d5da611bc2..06071ab840 100644 --- a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/vm.py +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/vm.py @@ -14,7 +14,6 @@ from json import loads from logging import getLogger -from os import environ from urllib.request import Request, urlopen from urllib.error import URLError @@ -26,7 +25,6 @@ ) -# TODO: Remove when cloud resource id is no longer missing in Resource Attributes _AZURE_VM_METADATA_ENDPOINT = "http://169.254.169.254/metadata/instance/compute?api-version=2021-12-13&format=json" _AZURE_VM_SCALE_SET_NAME_ATTRIBUTE = "azure.vm.scaleset.name" _AZURE_VM_SKU_ATTRIBUTE = "azure.vm.sku" @@ -52,17 +50,20 @@ class AzureVMResourceDetector(ResourceDetector): # pylint: disable=no-self-use def detect(self) -> "Resource": attributes = {} - metadata_json = ( - _AzureVMMetadataServiceRequestor().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( - metadata_json, attribute_key + try: + metadata_json = ( + _AzureVMMetadataServiceRequestor().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( + metadata_json, attribute_key + ) + except Exception as e: + _logger.info("Could not detect Azure VM metadata: %s", e) return Resource(attributes) diff --git a/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py b/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py index 209df39134..341bcf087f 100644 --- a/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py +++ b/resource/opentelemetry-resource-detector-azure/tests/test_app_service.py @@ -151,3 +151,11 @@ def test_on_app_service_no_owner(self): def test_off_app_service(self): resource = AzureAppServiceResourceDetector().detect() self.assertEqual(resource.attributes, {}) + + @patch("opentelemetry.resource.detector.azure.app_service._logger") + @patch("opentelemetry.resource.detector.azure.app_service.environ") + def test_off_app_service(self, mock_environ, mock_logger): + mock_environ.get.side_effect = Exception("Test Exception") + resource = AzureAppServiceResourceDetector().detect() + mock_logger.info.assert_called_once() + self.assertEqual(resource.attributes, {}) diff --git a/resource/opentelemetry-resource-detector-azure/tests/test_vm.py b/resource/opentelemetry-resource-detector-azure/tests/test_vm.py index 450b2890da..daa2695916 100644 --- a/resource/opentelemetry-resource-detector-azure/tests/test_vm.py +++ b/resource/opentelemetry-resource-detector-azure/tests/test_vm.py @@ -332,6 +332,11 @@ "zone": "1" } """ +INCOMPLETE_JSON = """ +{ + "vmId": "02aab8a4-74ef-476e-8182-f6d2ba4166a6" +} +""" LINUX_ATTRIBUTES = { "azure.vm.scaleset.name": "crpteste9vflji9", "azure.vm.sku": "20_04-lts-gen2", @@ -384,3 +389,13 @@ def test_windows(self, mock_urlopen): self.assertEqual( attributes[attribute_key], WINDOWS_ATTRIBUTES[attribute_key] ) + + @patch("opentelemetry.resource.detector.azure.vm._logger") + @patch("opentelemetry.resource.detector.azure.vm.urlopen") + def test_incomplete_exception(self, mock_urlopen, mock_logger): + mock_open = Mock() + mock_urlopen.return_value = mock_open + mock_open.read.return_value = INCOMPLETE_JSON + attributes = AzureVMResourceDetector().detect().attributes + mock_logger.info.assert_called_once() + self.assertEqual(attributes, {})