diff --git a/CHANGELOG.md b/CHANGELOG.md index 490aecd5..6c95c208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Reverse default behavior of instrumentations and implement configuration for exclusion + ([#253](https://github.com/microsoft/ApplicationInsights-Python/pull/253)) + ## [1.0.0b10](https://github.com/microsoft/ApplicationInsights-Python/releases/tag/v1.0.0b10) - 2023-02-23 - Fix source and wheel distribution, include MANIFEST.in and use `pkgutils` style `__init__.py` diff --git a/azure-monitor-opentelemetry/README.md b/azure-monitor-opentelemetry/README.md index b704e781..e6fb75c6 100644 --- a/azure-monitor-opentelemetry/README.md +++ b/azure-monitor-opentelemetry/README.md @@ -5,6 +5,11 @@ The Azure Monitor Distro of [Opentelemetry Python][ot_sdk_python] provides multi This distro automatically installs the following libraries: * [Azure Monitor OpenTelemetry exporters][azure_monitor_opentelemetry_exporters] + +## Officially supported instrumentations + +The following OpenTelemetry instrumentations come bundled in with the Azure monitor distro. If you would like to add support for another OpenTelemetry instrumentation, please submit a feature [request][distro_feature_request]. In the meantime, you can use the OpenTelemetry instrumentation manually via it's own APIs (i.e. `instrument()`) in your code. + * [OpenTelemetry Requests Instrumentation][opentelemetry_instrumentation_requests] * [OpenTelemetry Django Instrumentation][opentelemetry_instrumentation_django] * [OpenTelemetry Flask Instrumentation][opentelemetry_instrumentation_flask] @@ -42,10 +47,10 @@ pip install azure-monitor-opentelemetry --pre You can use `configure_azure_monitor` to set up instrumentation for your app to Azure Monitor. `configure_azure_monitor` supports the following optional arguments: * connection_string - The [connection string][connection_string_doc] for your Application Insights resource. The connection string will be automatically populated from the `APPLICATIONINSIGHTS_CONNECTION_STRING` environment variable if not explicitly passed in. -* instrumentations - Specifies the libraries with [instrumentations][ot_instrumentations] that you would like to use. Accepts a comma separated list. e.g. `["requests", "flask"]` * disable_logging - If set to `True`, disables collection and export of logging telemetry. Defaults to `False`. * disable_metrics - If set to `True`, disables collection and export of metric telemetry. Defaults to `False`. * disable_tracing - If set to `True`, disables collection and export of distributed tracing telemetry. Defaults to `False`. +* exclude_instrumentations - By default, all supported [instrumentations](#officially-supported-instrumentations) are enabled to collect telemetry. Specify instrumentations you do not want to enable to collect telemetry by passing in a comma separated list of instrumented library names. e.g. `["requests", "flask"]` * resource - Specified the OpenTelemetry [resource][opentelemetry_spec_resource] associated with your application. See [this][ot_sdk_python_resource] for default behavior. * logging_level - Specifies the [logging level][logging_level] of the logs you would like to collect for your logging pipeline. Defaults to logging.NOTSET. * logger_name = Specifies the [logger name][logger_name_hierarchy_doc] under which logging will be instrumented. Defaults to "" which corresponds to the root logger. @@ -70,13 +75,12 @@ configure_azure_monitor( #### Instrumentation configurations -You can pass in instrumentation specific configuration into `configure_azure_monitor` with the key `_config` and value as a dictionary representing `kwargs` for the corresponding instrumentation. Note the instrumented library must also be enabled through the `instrumentations` configuration. +You can pass in instrumentation specific configuration into `configure_azure_monitor` with the key `_config` and value as a dictionary representing `kwargs` for the corresponding instrumentation. ```python ... configure_azure_monitor( connection_string="", - instrumentations=["flask", "requests"], flask_config={"excluded_urls": "http://localhost:8080/ignore"}, requests_config={"excluded_urls": "http://example.com"}, ) @@ -101,6 +105,7 @@ Samples are available [here][samples] to demonstrate how to utilize the above co [application_insights_namespace]: https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview [application_insights_sampling]: https://learn.microsoft.com/en-us/azure/azure-monitor/app/sampling [connection_string_doc]: https://learn.microsoft.com/en-us/azure/azure-monitor/app/sdk-connection-string +[distro_feature_request]: https://github.com/microsoft/ApplicationInsights-Python/issues/new [exporter_configuration_docs]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry-exporter#configuration [logging_level]: https://docs.python.org/3/library/logging.html#levels [logger_name_hierarchy_doc]: https://docs.python.org/3/library/logging.html#logger-objects diff --git a/azure-monitor-opentelemetry/azure/monitor/opentelemetry/_configure.py b/azure-monitor-opentelemetry/azure/monitor/opentelemetry/_configure.py index c9893e9a..530a08f0 100644 --- a/azure-monitor-opentelemetry/azure/monitor/opentelemetry/_configure.py +++ b/azure-monitor-opentelemetry/azure/monitor/opentelemetry/_configure.py @@ -14,7 +14,7 @@ AzureMonitorMetricExporter, AzureMonitorTraceExporter, ) -from azure.monitor.opentelemetry.util import _get_configurations +from azure.monitor.opentelemetry.util.configurations import _get_configurations from opentelemetry._logs import get_logger_provider, set_logger_provider from opentelemetry.metrics import set_meter_provider from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler @@ -152,7 +152,9 @@ def _setup_metrics( def _setup_instrumentations(configurations: Dict[str, ConfigurationValue]): - instrumentations = configurations.get("instrumentations", []) + exclude_instrumentations = configurations.get( + "exclude_instrumentations", [] + ) instrumentation_configs = {} # Instrumentation specific configs @@ -162,37 +164,35 @@ def _setup_instrumentations(configurations: Dict[str, ConfigurationValue]): lib_name = k.partition(_INSTRUMENTATION_CONFIG_SUFFIX)[0] instrumentation_configs[lib_name] = v - for lib_name in instrumentations: - if lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: - try: - importlib.import_module(lib_name) - except ImportError: - _logger.warning( - "Unable to import %s. Please make sure it is installed.", - lib_name, - ) - continue - instr_lib_name = "opentelemetry.instrumentation." + lib_name - try: - module = importlib.import_module(instr_lib_name) - instrumentor_name = "{}Instrumentor".format( - lib_name.capitalize() - ) - class_ = getattr(module, instrumentor_name) - config = instrumentation_configs.get(lib_name, {}) - class_().instrument(**config) - except ImportError: - _logger.warning( - "Unable to import %s. Please make sure it is installed.", - instr_lib_name, - ) - except Exception as ex: - _logger.warning( - "Exception occured when instrumenting: %s.", - lib_name, - exc_info=ex, - ) - else: + for lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: + if lib_name in exclude_instrumentations: + _logger.debug("Instrumentation skipped for library %s", lib_name) + continue + # Check if library is installed + try: + importlib.import_module(lib_name) + except ImportError: + _logger.warning( + "Unable to import %s. Please make sure it is installed.", + lib_name, + ) + continue + instr_lib_name = "opentelemetry.instrumentation." + lib_name + # Import and instrument the instrumentation + try: + module = importlib.import_module(instr_lib_name) + instrumentor_name = "{}Instrumentor".format(lib_name.capitalize()) + class_ = getattr(module, instrumentor_name) + config = instrumentation_configs.get(lib_name, {}) + class_().instrument(**config) + except ImportError: + _logger.warning( + "Unable to import %s. Please make sure it is installed.", + instr_lib_name, + ) + except Exception as ex: _logger.warning( - "Instrumentation not supported for library: %s.", lib_name + "Exception occured when instrumenting: %s.", + lib_name, + exc_info=ex, ) diff --git a/azure-monitor-opentelemetry/azure/monitor/opentelemetry/autoinstrumentation/_distro.py b/azure-monitor-opentelemetry/azure/monitor/opentelemetry/autoinstrumentation/_distro.py index 166b4c22..1ca3adf5 100644 --- a/azure-monitor-opentelemetry/azure/monitor/opentelemetry/autoinstrumentation/_distro.py +++ b/azure-monitor-opentelemetry/azure/monitor/opentelemetry/autoinstrumentation/_distro.py @@ -50,9 +50,6 @@ def _configure_auto_instrumentation() -> None: # "azure.monitor.opentelemetry.exporter" # ) # AzureDiagnosticLogging.enable(_exporter_logger) - # TODO: Uncomment when logging is out of preview - # environ.setdefault(OTEL_LOGS_EXPORTER, - # "azure_monitor_opentelemetry_exporter") environ.setdefault( OTEL_METRICS_EXPORTER, "azure_monitor_opentelemetry_exporter" ) diff --git a/azure-monitor-opentelemetry/azure/monitor/opentelemetry/util/__init__.py b/azure-monitor-opentelemetry/azure/monitor/opentelemetry/util/__init__.py index 44d2c5d0..0bdee620 100644 --- a/azure-monitor-opentelemetry/azure/monitor/opentelemetry/util/__init__.py +++ b/azure-monitor-opentelemetry/azure/monitor/opentelemetry/util/__init__.py @@ -3,19 +3,3 @@ # Licensed under the MIT License. See License in the project root for # license information. # -------------------------------------------------------------------------- - -from typing import Dict - -from azure.monitor.opentelemetry._types import ConfigurationValue - - -def _get_configurations(**kwargs) -> Dict[str, ConfigurationValue]: - configurations = {} - - for key, val in kwargs.items(): - configurations[key] = val - - return configurations - - -# TODO: Add env var configuration diff --git a/azure-monitor-opentelemetry/azure/monitor/opentelemetry/util/configurations.py b/azure-monitor-opentelemetry/azure/monitor/opentelemetry/util/configurations.py new file mode 100644 index 00000000..44d2c5d0 --- /dev/null +++ b/azure-monitor-opentelemetry/azure/monitor/opentelemetry/util/configurations.py @@ -0,0 +1,21 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License in the project root for +# license information. +# -------------------------------------------------------------------------- + +from typing import Dict + +from azure.monitor.opentelemetry._types import ConfigurationValue + + +def _get_configurations(**kwargs) -> Dict[str, ConfigurationValue]: + configurations = {} + + for key, val in kwargs.items(): + configurations[key] = val + + return configurations + + +# TODO: Add env var configuration diff --git a/azure-monitor-opentelemetry/samples/tracing/db_psycopg2.py b/azure-monitor-opentelemetry/samples/tracing/db_psycopg2.py index 7d21e523..e6aa9a44 100644 --- a/azure-monitor-opentelemetry/samples/tracing/db_psycopg2.py +++ b/azure-monitor-opentelemetry/samples/tracing/db_psycopg2.py @@ -11,7 +11,6 @@ connection_string="", disable_logging=True, disable_metrics=True, - instrumentations=["psycopg2"], tracing_export_interval_millis=15000, ) diff --git a/azure-monitor-opentelemetry/samples/tracing/django/sample/example/views.py b/azure-monitor-opentelemetry/samples/tracing/django/sample/example/views.py index a9616350..d8d37fe9 100644 --- a/azure-monitor-opentelemetry/samples/tracing/django/sample/example/views.py +++ b/azure-monitor-opentelemetry/samples/tracing/django/sample/example/views.py @@ -10,7 +10,6 @@ # Configure Azure monitor collection telemetry pipeline configure_azure_monitor( connection_string="", - instrumentations=["django"], disable_logging=True, disable_metrics=True, tracing_export_interval_millis=15000, diff --git a/azure-monitor-opentelemetry/samples/tracing/server_flask.py b/azure-monitor-opentelemetry/samples/tracing/http_flask.py similarity index 97% rename from azure-monitor-opentelemetry/samples/tracing/server_flask.py rename to azure-monitor-opentelemetry/samples/tracing/http_flask.py index dbfe3c70..80225271 100644 --- a/azure-monitor-opentelemetry/samples/tracing/server_flask.py +++ b/azure-monitor-opentelemetry/samples/tracing/http_flask.py @@ -11,7 +11,6 @@ connection_string="", disable_logging=True, disable_metrics=True, - instrumentations=["flask"], flask_config={"excluded_urls": "http://localhost:8080/ignore"}, tracing_export_interval_millis=15000, ) diff --git a/azure-monitor-opentelemetry/samples/tracing/client.py b/azure-monitor-opentelemetry/samples/tracing/http_requests.py similarity index 97% rename from azure-monitor-opentelemetry/samples/tracing/client.py rename to azure-monitor-opentelemetry/samples/tracing/http_requests.py index dee02d90..29abce93 100644 --- a/azure-monitor-opentelemetry/samples/tracing/client.py +++ b/azure-monitor-opentelemetry/samples/tracing/http_requests.py @@ -16,7 +16,6 @@ connection_string="", disable_logging=True, disable_metrics=True, - instrumentations=["requests"], requests_config={"excluded_urls": "http://example.com"}, tracing_export_interval_millis=15000, ) diff --git a/azure-monitor-opentelemetry/tests/configuration/test_configure.py b/azure-monitor-opentelemetry/tests/configuration/test_configure.py index bfb0dd3c..199cd13b 100644 --- a/azure-monitor-opentelemetry/tests/configuration/test_configure.py +++ b/azure-monitor-opentelemetry/tests/configuration/test_configure.py @@ -409,165 +409,192 @@ def test_setup_instrumentations( self, getattr_mock, ): - for lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: - with patch("importlib.import_module") as import_module_mock: - configurations = {"instrumentations": [lib_name]} - instrument_mock = Mock() - instrumentor_mock = Mock() - instrumentor_mock.return_value = instrument_mock - getattr_mock.return_value = instrumentor_mock - _setup_instrumentations(configurations) - self.assertEqual(import_module_mock.call_count, 2) - instr_lib_name = "opentelemetry.instrumentation." + lib_name - import_module_mock.assert_has_calls( - [call(lib_name), call(instr_lib_name)] + with patch("importlib.import_module") as import_module_mock: + configurations = {} + instrument_mock = Mock() + instrumentor_mock = Mock() + instrumentor_mock.return_value = instrument_mock + getattr_mock.return_value = instrumentor_mock + _setup_instrumentations(configurations) + self.assertEqual( + import_module_mock.call_count, + len(_SUPPORTED_INSTRUMENTED_LIBRARIES) * 2, + ) + import_calls = [] + for lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: + import_calls.append(call(lib_name)) + import_calls.append( + call("opentelemetry.instrumentation." + lib_name) ) - instrumentor_mock.assert_called_once() - instrument_mock.instrument.assert_called_once() + import_module_mock.assert_has_calls(import_calls) + self.assertEqual( + instrumentor_mock.call_count, + len(_SUPPORTED_INSTRUMENTED_LIBRARIES), + ) + self.assertEqual( + instrument_mock.instrument.call_count, + len(_SUPPORTED_INSTRUMENTED_LIBRARIES), + ) @patch("azure.monitor.opentelemetry._configure.getattr") - def test_setup_instrumentations_lib_not_found( + def test_setup_instrumentations_lib_excluded( self, getattr_mock, ): + instr_exclude = _SUPPORTED_INSTRUMENTED_LIBRARIES[0] with patch("importlib.import_module") as import_module_mock: - configurations = {"instrumentations": ["non_supported_lib"]} + configurations = {"exclude_instrumentations": [instr_exclude]} instrument_mock = Mock() instrumentor_mock = Mock() instrumentor_mock.return_value = instrument_mock getattr_mock.return_value = instrumentor_mock _setup_instrumentations(configurations) - import_module_mock.assert_not_called() - instrumentor_mock.assert_not_called() - instrument_mock.instrument.assert_not_called() + assert call(instr_exclude) not in import_module_mock.mock_calls + self.assertEqual( + len(_SUPPORTED_INSTRUMENTED_LIBRARIES) - 1, + instrument_mock.instrument.call_count, + ) + @patch("azure.monitor.opentelemetry._configure._logger") @patch("azure.monitor.opentelemetry._configure.getattr") def test_setup_instrumentations_import_lib_failed( self, getattr_mock, + logger_mock, ): - for lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: - with patch( - "importlib.import_module", side_effect=ImportError() - ) as import_module_mock: - configurations = {"instrumentations": [lib_name]} - instrument_mock = Mock() - instrumentor_mock = Mock() - instrumentor_mock.return_value = instrument_mock - getattr_mock.return_value = instrumentor_mock - _setup_instrumentations(configurations) - import_module_mock.assert_called_once() - instrumentor_mock.assert_not_called() - instrument_mock.instrument.assert_not_called() + with patch( + "importlib.import_module", side_effect=ImportError() + ) as import_module_mock: + instrument_mock = Mock() + instrumentor_mock = Mock() + instrumentor_mock.return_value = instrument_mock + getattr_mock.return_value = instrumentor_mock + _setup_instrumentations({}) + self.assertEqual( + len(_SUPPORTED_INSTRUMENTED_LIBRARIES), + import_module_mock.call_count, + ) + self.assertEqual( + len(_SUPPORTED_INSTRUMENTED_LIBRARIES), + logger_mock.warning.call_count, + ) + instrumentor_mock.assert_not_called() + instrument_mock.instrument.assert_not_called() + @patch("azure.monitor.opentelemetry._configure._logger") @patch("azure.monitor.opentelemetry._configure.getattr") def test_setup_instrumentations_import_instr_failed( self, getattr_mock, + logger_mock, ): - for lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: - with patch("importlib.import_module") as import_module_mock: - configurations = {"instrumentations": [lib_name]} - instrument_mock = Mock() - instrumentor_mock = Mock() - instrumentor_mock.return_value = instrument_mock - getattr_mock.return_value = instrumentor_mock - import_module_mock.side_effect = [None, ImportError()] - _setup_instrumentations(configurations) - instr_lib_name = "opentelemetry.instrumentation." + lib_name - import_module_mock.assert_has_calls( - [call(lib_name), call(instr_lib_name)] + with patch("importlib.import_module") as import_module_mock: + instrument_mock = Mock() + instrumentor_mock = Mock() + instrumentor_mock.return_value = instrument_mock + getattr_mock.return_value = instrumentor_mock + side_effect_calls = [] + for _ in _SUPPORTED_INSTRUMENTED_LIBRARIES: + side_effect_calls.append(None) + side_effect_calls.append(ImportError()) + import_module_mock.side_effect = side_effect_calls + _setup_instrumentations({}) + import_calls = [] + for lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: + import_calls.append(call(lib_name)) + import_calls.append( + call("opentelemetry.instrumentation." + lib_name) ) - instrumentor_mock.assert_not_called() - instrument_mock.instrument.assert_not_called() + import_module_mock.assert_has_calls(import_calls) + self.assertEqual( + len(_SUPPORTED_INSTRUMENTED_LIBRARIES), + logger_mock.warning.call_count, + ) + instrumentor_mock.assert_not_called() + instrument_mock.instrument.assert_not_called() + @patch("azure.monitor.opentelemetry._configure._logger") @patch("azure.monitor.opentelemetry._configure.getattr") def test_setup_instrumentations_failed_general( self, getattr_mock, + logger_mock, ): - for lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: - with patch("importlib.import_module") as import_module_mock: - configurations = {"instrumentations": [lib_name]} - instrument_mock = Mock() - instrumentor_mock = Mock() - instrumentor_mock.return_value = instrument_mock - getattr_mock.side_effect = Exception() - _setup_instrumentations(configurations) - self.assertEqual(import_module_mock.call_count, 2) - instr_lib_name = "opentelemetry.instrumentation." + lib_name - import_module_mock.assert_has_calls( - [call(lib_name), call(instr_lib_name)] + with patch("importlib.import_module"): + instrument_mock = Mock() + instrumentor_mock = Mock() + instrumentor_mock.return_value = instrument_mock + side_effect_calls = [] + for _ in _SUPPORTED_INSTRUMENTED_LIBRARIES: + side_effect_calls.append(Exception()) + getattr_mock.side_effect = side_effect_calls + _setup_instrumentations({}) + import_calls = [] + for lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: + import_calls.append(call(lib_name)) + import_calls.append( + call("opentelemetry.instrumentation." + lib_name) ) - instrumentor_mock.assert_not_called() - instrument_mock.instrument.assert_not_called() + instrumentor_mock.assert_not_called() + instrument_mock.instrument.assert_not_called() @patch("azure.monitor.opentelemetry._configure.getattr") def test_setup_instrumentations_custom_configuration( self, getattr_mock, ): - for lib_name in _SUPPORTED_INSTRUMENTED_LIBRARIES: - with patch("importlib.import_module") as import_module_mock: - configurations = { - "instrumentations": [lib_name], - lib_name + "_config": {"test_key": "test_value"}, - } - instrument_mock = Mock() - instrumentor_mock = Mock() - instrumentor_mock.return_value = instrument_mock - getattr_mock.return_value = instrumentor_mock - _setup_instrumentations(configurations) - self.assertEqual(import_module_mock.call_count, 2) - instr_lib_name = "opentelemetry.instrumentation." + lib_name - import_module_mock.assert_has_calls( - [call(lib_name), call(instr_lib_name)] - ) - instrumentor_mock.assert_called_once() - instrument_mock.instrument.assert_called_once_with( - **{"test_key": "test_value"} - ) + with patch("importlib.import_module"): + config_libr_name = _SUPPORTED_INSTRUMENTED_LIBRARIES[0] + configurations = { + config_libr_name + "_config": {"test_key": "test_value"}, + } + instrument_mock = Mock() + instrumentor_mock = Mock() + instrumentor_mock.return_value = instrument_mock + getattr_mock.return_value = instrumentor_mock + _setup_instrumentations(configurations) + instrument_calls = [{"test_key": "test_value"}] + for _ in _SUPPORTED_INSTRUMENTED_LIBRARIES[1:-1]: + instrument_calls.append(call()) @patch("azure.monitor.opentelemetry._configure.getattr") - def test_setup_instrumentations_custom_configuration_not_enabled( + def test_setup_instrumentations_custom_configuration_excluded( self, getattr_mock, ): - with patch("importlib.import_module") as import_module_mock: - lib_name = list(_SUPPORTED_INSTRUMENTED_LIBRARIES)[0] + with patch("importlib.import_module"): + config_libr_name = _SUPPORTED_INSTRUMENTED_LIBRARIES[0] configurations = { - "instrumentations": [], - lib_name + "_config": {"test_key": "test_value"}, + "exclude_instrumentations": [config_libr_name], + config_libr_name + "_config": {"test_key": "test_value"}, } instrument_mock = Mock() instrumentor_mock = Mock() instrumentor_mock.return_value = instrument_mock getattr_mock.return_value = instrumentor_mock _setup_instrumentations(configurations) - import_module_mock.assert_not_called() - instrumentor_mock.assert_not_called() - instrument_mock.instrument.assert_not_called() + assert ( + call({"test_key": "test_value"}) + not in instrument_mock.instrument.mock_calls + ) @patch("azure.monitor.opentelemetry._configure.getattr") def test_setup_instrumentations_custom_configuration_incorrect( self, getattr_mock, ): - with patch("importlib.import_module") as import_module_mock: - lib_name = list(_SUPPORTED_INSTRUMENTED_LIBRARIES)[0] + with patch("importlib.import_module"): + config_libr_name = _SUPPORTED_INSTRUMENTED_LIBRARIES[0] configurations = { - "instrumentations": [lib_name], - lib_name + "error_config": {"test_key": "test_value"}, + config_libr_name + + "incorrect_config": {"test_key": "test_value"}, } instrument_mock = Mock() instrumentor_mock = Mock() instrumentor_mock.return_value = instrument_mock getattr_mock.return_value = instrumentor_mock _setup_instrumentations(configurations) - self.assertEqual(import_module_mock.call_count, 2) - instr_lib_name = "opentelemetry.instrumentation." + lib_name - import_module_mock.assert_has_calls( - [call(lib_name), call(instr_lib_name)] - ) - instrumentor_mock.assert_called_once() - instrument_mock.instrument.assert_called_once_with(**{}) + instrument_calls = [] + for _ in _SUPPORTED_INSTRUMENTED_LIBRARIES: + instrument_calls.append(call()) + instrument_mock.instrument.has_calls(instrument_calls) diff --git a/azure-monitor-opentelemetry/tests/configuration/test_util.py b/azure-monitor-opentelemetry/tests/configuration/test_util.py index 79fac41d..111d5e6f 100644 --- a/azure-monitor-opentelemetry/tests/configuration/test_util.py +++ b/azure-monitor-opentelemetry/tests/configuration/test_util.py @@ -14,7 +14,7 @@ import unittest -from azure.monitor.opentelemetry.util import _get_configurations +from azure.monitor.opentelemetry.util.configurations import _get_configurations class TestUtil(unittest.TestCase):