diff --git a/src/sap_cloud_sdk/core/telemetry/auto_instrument.py b/src/sap_cloud_sdk/core/telemetry/auto_instrument.py index fef7842e..1b4c0ebe 100644 --- a/src/sap_cloud_sdk/core/telemetry/auto_instrument.py +++ b/src/sap_cloud_sdk/core/telemetry/auto_instrument.py @@ -169,8 +169,15 @@ def _merge_resource_attrs_into_active_provider_if_wrapper_installed( if "telemetry.auto.version" not in existing_attrs: return - provider._resource = provider.resource.merge(Resource.create(sap_attrs)) + merged = provider.resource.merge(Resource.create(sap_attrs)) + + with provider._tracers_lock: + provider._resource = merged + for tracer in provider._tracers.values(): + tracer.resource = merged + logger.info( "Merged sap-cloud-sdk resource attrs onto wrapper-installed " - "TracerProvider (marker: telemetry.auto.version)" + "TracerProvider and %d cached Tracer(s) (marker: telemetry.auto.version)", + len(provider._tracers), ) diff --git a/tests/core/unit/telemetry/test_auto_instrument.py b/tests/core/unit/telemetry/test_auto_instrument.py index 98ed6328..220feded 100644 --- a/tests/core/unit/telemetry/test_auto_instrument.py +++ b/tests/core/unit/telemetry/test_auto_instrument.py @@ -330,6 +330,38 @@ def test_auto_instrument_merge_overrides_colliding_service_name(self, mock_trace assert wrapper_provider.resource.attributes['service.name'] == 'cloud-sdk-app' + def test_auto_instrument_back_patches_cached_tracers(self, mock_traceloop_components): + """Tracer objects cached in provider._tracers before auto_instrument() is + called must have their resource updated to the merged resource.""" + mock_traceloop_components['get_app_name'].return_value = 'cloud-sdk-app' + sap_attrs = { + 'service.name': 'cloud-sdk-app', + 'sap.cloud_sdk.name': 'SAP Cloud SDK for Python', + 'sap.cloud_sdk.language': 'python', + } + mock_traceloop_components['create_resource'].return_value = sap_attrs + + wrapper_provider = SDKTracerProvider( + resource=Resource.create({ + 'telemetry.auto.version': '0.62b1', + 'service.name': 'operator-supplied-name', + }) + ) + mock_traceloop_components['get_tracer_provider'].return_value = wrapper_provider + + pre_merge_tracer_a = wrapper_provider.get_tracer("opentelemetry.instrumentation.requests") + pre_merge_tracer_b = wrapper_provider.get_tracer("opentelemetry.instrumentation.langchain") + pre_merge_resource = pre_merge_tracer_a.resource + + with patch.dict('os.environ', {'OTEL_EXPORTER_OTLP_ENDPOINT': 'http://localhost:4317'}, clear=True): + auto_instrument() + + merged_resource = wrapper_provider.resource + assert merged_resource.attributes['sap.cloud_sdk.name'] == 'SAP Cloud SDK for Python' + assert pre_merge_tracer_a.resource is merged_resource + assert pre_merge_tracer_b.resource is merged_resource + assert pre_merge_tracer_a.resource is not pre_merge_resource + class TestAutoInstrumentMiddlewares: """Tests for the middlewares parameter of auto_instrument."""