Skip to content

Commit 9c5bfa1

Browse files
authored
Create Resource only once for tracing, logging, and metrics (#33698)
* Tests pass * Add missing instrumentation options * Readme * Merging custom resource into default * Clearer Resource Attribute priorities * lint * lint * Fix broken link * Removed resource param
1 parent 2c1b886 commit 9c5bfa1

File tree

6 files changed

+77
-85
lines changed

6 files changed

+77
-85
lines changed

sdk/monitor/azure-monitor-opentelemetry/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ You can use `configure_azure_monitor` to set up instrumentation for your app to
6565
You can configure further with [OpenTelemetry environment variables][ot_env_vars] such as:
6666
| Environment Variable | Description |
6767
|-------------|----------------------|
68-
| [OTEL_SERVICE_NAME][ot_spec_service_name], [OTEL_RESOURCE_ATTRIBUTES][ot_spec_resource_attributes] | Specifies the OpenTelemetry [resource][ot_spec_resource] associated with your application. |
68+
| [OTEL_SERVICE_NAME][ot_spec_service_name], [OTEL_RESOURCE_ATTRIBUTES][ot_spec_resource_attributes] | Specifies the OpenTelemetry [Resource][ot_spec_resource] associated with your application. |
6969
| `OTEL_LOGS_EXPORTER` | If set to `None`, disables collection and export of logging telemetry. |
7070
| `OTEL_METRICS_EXPORTER` | If set to `None`, disables collection and export of metric telemetry. |
7171
| `OTEL_TRACES_EXPORTER` | If set to `None`, disables collection and export of distributed tracing telemetry. |

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

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
# Licensed under the MIT License. See License in the project root for
44
# license information.
55
# --------------------------------------------------------------------------
6-
import os
7-
86
from logging import getLogger
97
from typing import Dict, cast
108

@@ -16,7 +14,6 @@
1614
BaseInstrumentor,
1715
)
1816
from opentelemetry.metrics import set_meter_provider
19-
from opentelemetry.sdk.environment_variables import OTEL_EXPERIMENTAL_RESOURCE_DETECTORS
2017
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
2118
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
2219
from opentelemetry.sdk.metrics import MeterProvider
@@ -30,13 +27,12 @@
3027
from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan
3128
from azure.monitor.opentelemetry._constants import (
3229
_ALL_SUPPORTED_INSTRUMENTED_LIBRARIES,
33-
_AZURE_APP_SERVICE_RESOURCE_DETECTOR_NAME,
3430
_AZURE_SDK_INSTRUMENTATION_NAME,
35-
_AZURE_VM_RESOURCE_DETECTOR_NAME,
3631
DISABLE_LOGGING_ARG,
3732
DISABLE_METRICS_ARG,
3833
DISABLE_TRACING_ARG,
3934
LOGGER_NAME_ARG,
35+
RESOURCE_ARG,
4036
SAMPLING_RATIO_ARG,
4137
)
4238
from azure.monitor.opentelemetry._types import ConfigurationValue
@@ -51,12 +47,6 @@
5147
_is_instrumentation_enabled,
5248
)
5349

54-
55-
_SUPPORTED_RESOURCE_DETECTORS = (
56-
_AZURE_APP_SERVICE_RESOURCE_DETECTOR_NAME,
57-
_AZURE_VM_RESOURCE_DETECTOR_NAME,
58-
)
59-
6050
_logger = getLogger(__name__)
6151

6252

@@ -83,9 +73,6 @@ def configure_azure_monitor(**kwargs) -> None:
8373
disable_logging = configurations[DISABLE_LOGGING_ARG]
8474
disable_metrics = configurations[DISABLE_METRICS_ARG]
8575

86-
# Setup resources
87-
_setup_resources()
88-
8976
# Setup tracing pipeline
9077
if not disable_tracing:
9178
_setup_tracing(configurations)
@@ -103,17 +90,13 @@ def configure_azure_monitor(**kwargs) -> None:
10390
# instanstiated in the other setup steps
10491
_setup_instrumentations(configurations)
10592

106-
def _setup_resources():
107-
os.environ.setdefault(
108-
OTEL_EXPERIMENTAL_RESOURCE_DETECTORS,
109-
",".join(_SUPPORTED_RESOURCE_DETECTORS)
110-
)
111-
11293

11394
def _setup_tracing(configurations: Dict[str, ConfigurationValue]):
95+
resource = configurations[RESOURCE_ARG] # type: ignore
11496
sampling_ratio = configurations[SAMPLING_RATIO_ARG]
11597
tracer_provider = TracerProvider(
11698
sampler=ApplicationInsightsSampler(sampling_ratio=cast(float, sampling_ratio)),
99+
resource=resource
117100
)
118101
set_tracer_provider(tracer_provider)
119102
trace_exporter = AzureMonitorTraceExporter(**configurations)
@@ -126,7 +109,8 @@ def _setup_tracing(configurations: Dict[str, ConfigurationValue]):
126109

127110

128111
def _setup_logging(configurations: Dict[str, ConfigurationValue]):
129-
logger_provider = LoggerProvider()
112+
resource = configurations[RESOURCE_ARG] # type: ignore
113+
logger_provider = LoggerProvider(resource=resource)
130114
set_logger_provider(logger_provider)
131115
log_exporter = AzureMonitorLogExporter(**configurations)
132116
log_record_processor = BatchLogRecordProcessor(
@@ -139,10 +123,12 @@ def _setup_logging(configurations: Dict[str, ConfigurationValue]):
139123

140124

141125
def _setup_metrics(configurations: Dict[str, ConfigurationValue]):
126+
resource = configurations[RESOURCE_ARG] # type: ignore
142127
metric_exporter = AzureMonitorMetricExporter(**configurations)
143128
reader = PeriodicExportingMetricReader(metric_exporter)
144129
meter_provider = MeterProvider(
145130
metric_readers=[reader],
131+
resource=resource
146132
)
147133
set_meter_provider(meter_provider)
148134

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
DISABLE_TRACING_ARG = "disable_tracing"
2424
LOGGER_NAME_ARG = "logger_name"
2525
INSTRUMENTATION_OPTIONS_ARG = "instrumentation_options"
26+
RESOURCE_ARG = "resource"
2627
SAMPLING_RATIO_ARG = "sampling_ratio"
2728

2829

sdk/monitor/azure-monitor-opentelemetry/azure/monitor/opentelemetry/_util/configurations.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,33 @@
1616
from opentelemetry.instrumentation.environment_variables import (
1717
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,
1818
)
19-
from opentelemetry.sdk.environment_variables import OTEL_TRACES_SAMPLER_ARG
19+
from opentelemetry.sdk.environment_variables import (
20+
OTEL_EXPERIMENTAL_RESOURCE_DETECTORS,
21+
OTEL_TRACES_SAMPLER_ARG,
22+
)
23+
from opentelemetry.sdk.resources import Resource
2024

2125
from azure.monitor.opentelemetry._constants import (
26+
_AZURE_APP_SERVICE_RESOURCE_DETECTOR_NAME,
27+
_AZURE_VM_RESOURCE_DETECTOR_NAME,
2228
_FULLY_SUPPORTED_INSTRUMENTED_LIBRARIES,
2329
_PREVIEW_INSTRUMENTED_LIBRARIES,
2430
DISABLE_LOGGING_ARG,
2531
DISABLE_METRICS_ARG,
2632
DISABLE_TRACING_ARG,
2733
INSTRUMENTATION_OPTIONS_ARG,
2834
LOGGER_NAME_ARG,
35+
RESOURCE_ARG,
2936
SAMPLING_RATIO_ARG,
3037
)
3138
from azure.monitor.opentelemetry._types import ConfigurationValue
3239

3340

3441
_INVALID_FLOAT_MESSAGE = "Value of %s must be a float. Defaulting to %s: %s"
35-
36-
42+
_SUPPORTED_RESOURCE_DETECTORS = (
43+
_AZURE_APP_SERVICE_RESOURCE_DETECTOR_NAME,
44+
_AZURE_VM_RESOURCE_DETECTOR_NAME,
45+
)
3746
# TODO: remove when sampler uses env var instead
3847
SAMPLING_RATIO_ENV_VAR = OTEL_TRACES_SAMPLER_ARG
3948

@@ -51,6 +60,7 @@ def _get_configurations(**kwargs) -> Dict[str, ConfigurationValue]:
5160
_default_disable_metrics(configurations)
5261
_default_disable_tracing(configurations)
5362
_default_logger_name(configurations)
63+
_default_resource(configurations)
5464
_default_sampling_ratio(configurations)
5565
_default_instrumentation_options(configurations)
5666

@@ -86,6 +96,14 @@ def _default_logger_name(configurations):
8696
configurations[LOGGER_NAME_ARG] = ""
8797

8898

99+
def _default_resource(configurations):
100+
environ.setdefault(
101+
OTEL_EXPERIMENTAL_RESOURCE_DETECTORS,
102+
",".join(_SUPPORTED_RESOURCE_DETECTORS)
103+
)
104+
configurations[RESOURCE_ARG] = Resource.create()
105+
106+
89107
# TODO: remove when sampler uses env var instead
90108
def _default_sampling_ratio(configurations):
91109
default = 1.0

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

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
_setup_instrumentations,
2121
_setup_logging,
2222
_setup_metrics,
23-
_setup_resources,
2423
_setup_tracing,
2524
configure_azure_monitor,
2625
)
@@ -39,12 +38,8 @@ class TestConfigure(unittest.TestCase):
3938
@patch(
4039
"azure.monitor.opentelemetry._configure._setup_tracing",
4140
)
42-
@patch(
43-
"azure.monitor.opentelemetry._configure._setup_resources",
44-
)
4541
def test_configure_azure_monitor(
4642
self,
47-
resource_mock,
4843
tracing_mock,
4944
logging_mock,
5045
metrics_mock,
@@ -54,7 +49,6 @@ def test_configure_azure_monitor(
5449
"connection_string": "test_cs",
5550
}
5651
configure_azure_monitor(**kwargs)
57-
resource_mock.assert_called_once()
5852
tracing_mock.assert_called_once()
5953
logging_mock.assert_called_once()
6054
metrics_mock.assert_called_once()
@@ -72,16 +66,12 @@ def test_configure_azure_monitor(
7266
@patch(
7367
"azure.monitor.opentelemetry._configure._setup_tracing",
7468
)
75-
@patch(
76-
"azure.monitor.opentelemetry._configure._setup_resources",
77-
)
7869
@patch(
7970
"azure.monitor.opentelemetry._configure._get_configurations",
8071
)
8172
def test_configure_azure_monitor_disable_tracing(
8273
self,
8374
config_mock,
84-
resource_mock,
8575
tracing_mock,
8676
logging_mock,
8777
metrics_mock,
@@ -106,7 +96,6 @@ def test_configure_azure_monitor_disable_tracing(
10696
}
10797
config_mock.return_value = configurations
10898
configure_azure_monitor()
109-
resource_mock.assert_called_once()
11099
tracing_mock.assert_not_called()
111100
logging_mock.assert_called_once_with(configurations)
112101
metrics_mock.assert_called_once_with(configurations)
@@ -124,16 +113,12 @@ def test_configure_azure_monitor_disable_tracing(
124113
@patch(
125114
"azure.monitor.opentelemetry._configure._setup_tracing",
126115
)
127-
@patch(
128-
"azure.monitor.opentelemetry._configure._setup_resources",
129-
)
130116
@patch(
131117
"azure.monitor.opentelemetry._configure._get_configurations",
132118
)
133119
def test_configure_azure_monitor_disable_logging(
134120
self,
135121
config_mock,
136-
resource_mock,
137122
tracing_mock,
138123
logging_mock,
139124
metrics_mock,
@@ -147,7 +132,6 @@ def test_configure_azure_monitor_disable_logging(
147132
}
148133
config_mock.return_value = configurations
149134
configure_azure_monitor()
150-
resource_mock.assert_called_once()
151135
tracing_mock.assert_called_once_with(configurations)
152136
logging_mock.assert_not_called()
153137
metrics_mock.assert_called_once_with(configurations)
@@ -165,16 +149,12 @@ def test_configure_azure_monitor_disable_logging(
165149
@patch(
166150
"azure.monitor.opentelemetry._configure._setup_tracing",
167151
)
168-
@patch(
169-
"azure.monitor.opentelemetry._configure._setup_resources",
170-
)
171152
@patch(
172153
"azure.monitor.opentelemetry._configure._get_configurations",
173154
)
174155
def test_configure_azure_monitor_disable_metrics(
175156
self,
176157
config_mock,
177-
resource_mock,
178158
tracing_mock,
179159
logging_mock,
180160
metrics_mock,
@@ -188,44 +168,11 @@ def test_configure_azure_monitor_disable_metrics(
188168
}
189169
config_mock.return_value = configurations
190170
configure_azure_monitor()
191-
resource_mock.assert_called_once()
192171
tracing_mock.assert_called_once_with(configurations)
193172
logging_mock.assert_called_once_with(configurations)
194173
metrics_mock.assert_not_called()
195174
instrumentation_mock.assert_called_once_with(configurations)
196175

197-
@patch.dict("os.environ", {}, clear=True)
198-
def test_setup_resources(self):
199-
_setup_resources()
200-
self.assertEqual(
201-
os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"],
202-
"azure_app_service,azure_vm"
203-
)
204-
205-
@patch.dict("os.environ", {"OTEL_EXPERIMENTAL_RESOURCE_DETECTORS": ""})
206-
def test_setup_resources_empty_string(self):
207-
_setup_resources()
208-
self.assertEqual(
209-
os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"],
210-
""
211-
)
212-
213-
@patch.dict("os.environ", {"OTEL_EXPERIMENTAL_RESOURCE_DETECTORS": "test_detector"})
214-
def test_setup_resources_existing_detectors(self):
215-
_setup_resources()
216-
self.assertEqual(
217-
os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"],
218-
"test_detector"
219-
)
220-
221-
@patch.dict("os.environ", {"OTEL_EXPERIMENTAL_RESOURCE_DETECTORS": "azure_vm,test_detector, azure_app_service"})
222-
def test_setup_resources_azure_and_existing_detectors(self):
223-
_setup_resources()
224-
self.assertEqual(
225-
os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"],
226-
"azure_vm,test_detector, azure_app_service"
227-
)
228-
229176
@patch(
230177
"azure.monitor.opentelemetry._configure.settings",
231178
)
@@ -274,11 +221,13 @@ def test_setup_tracing(
274221
"azure_sdk": {"enabled": True}
275222
},
276223
"sampling_ratio": 0.5,
224+
"resource": "test_resource",
277225
}
278226
_setup_tracing(configurations)
279227
sampler_mock.assert_called_once_with(sampling_ratio=0.5)
280228
tp_mock.assert_called_once_with(
281229
sampler=sampler_init_mock,
230+
resource="test_resource"
282231
)
283232
set_tracer_provider_mock.assert_called_once_with(tp_init_mock)
284233
get_tracer_provider_mock.assert_called()
@@ -336,10 +285,11 @@ def test_setup_logging(
336285
configurations = {
337286
"connection_string": "test_cs",
338287
"logger_name": "test",
288+
"resource": "test_resource",
339289
}
340290
_setup_logging(configurations)
341291

342-
lp_mock.assert_called_once_with()
292+
lp_mock.assert_called_once_with(resource="test_resource")
343293
set_logger_provider_mock.assert_called_once_with(lp_init_mock)
344294
get_logger_provider_mock.assert_called()
345295
log_exporter_mock.assert_called_once_with(**configurations)
@@ -386,10 +336,12 @@ def test_setup_metrics(
386336

387337
configurations = {
388338
"connection_string": "test_cs",
339+
"resource": "test_resource",
389340
}
390341
_setup_metrics(configurations)
391342
mp_mock.assert_called_once_with(
392343
metric_readers=[reader_init_mock],
344+
resource="test_resource"
393345
)
394346
set_meter_provider_mock.assert_called_once_with(mp_init_mock)
395347
metric_exporter_mock.assert_called_once_with(**configurations)

0 commit comments

Comments
 (0)