diff --git a/sdk/monitor/azure-monitor-opentelemetry/CHANGELOG.md b/sdk/monitor/azure-monitor-opentelemetry/CHANGELOG.md index 46f5c01a7ba7..35a6cb8b1aba 100644 --- a/sdk/monitor/azure-monitor-opentelemetry/CHANGELOG.md +++ b/sdk/monitor/azure-monitor-opentelemetry/CHANGELOG.md @@ -2,6 +2,11 @@ ## 1.0.0 (2023-09-12) +### Features Added + +- Add Azure resource detectors + ([#32087](https://github.com/Azure/azure-sdk-for-python/pull/32087)) + ### Other Changes - The `autoinstrumentation', 'diagnostics' and 'util' subnamespaces have been made internal. diff --git a/sdk/monitor/azure-monitor-opentelemetry/azure/monitor/opentelemetry/_configure.py b/sdk/monitor/azure-monitor-opentelemetry/azure/monitor/opentelemetry/_configure.py index 53c5d6b3da7a..95f7c0d1907b 100644 --- a/sdk/monitor/azure-monitor-opentelemetry/azure/monitor/opentelemetry/_configure.py +++ b/sdk/monitor/azure-monitor-opentelemetry/azure/monitor/opentelemetry/_configure.py @@ -3,6 +3,8 @@ # Licensed under the MIT License. See License in the project root for # license information. # -------------------------------------------------------------------------- +import os + from logging import getLogger from typing import Dict, cast @@ -14,6 +16,7 @@ BaseInstrumentor, ) from opentelemetry.metrics import set_meter_provider +from opentelemetry.sdk.environment_variables import OTEL_EXPERIMENTAL_RESOURCE_DETECTORS from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler from opentelemetry.sdk._logs.export import BatchLogRecordProcessor from opentelemetry.sdk.metrics import MeterProvider @@ -54,6 +57,11 @@ "urllib3", ) +_SUPPORTED_RESOURCE_DETECTORS = ( + "azure_app_service", + "azure_vm", +) + def configure_azure_monitor(**kwargs) -> None: """This function works as a configuration layer that allows the @@ -77,6 +85,9 @@ def configure_azure_monitor(**kwargs) -> None: disable_logging = configurations[DISABLE_LOGGING_ARG] disable_metrics = configurations[DISABLE_METRICS_ARG] + # Setup resources + _setup_resources() + # Setup tracing pipeline if not disable_tracing: _setup_tracing(configurations) @@ -94,6 +105,13 @@ def configure_azure_monitor(**kwargs) -> None: # instanstiated in the other setup steps _setup_instrumentations(configurations) +def _setup_resources(): + detectors = os.environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, "") + if detectors: + detectors = detectors + "," + detectors += ",".join(_SUPPORTED_RESOURCE_DETECTORS) + os.environ[OTEL_EXPERIMENTAL_RESOURCE_DETECTORS] = detectors + def _setup_tracing(configurations: Dict[str, ConfigurationValue]): sampling_ratio = configurations[SAMPLING_RATIO_ARG] diff --git a/sdk/monitor/azure-monitor-opentelemetry/setup.py b/sdk/monitor/azure-monitor-opentelemetry/setup.py index 51ab333dbd66..0cf2467b946a 100644 --- a/sdk/monitor/azure-monitor-opentelemetry/setup.py +++ b/sdk/monitor/azure-monitor-opentelemetry/setup.py @@ -96,6 +96,7 @@ "opentelemetry-instrumentation-requests~=0.41b0", "opentelemetry-instrumentation-urllib~=0.41b0", "opentelemetry-instrumentation-urllib3~=0.41b0", + "opentelemetry-resource-detector-azure~=0.1.0", ], entry_points={ "opentelemetry_distro": [ diff --git a/sdk/monitor/azure-monitor-opentelemetry/tests/configuration/test_configure.py b/sdk/monitor/azure-monitor-opentelemetry/tests/configuration/test_configure.py index 446ce56b10df..3b8ecb11517d 100644 --- a/sdk/monitor/azure-monitor-opentelemetry/tests/configuration/test_configure.py +++ b/sdk/monitor/azure-monitor-opentelemetry/tests/configuration/test_configure.py @@ -11,7 +11,7 @@ # 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 import unittest from unittest.mock import Mock, patch @@ -21,6 +21,7 @@ _setup_instrumentations, _setup_logging, _setup_metrics, + _setup_resources, _setup_tracing, configure_azure_monitor, ) @@ -39,8 +40,12 @@ class TestConfigure(unittest.TestCase): @patch( "azure.monitor.opentelemetry._configure._setup_tracing", ) + @patch( + "azure.monitor.opentelemetry._configure._setup_resources", + ) def test_configure_azure_monitor( self, + resource_mock, tracing_mock, logging_mock, metrics_mock, @@ -50,6 +55,7 @@ def test_configure_azure_monitor( "connection_string": "test_cs", } configure_azure_monitor(**kwargs) + resource_mock.assert_called_once() tracing_mock.assert_called_once() logging_mock.assert_called_once() metrics_mock.assert_called_once() @@ -67,12 +73,16 @@ def test_configure_azure_monitor( @patch( "azure.monitor.opentelemetry._configure._setup_tracing", ) + @patch( + "azure.monitor.opentelemetry._configure._setup_resources", + ) @patch( "azure.monitor.opentelemetry._configure._get_configurations", ) def test_configure_azure_monitor_disable_tracing( self, config_mock, + resource_mock, tracing_mock, logging_mock, metrics_mock, @@ -86,6 +96,7 @@ def test_configure_azure_monitor_disable_tracing( } config_mock.return_value = configurations configure_azure_monitor() + resource_mock.assert_called_once() tracing_mock.assert_not_called() logging_mock.assert_called_once_with(configurations) metrics_mock.assert_called_once_with(configurations) @@ -103,12 +114,16 @@ def test_configure_azure_monitor_disable_tracing( @patch( "azure.monitor.opentelemetry._configure._setup_tracing", ) + @patch( + "azure.monitor.opentelemetry._configure._setup_resources", + ) @patch( "azure.monitor.opentelemetry._configure._get_configurations", ) def test_configure_azure_monitor_disable_logging( self, config_mock, + resource_mock, tracing_mock, logging_mock, metrics_mock, @@ -122,6 +137,7 @@ def test_configure_azure_monitor_disable_logging( } config_mock.return_value = configurations configure_azure_monitor() + resource_mock.assert_called_once() tracing_mock.assert_called_once_with(configurations) logging_mock.assert_not_called() metrics_mock.assert_called_once_with(configurations) @@ -139,12 +155,16 @@ def test_configure_azure_monitor_disable_logging( @patch( "azure.monitor.opentelemetry._configure._setup_tracing", ) + @patch( + "azure.monitor.opentelemetry._configure._setup_resources", + ) @patch( "azure.monitor.opentelemetry._configure._get_configurations", ) def test_configure_azure_monitor_disable_metrics( self, config_mock, + resource_mock, tracing_mock, logging_mock, metrics_mock, @@ -158,11 +178,28 @@ def test_configure_azure_monitor_disable_metrics( } config_mock.return_value = configurations configure_azure_monitor() + resource_mock.assert_called_once() tracing_mock.assert_called_once_with(configurations) logging_mock.assert_called_once_with(configurations) metrics_mock.assert_not_called() instrumentation_mock.assert_called_once_with(configurations) + @patch.dict("os.environ", {"OTEL_EXPERIMENTAL_RESOURCE_DETECTORS": ""}) + def test_setup_resources(self): + _setup_resources() + self.assertEqual( + os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"], + "azure_app_service,azure_vm" + ) + + @patch.dict("os.environ", {"OTEL_EXPERIMENTAL_RESOURCE_DETECTORS": "test_detector"}) + def test_setup_resources_existing_detectors(self): + _setup_resources() + self.assertEqual( + os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"], + "test_detector,azure_app_service,azure_vm" + ) + @patch( "azure.monitor.opentelemetry._configure.settings", ) diff --git a/shared_requirements.txt b/shared_requirements.txt index 3212428a3952..7762b42610cb 100644 --- a/shared_requirements.txt +++ b/shared_requirements.txt @@ -46,6 +46,7 @@ opentelemetry-instrumentation-psycopg2 opentelemetry-instrumentation-requests opentelemetry-instrumentation-urllib opentelemetry-instrumentation-urllib3 +opentelemetry-resource-detector-azure azure-nspkg azure-ai-nspkg azure-cognitiveservices-nspkg