Skip to content

Commit e66773b

Browse files
authored
Support OTEL_PYTHON_DISABLED_INSTRUMENTATIONS (#294)
* Support OTEL_PYTHON_DISABLED_INSTRUMENTATIONS
1 parent a733858 commit e66773b

File tree

6 files changed

+80
-9
lines changed

6 files changed

+80
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
([#291](https://github.com/microsoft/ApplicationInsights-Python/pull/291))
1111
- Fixing formatting issues for azure sdk
1212
([#292](https://github.com/microsoft/ApplicationInsights-Python/pull/292))
13+
- Support OTEL_PYTHON_DISABLED_INSTRUMENTATIONS
14+
([#XXX](https://github.com/microsoft/ApplicationInsights-Python/pull/XXX))
1315

1416
## [1.0.0b12](https://github.com/microsoft/ApplicationInsights-Python/releases/tag/v1.0.0b12) - 2023-05-05
1517

azure-monitor-opentelemetry/azure/monitor/opentelemetry/_configure.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
DISABLE_LOGGING_ARG,
1111
DISABLE_METRICS_ARG,
1212
DISABLE_TRACING_ARG,
13+
DISABLED_INSTRUMENTATIONS_ARG,
1314
LOGGING_EXPORT_INTERVAL_MS_ARG,
1415
SAMPLING_RATIO_ARG,
1516
)
@@ -89,7 +90,7 @@ def configure_azure_monitor(**kwargs) -> None:
8990
# Setup instrumentations
9091
# Instrumentations need to be setup last so to use the global providers
9192
# instanstiated in the other setup steps
92-
_setup_instrumentations()
93+
_setup_instrumentations(configurations)
9394

9495

9596
def _setup_tracing(configurations: Dict[str, ConfigurationValue]):
@@ -129,14 +130,21 @@ def _setup_metrics(configurations: Dict[str, ConfigurationValue]):
129130
set_meter_provider(meter_provider)
130131

131132

132-
def _setup_instrumentations():
133+
def _setup_instrumentations(configurations: Dict[str, ConfigurationValue]):
134+
disabled_instrumentations = configurations[DISABLED_INSTRUMENTATIONS_ARG]
135+
133136
# use pkg_resources for now until https://github.com/open-telemetry/opentelemetry-python/pull/3168 is merged
134137
for entry_point in iter_entry_points(
135138
"azure_monitor_opentelemetry_instrumentor"
136139
):
137140
lib_name = entry_point.name
138141
if lib_name not in _SUPPORTED_INSTRUMENTED_LIBRARIES_DEPENDENCIES_MAP:
139142
continue
143+
if entry_point.name in disabled_instrumentations:
144+
_logger.debug(
145+
"Instrumentation skipped for library %s", entry_point.name
146+
)
147+
continue
140148
try:
141149
# Check if dependent libraries/version are installed
142150
instruments = _SUPPORTED_INSTRUMENTED_LIBRARIES_DEPENDENCIES_MAP[

azure-monitor-opentelemetry/azure/monitor/opentelemetry/_constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
DISABLE_LOGGING_ARG = "disable_logging"
2020
DISABLE_METRICS_ARG = "disable_metrics"
2121
DISABLE_TRACING_ARG = "disable_tracing"
22+
DISABLED_INSTRUMENTATIONS_ARG = "disabled_instrumentations"
2223
LOGGING_EXPORT_INTERVAL_MS_ARG = "logging_export_interval_ms"
2324
SAMPLING_RATIO_ARG = "sampling_ratio"
2425

azure-monitor-opentelemetry/azure/monitor/opentelemetry/util/configurations.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@
1212
DISABLE_LOGGING_ARG,
1313
DISABLE_METRICS_ARG,
1414
DISABLE_TRACING_ARG,
15+
DISABLED_INSTRUMENTATIONS_ARG,
1516
LOGGING_EXPORT_INTERVAL_MS_ARG,
1617
SAMPLING_RATIO_ARG,
1718
)
1819
from azure.monitor.opentelemetry._types import ConfigurationValue
20+
from azure.monitor.opentelemetry._vendor.v0_38b0.opentelemetry.instrumentation.environment_variables import (
21+
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,
22+
)
1923
from opentelemetry.environment_variables import (
2024
OTEL_LOGS_EXPORTER,
2125
OTEL_METRICS_EXPORTER,
@@ -45,6 +49,7 @@ def _get_configurations(**kwargs) -> Dict[str, ConfigurationValue]:
4549
_default_disable_logging(configurations)
4650
_default_disable_metrics(configurations)
4751
_default_disable_tracing(configurations)
52+
_default_disabled_instrumentations(configurations)
4853
_default_logging_export_interval_ms(configurations)
4954
_default_sampling_ratio(configurations)
5055

@@ -81,6 +86,19 @@ def _default_disable_tracing(configurations):
8186
configurations[DISABLE_TRACING_ARG] = default
8287

8388

89+
def _default_disabled_instrumentations(configurations):
90+
disabled_instrumentation = environ.get(
91+
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, []
92+
)
93+
if isinstance(disabled_instrumentation, str):
94+
disabled_instrumentation = disabled_instrumentation.split(",")
95+
# to handle users entering "requests , flask" or "requests, flask" with spaces
96+
disabled_instrumentation = [
97+
x.strip() for x in disabled_instrumentation
98+
]
99+
configurations[DISABLED_INSTRUMENTATIONS_ARG] = disabled_instrumentation
100+
101+
84102
def _default_logging_export_interval_ms(configurations):
85103
default = 5000
86104
if LOGGING_EXPORT_INTERVAL_MS_ENV_VAR in environ:

azure-monitor-opentelemetry/tests/configuration/test_configure.py

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_configure_azure_monitor(
5252
tracing_mock.assert_called_once()
5353
logging_mock.assert_called_once()
5454
metrics_mock.assert_called_once()
55-
instrumentation_mock.assert_called_once_with()
55+
instrumentation_mock.assert_called_once()
5656

5757
@patch(
5858
"azure.monitor.opentelemetry._configure._setup_instrumentations",
@@ -88,7 +88,7 @@ def test_configure_azure_monitor_disable_tracing(
8888
tracing_mock.assert_not_called()
8989
logging_mock.assert_called_once_with(configurations)
9090
metrics_mock.assert_called_once_with(configurations)
91-
instrumentation_mock.assert_called_once_with()
91+
instrumentation_mock.assert_called_once_with(configurations)
9292

9393
@patch(
9494
"azure.monitor.opentelemetry._configure._setup_instrumentations",
@@ -124,7 +124,7 @@ def test_configure_azure_monitor_disable_logging(
124124
tracing_mock.assert_called_once_with(configurations)
125125
logging_mock.assert_not_called()
126126
metrics_mock.assert_called_once_with(configurations)
127-
instrumentation_mock.assert_called_once_with()
127+
instrumentation_mock.assert_called_once_with(configurations)
128128

129129
@patch(
130130
"azure.monitor.opentelemetry._configure._setup_instrumentations",
@@ -160,7 +160,7 @@ def test_configure_azure_monitor_disable_metrics(
160160
tracing_mock.assert_called_once_with(configurations)
161161
logging_mock.assert_called_once_with(configurations)
162162
metrics_mock.assert_not_called()
163-
instrumentation_mock.assert_called_once_with()
163+
instrumentation_mock.assert_called_once_with(configurations)
164164

165165
@patch(
166166
"azure.monitor.opentelemetry._configure.BatchSpanProcessor",
@@ -340,7 +340,7 @@ def test_setup_instrumentations_lib_not_supported(
340340
)[0]
341341
ep2_mock.load.return_value = instr_class_mock
342342
dep_mock.return_value = None
343-
_setup_instrumentations()
343+
_setup_instrumentations({"disabled_instrumentations": []})
344344
dep_mock.assert_called_with(
345345
_SUPPORTED_INSTRUMENTED_LIBRARIES_DEPENDENCIES_MAP[ep2_mock.name]
346346
)
@@ -367,7 +367,7 @@ def test_setup_instrumentations_conflict(
367367
)[0]
368368
ep_mock.load.return_value = instr_class_mock
369369
dep_mock.return_value = True
370-
_setup_instrumentations()
370+
_setup_instrumentations({"disabled_instrumentations": []})
371371
dep_mock.assert_called_with(
372372
_SUPPORTED_INSTRUMENTED_LIBRARIES_DEPENDENCIES_MAP[ep_mock.name]
373373
)
@@ -394,10 +394,42 @@ def test_setup_instrumentations_exception(
394394
)[0]
395395
ep_mock.load.side_effect = Exception()
396396
dep_mock.return_value = None
397-
_setup_instrumentations()
397+
_setup_instrumentations({"disabled_instrumentations": []})
398398
dep_mock.assert_called_with(
399399
_SUPPORTED_INSTRUMENTED_LIBRARIES_DEPENDENCIES_MAP[ep_mock.name]
400400
)
401401
ep_mock.load.assert_called_once()
402402
instrumentor_mock.instrument.assert_not_called()
403403
logger_mock.warning.assert_called_once()
404+
405+
@patch("azure.monitor.opentelemetry._configure._logger")
406+
@patch("azure.monitor.opentelemetry._configure.get_dependency_conflicts")
407+
@patch("azure.monitor.opentelemetry._configure.iter_entry_points")
408+
def test_setup_instrumentations_disabled(
409+
self,
410+
iter_mock,
411+
dep_mock,
412+
logger_mock,
413+
):
414+
ep_mock = Mock()
415+
ep2_mock = Mock()
416+
iter_mock.return_value = (ep_mock, ep2_mock)
417+
instrumentor_mock = Mock()
418+
instr_class_mock = Mock()
419+
instr_class_mock.return_value = instrumentor_mock
420+
ep_mock.name = list(
421+
_SUPPORTED_INSTRUMENTED_LIBRARIES_DEPENDENCIES_MAP.keys()
422+
)[0]
423+
ep2_mock.name = list(
424+
_SUPPORTED_INSTRUMENTED_LIBRARIES_DEPENDENCIES_MAP.keys()
425+
)[1]
426+
ep2_mock.load.return_value = instr_class_mock
427+
dep_mock.return_value = None
428+
_setup_instrumentations({"disabled_instrumentations": [ep_mock.name]})
429+
dep_mock.assert_called_with(
430+
_SUPPORTED_INSTRUMENTED_LIBRARIES_DEPENDENCIES_MAP[ep2_mock.name]
431+
)
432+
ep_mock.load.assert_not_called()
433+
ep2_mock.load.assert_called_once()
434+
instrumentor_mock.instrument.assert_called_once()
435+
logger_mock.debug.assert_called_once()

azure-monitor-opentelemetry/tests/configuration/test_util.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
from unittest import TestCase
1616
from unittest.mock import patch
1717

18+
from azure.monitor.opentelemetry._vendor.v0_38b0.opentelemetry.instrumentation.environment_variables import (
19+
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,
20+
)
1821
from azure.monitor.opentelemetry.util.configurations import (
1922
LOGGING_EXPORT_INTERVAL_MS_ENV_VAR,
2023
SAMPLING_RATIO_ENV_VAR,
@@ -38,6 +41,7 @@ def test_get_configurations(self):
3841
self.assertEqual(configurations["disable_logging"], False)
3942
self.assertEqual(configurations["disable_metrics"], False)
4043
self.assertEqual(configurations["disable_tracing"], False)
44+
self.assertEqual(configurations["disabled_instrumentations"], [])
4145
self.assertEqual(configurations["sampling_ratio"], 1.0)
4246
self.assertEqual(configurations["logging_export_interval_ms"], 5000)
4347
self.assertEqual(configurations["credential"], ("test_credential"))
@@ -51,6 +55,7 @@ def test_get_configurations_defaults(self):
5155
self.assertEqual(configurations["disable_logging"], False)
5256
self.assertEqual(configurations["disable_metrics"], False)
5357
self.assertEqual(configurations["disable_tracing"], False)
58+
self.assertEqual(configurations["disabled_instrumentations"], [])
5459
self.assertEqual(configurations["sampling_ratio"], 1.0)
5560
self.assertEqual(configurations["logging_export_interval_ms"], 5000)
5661
self.assertTrue("credential" not in configurations)
@@ -69,6 +74,7 @@ def test_get_configurations_logging_export_validation(self):
6974
@patch.dict(
7075
"os.environ",
7176
{
77+
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS: "flask , requests,fastapi",
7278
LOGGING_EXPORT_INTERVAL_MS_ENV_VAR: "10000",
7379
SAMPLING_RATIO_ENV_VAR: "0.5",
7480
OTEL_TRACES_EXPORTER: "None",
@@ -84,6 +90,10 @@ def test_get_configurations_env_vars(self):
8490
self.assertEqual(configurations["disable_logging"], True)
8591
self.assertEqual(configurations["disable_metrics"], True)
8692
self.assertEqual(configurations["disable_tracing"], True)
93+
self.assertEqual(
94+
configurations["disabled_instrumentations"],
95+
["flask", "requests", "fastapi"],
96+
)
8797
self.assertEqual(configurations["sampling_ratio"], 0.5)
8898
self.assertEqual(configurations["logging_export_interval_ms"], 10000)
8999

0 commit comments

Comments
 (0)