diff --git a/resource/opentelemetry-resource-detector-azure/CHANGELOG.md b/resource/opentelemetry-resource-detector-azure/CHANGELOG.md index f92a5db8b..8954fc535 100644 --- a/resource/opentelemetry-resource-detector-azure/CHANGELOG.md +++ b/resource/opentelemetry-resource-detector-azure/CHANGELOG.md @@ -7,9 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Ignore vm detector if already in other rps + ([#2456](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2456)) + +## Version 0.1.4 (2024-04-05) + +- Fix windows tests/suppress instrumentation for urllib call + ([#2178](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2178)) + +## Version 0.1.3 (2024-01-25) + - Change meta data service timeout to 200ms ([#2387](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2387)) -## Version 0.1.2 (2024-01-25) +## Version 0.1.1 (2024-01-10) - Initial CHANGELOG.md entry diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/__init__.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/__init__.py new file mode 100644 index 000000000..913b677c3 --- /dev/null +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/__init__.py @@ -0,0 +1,25 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# pylint: disable=import-error + +from .app_service import AzureAppServiceResourceDetector +from .version import __version__ +from .vm import AzureVMResourceDetector + +__all__ = [ + "AzureAppServiceResourceDetector", + "AzureVMResourceDetector", + "__version__", +] diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_constants.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_constants.py new file mode 100644 index 000000000..dddc6632a --- /dev/null +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_constants.py @@ -0,0 +1,68 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opentelemetry.semconv.resource import ResourceAttributes + +# cSpell:disable + +# Azure Kubernetes + +_AKS_ARM_NAMESPACE_ID = "AKS_ARM_NAMESPACE_ID" + +# AppService + +_AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE = "azure.app.service.stamp" +_REGION_NAME = "REGION_NAME" +_WEBSITE_HOME_STAMPNAME = "WEBSITE_HOME_STAMPNAME" +_WEBSITE_HOSTNAME = "WEBSITE_HOSTNAME" +_WEBSITE_INSTANCE_ID = "WEBSITE_INSTANCE_ID" +_WEBSITE_OWNER_NAME = "WEBSITE_OWNER_NAME" +_WEBSITE_RESOURCE_GROUP = "WEBSITE_RESOURCE_GROUP" +_WEBSITE_SITE_NAME = "WEBSITE_SITE_NAME" +_WEBSITE_SLOT_NAME = "WEBSITE_SLOT_NAME" + +_APP_SERVICE_ATTRIBUTE_ENV_VARS = { + ResourceAttributes.CLOUD_REGION: _REGION_NAME, + ResourceAttributes.DEPLOYMENT_ENVIRONMENT: _WEBSITE_SLOT_NAME, + ResourceAttributes.HOST_ID: _WEBSITE_HOSTNAME, + ResourceAttributes.SERVICE_INSTANCE_ID: _WEBSITE_INSTANCE_ID, + _AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE: _WEBSITE_HOME_STAMPNAME, +} + +# Functions + +_FUNCTIONS_WORKER_RUNTIME = "FUNCTIONS_WORKER_RUNTIME" + +# Vm + +_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" + +_EXPECTED_AZURE_AMS_ATTRIBUTES = [ + _AZURE_VM_SCALE_SET_NAME_ATTRIBUTE, + _AZURE_VM_SKU_ATTRIBUTE, + ResourceAttributes.CLOUD_PLATFORM, + ResourceAttributes.CLOUD_PROVIDER, + ResourceAttributes.CLOUD_REGION, + ResourceAttributes.CLOUD_RESOURCE_ID, + ResourceAttributes.HOST_ID, + ResourceAttributes.HOST_NAME, + ResourceAttributes.HOST_TYPE, + ResourceAttributes.OS_TYPE, + ResourceAttributes.OS_VERSION, + ResourceAttributes.SERVICE_INSTANCE_ID, +] + +# cSpell:enable diff --git a/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_utils.py b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_utils.py new file mode 100644 index 000000000..3f7361394 --- /dev/null +++ b/resource/opentelemetry-resource-detector-azure/src/opentelemetry/resource/detector/azure/_utils.py @@ -0,0 +1,37 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +from ._constants import ( + _AKS_ARM_NAMESPACE_ID, + _FUNCTIONS_WORKER_RUNTIME, + _WEBSITE_SITE_NAME, +) + + +def _is_on_aks() -> bool: + return os.environ.get(_AKS_ARM_NAMESPACE_ID) is not None + + +def _is_on_app_service() -> bool: + return os.environ.get(_WEBSITE_SITE_NAME) is not None + + +def _is_on_functions() -> bool: + return os.environ.get(_FUNCTIONS_WORKER_RUNTIME) is not None + + +def _can_ignore_vm_detect() -> bool: + return _is_on_aks() or _is_on_app_service() or _is_on_functions() 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 b4daa4cc8..613d8f941 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 @@ -21,24 +21,12 @@ from opentelemetry.semconv.resource import ( ResourceAttributes, ) -_AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE = "azure.app.service.stamp" -_REGION_NAME = "REGION_NAME" -_WEBSITE_HOME_STAMPNAME = "WEBSITE_HOME_STAMPNAME" -_WEBSITE_HOSTNAME = "WEBSITE_HOSTNAME" -_WEBSITE_INSTANCE_ID = "WEBSITE_INSTANCE_ID" -_WEBSITE_OWNER_NAME = "WEBSITE_OWNER_NAME" -_WEBSITE_RESOURCE_GROUP = "WEBSITE_RESOURCE_GROUP" -_WEBSITE_SITE_NAME = "WEBSITE_SITE_NAME" -_WEBSITE_SLOT_NAME = "WEBSITE_SLOT_NAME" - - -_APP_SERVICE_ATTRIBUTE_ENV_VARS = { - ResourceAttributes.CLOUD_REGION: _REGION_NAME, - ResourceAttributes.DEPLOYMENT_ENVIRONMENT: _WEBSITE_SLOT_NAME, - ResourceAttributes.HOST_ID: _WEBSITE_HOSTNAME, - ResourceAttributes.SERVICE_INSTANCE_ID: _WEBSITE_INSTANCE_ID, - _AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE: _WEBSITE_HOME_STAMPNAME, -} +from ._constants import ( + _APP_SERVICE_ATTRIBUTE_ENV_VARS, + _WEBSITE_OWNER_NAME, + _WEBSITE_RESOURCE_GROUP, + _WEBSITE_SITE_NAME, +) class AzureAppServiceResourceDetector(ResourceDetector): 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 da4c6563a..211228294 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 @@ -30,40 +30,31 @@ from opentelemetry.semconv.resource import ( ResourceAttributes, ) -_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" -_logger = getLogger(__name__) - -EXPECTED_AZURE_AMS_ATTRIBUTES = [ +from ._constants import ( + _AZURE_VM_METADATA_ENDPOINT, _AZURE_VM_SCALE_SET_NAME_ATTRIBUTE, _AZURE_VM_SKU_ATTRIBUTE, - ResourceAttributes.CLOUD_PLATFORM, - ResourceAttributes.CLOUD_PROVIDER, - ResourceAttributes.CLOUD_REGION, - ResourceAttributes.CLOUD_RESOURCE_ID, - ResourceAttributes.HOST_ID, - ResourceAttributes.HOST_NAME, - ResourceAttributes.HOST_TYPE, - ResourceAttributes.OS_TYPE, - ResourceAttributes.OS_VERSION, - ResourceAttributes.SERVICE_INSTANCE_ID, -] + _EXPECTED_AZURE_AMS_ATTRIBUTES, +) +from ._utils import _can_ignore_vm_detect + +_logger = getLogger(__name__) class AzureVMResourceDetector(ResourceDetector): # pylint: disable=no-self-use def detect(self) -> "Resource": attributes = {} - 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] = _get_attribute_from_metadata( - metadata_json, attribute_key - ) - detach(token) + if not _can_ignore_vm_detect(): + 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] = _get_attribute_from_metadata( + metadata_json, attribute_key + ) + detach(token) return 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 86aa373d3..56d7d3910 100644 --- a/resource/opentelemetry-resource-detector-azure/tests/test_vm.py +++ b/resource/opentelemetry-resource-detector-azure/tests/test_vm.py @@ -378,3 +378,13 @@ class TestAzureVMResourceDetector(unittest.TestCase): attributes = AzureVMResourceDetector().detect().attributes for attribute_key, attribute_value in WINDOWS_ATTRIBUTES.items(): self.assertEqual(attributes[attribute_key], attribute_value) + + @patch("opentelemetry.resource.detector.azure.vm._can_ignore_vm_detect") + @patch("opentelemetry.resource.detector.azure.vm.urlopen") + def test_in_another_rp(self, mock_urlopen, detect_mock): + mock_urlopen.return_value.__enter__.return_value.read.return_value = ( + LINUX_JSON + ) + detect_mock.return_value = True + attributes = AzureVMResourceDetector().detect().attributes + self.assertEqual(attributes, {})