From fbea1859f77d2dd231a9add84432f92c6c399b34 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Fri, 17 Apr 2026 10:19:51 +0200 Subject: [PATCH] elasticotel: load resource detector as last Since OTel SDK 1.42.0 the order of the resource detectors is preserved. Move the otel resource detector as last so we can override other resource detector attributes from environment variables. --- docs/reference/edot-python/configuration.md | 4 ++-- src/elasticotel/distro/__init__.py | 6 ++++-- tests/distro/test_distro.py | 2 +- tests/integration/test_integration.py | 11 +++++++++++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/reference/edot-python/configuration.md b/docs/reference/edot-python/configuration.md index 50894310..7efa5c07 100644 --- a/docs/reference/edot-python/configuration.md +++ b/docs/reference/edot-python/configuration.md @@ -229,7 +229,7 @@ EDOT Python uses different defaults than OpenTelemetry Python for the following | Option | EDOT Python default | OpenTelemetry Python default | Notes | |---|---|---|---| -| `OTEL_EXPERIMENTAL_RESOURCE_DETECTORS` | `process_runtime,os,otel,telemetry_distro,service_instance,containerid,_gcp,aws_ec2,aws_ecs,aws_elastic_beanstalk,azure_app_service,azure_vm` | `otel` | | +| `OTEL_EXPERIMENTAL_RESOURCE_DETECTORS` | `process_runtime,os,telemetry_distro,service_instance,containerid,_gcp,aws_ec2,aws_ecs,aws_elastic_beanstalk,azure_app_service,azure_vm,otel` | `otel` | | | `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` | `DELTA` | `CUMULATIVE` | | | `OTEL_LOG_LEVEL` | `warn` | | {applies_to}`edot_python: ga 1.9.0` | | `OTEL_METRICS_EXEMPLAR_FILTER` | `always_off` | `trace_based` | | @@ -237,7 +237,7 @@ EDOT Python uses different defaults than OpenTelemetry Python for the following | `OTEL_TRACES_SAMPLER_ARG` | `1.0` | | {applies_to}`edot_python: ga 1.6.0`| :::{note} -`OTEL_EXPERIMENTAL_RESOURCE_DETECTORS` cloud resource detectors are dynamically set. When running in a Kubernetes Pod it will be set to `process_runtime,os,otel,telemetry_distro,service_instance,_gcp,aws_eks`. +`OTEL_EXPERIMENTAL_RESOURCE_DETECTORS` cloud resource detectors are dynamically set. When running in a Kubernetes Pod it will be set to `process_runtime,os,telemetry_distro,service_instance,_gcp,aws_eks,otel`. ::: :::{note} diff --git a/src/elasticotel/distro/__init__.py b/src/elasticotel/distro/__init__.py index 9f6e67c5..ac7482be 100644 --- a/src/elasticotel/distro/__init__.py +++ b/src/elasticotel/distro/__init__.py @@ -190,10 +190,12 @@ def _configure(self, **kwargs): base_resource_detectors = [ "process_runtime", "os", - "otel", "telemetry_distro", "service_instance", "containerid", ] - detectors = base_resource_detectors + get_cloud_resource_detectors() + # the `otel` resource detector reads the `OTEL_RESOURCE_ATTRIBUTES` and `OTEL_SERVICE_NAME` + # from the environment variables. Keep it last so we can override attributes by the other + # resource detectors + detectors = base_resource_detectors + get_cloud_resource_detectors() + ["otel"] os.environ.setdefault(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, ",".join(detectors)) diff --git a/tests/distro/test_distro.py b/tests/distro/test_distro.py index 106d3b3c..5ec681f7 100644 --- a/tests/distro/test_distro.py +++ b/tests/distro/test_distro.py @@ -69,7 +69,7 @@ def test_default_configuration(self): self.assertEqual("otlp", os.environ.get(OTEL_LOGS_EXPORTER)) self.assertEqual("grpc", os.environ.get(OTEL_EXPORTER_OTLP_PROTOCOL)) self.assertEqual( - "process_runtime,os,otel,telemetry_distro,service_instance,containerid,_gcp,aws_ec2,aws_ecs,aws_elastic_beanstalk,azure_app_service,azure_vm", + "process_runtime,os,telemetry_distro,service_instance,containerid,_gcp,aws_ec2,aws_ecs,aws_elastic_beanstalk,azure_app_service,azure_vm,otel", os.environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS), ) self.assertEqual("always_off", os.environ.get(OTEL_METRICS_EXEMPLAR_FILTER)) diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index bd1f8bce..8901c783 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -77,6 +77,17 @@ def test_traces_sets_resource_attributes_from_env(self): resource = span["resource"] self.assertEqual(resource["service.name"], "my-service") + def test_traces_can_override_resource_attributes_from_env(self): + env = {"OTEL_RESOURCE_ATTRIBUTES": "telemetry.distro.name=custom-distro"} + stdout, stderr, returncode = self.run_script( + self.script, environment_variables=env, wrapper_script="opentelemetry-instrument" + ) + + telemetry = self.get_telemetry() + (span,) = telemetry["traces"] + resource = span["resource"] + self.assertEqual(resource["telemetry.distro.name"], "custom-distro") + def test_metrics_default_does_not_contain_system_metrics(self): stdout, stderr, returncode = self.run_script(self.script, wrapper_script="opentelemetry-instrument")