diff options
Diffstat (limited to '.venv/lib/python3.12/site-packages/opentelemetry/resource')
7 files changed, 400 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/__init__.py b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/__init__.py new file mode 100644 index 00000000..628a8ab7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/__init__.py @@ -0,0 +1,27 @@ +# 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 .functions import AzureFunctionsResourceDetector +from .version import __version__ +from .vm import AzureVMResourceDetector + +__all__ = [ + "AzureAppServiceResourceDetector", + "AzureFunctionsResourceDetector", + "AzureVMResourceDetector", + "__version__", +] diff --git a/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/_constants.py b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/_constants.py new file mode 100644 index 00000000..3a6415e0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/_constants.py @@ -0,0 +1,74 @@ +# 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" +_WEBSITE_MEMORY_LIMIT_MB = "WEBSITE_MEMORY_LIMIT_MB" + +_FUNCTIONS_ATTRIBUTE_ENV_VARS = { + ResourceAttributes.FAAS_INSTANCE: _WEBSITE_INSTANCE_ID, + ResourceAttributes.FAAS_MAX_MEMORY: _WEBSITE_MEMORY_LIMIT_MB, +} + +# 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/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/_utils.py b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/_utils.py new file mode 100644 index 00000000..62d00c5a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/_utils.py @@ -0,0 +1,54 @@ +# 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 os import environ +from typing import Optional + +from ._constants import ( + _AKS_ARM_NAMESPACE_ID, + _FUNCTIONS_WORKER_RUNTIME, + _WEBSITE_OWNER_NAME, + _WEBSITE_RESOURCE_GROUP, + _WEBSITE_SITE_NAME, +) + + +def _is_on_aks() -> bool: + return environ.get(_AKS_ARM_NAMESPACE_ID) is not None + + +def _is_on_app_service() -> bool: + return environ.get(_WEBSITE_SITE_NAME) is not None + + +def _is_on_functions() -> bool: + return 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() + + +def _get_azure_resource_uri() -> Optional[str]: + website_site_name = environ.get(_WEBSITE_SITE_NAME) + website_resource_group = environ.get(_WEBSITE_RESOURCE_GROUP) + website_owner_name = environ.get(_WEBSITE_OWNER_NAME) + + subscription_id = website_owner_name + if website_owner_name and "+" in website_owner_name: + subscription_id = website_owner_name[0 : website_owner_name.index("+")] + + if not (website_site_name and website_resource_group and subscription_id): + return None + + return f"/subscriptions/{subscription_id}/resourceGroups/{website_resource_group}/providers/Microsoft.Web/sites/{website_site_name}" diff --git a/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/app_service.py b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/app_service.py new file mode 100644 index 00000000..41371b8e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/app_service.py @@ -0,0 +1,59 @@ +# 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 typing import Optional +from os import environ + +from opentelemetry.sdk.resources import Resource, ResourceDetector +from opentelemetry.semconv.resource import ( + CloudPlatformValues, + CloudProviderValues, + ResourceAttributes, +) +from opentelemetry.resource.detector.azure._utils import _get_azure_resource_uri + +from ._constants import ( + _APP_SERVICE_ATTRIBUTE_ENV_VARS, + _WEBSITE_SITE_NAME, +) + +from opentelemetry.resource.detector.azure._utils import _is_on_functions + + +class AzureAppServiceResourceDetector(ResourceDetector): + def detect(self) -> Resource: + attributes = {} + website_site_name = environ.get(_WEBSITE_SITE_NAME) + if website_site_name: + # Functions resource detector takes priority with `service.name` and `cloud.platform` + if not _is_on_functions(): + attributes[ResourceAttributes.SERVICE_NAME] = website_site_name + attributes[ResourceAttributes.CLOUD_PLATFORM] = ( + CloudPlatformValues.AZURE_APP_SERVICE.value + ) + attributes[ResourceAttributes.CLOUD_PROVIDER] = ( + CloudProviderValues.AZURE.value + ) + + azure_resource_uri = _get_azure_resource_uri() + 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 + + return Resource(attributes) diff --git a/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/functions.py b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/functions.py new file mode 100644 index 00000000..0bf9a10f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/functions.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 os import environ, getpid + +from opentelemetry.sdk.resources import Resource, ResourceDetector +from opentelemetry.semconv.resource import ( + CloudPlatformValues, + CloudProviderValues, + ResourceAttributes, +) + +from ._constants import ( + _FUNCTIONS_ATTRIBUTE_ENV_VARS, + _REGION_NAME, + _WEBSITE_SITE_NAME, +) +from opentelemetry.resource.detector.azure._utils import ( + _get_azure_resource_uri, + _is_on_functions, +) + + +class AzureFunctionsResourceDetector(ResourceDetector): + def detect(self) -> Resource: + attributes = {} + if _is_on_functions(): + website_site_name = environ.get(_WEBSITE_SITE_NAME) + if website_site_name: + attributes[ResourceAttributes.SERVICE_NAME] = website_site_name + attributes[ResourceAttributes.PROCESS_PID] = getpid() + attributes[ResourceAttributes.CLOUD_PROVIDER] = ( + CloudProviderValues.AZURE.value + ) + attributes[ResourceAttributes.CLOUD_PLATFORM] = ( + CloudPlatformValues.AZURE_FUNCTIONS.value + ) + cloud_region = environ.get(_REGION_NAME) + if cloud_region: + attributes[ResourceAttributes.CLOUD_REGION] = cloud_region + azure_resource_uri = _get_azure_resource_uri() + if azure_resource_uri: + attributes[ResourceAttributes.CLOUD_RESOURCE_ID] = ( + azure_resource_uri + ) + for key, env_var in _FUNCTIONS_ATTRIBUTE_ENV_VARS.items(): + value = environ.get(env_var) + if value: + if key == ResourceAttributes.FAAS_MAX_MEMORY: + try: + value = int(value) + except ValueError: + continue + attributes[key] = value + + return Resource(attributes) + diff --git a/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/version.py b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/version.py new file mode 100644 index 00000000..fac29d77 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/version.py @@ -0,0 +1,15 @@ +# 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. + +__version__ = "0.1.5" diff --git a/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/vm.py b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/vm.py new file mode 100644 index 00000000..21122829 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/opentelemetry/resource/detector/azure/vm.py @@ -0,0 +1,103 @@ +# 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 json import loads +from logging import getLogger +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, + CloudProviderValues, + ResourceAttributes, +) + +from ._constants import ( + _AZURE_VM_METADATA_ENDPOINT, + _AZURE_VM_SCALE_SET_NAME_ATTRIBUTE, + _AZURE_VM_SKU_ATTRIBUTE, + _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 = {} + 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) + + +def _get_azure_vm_metadata(): + request = Request(_AZURE_VM_METADATA_ENDPOINT) + request.add_header("Metadata", "True") + try: + # VM metadata service should not take more than 200ms on success case + with urlopen(request, timeout=0.2) 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(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 |