From f8ee5d6f4e0ecb5f9acca5c9dfe036157729fccf Mon Sep 17 00:00:00 2001 From: Nathan <45177569+nmstory@users.noreply.github.com> Date: Sun, 1 Nov 2026 01:27:11 +0000 Subject: [PATCH] fix(agentex): ignore SDK-generated service.instance.id in otel metrics opentelemetry-sdk 1.45 makes Resource.create() fill service.instance.id with a random UUID by default. _unique_instance_id treated any existing value as operator-supplied and only appended the pid, so the per-worker id became . instead of ... Read the configured id from OTEL_RESOURCE_ATTRIBUTES only, so an explicit value is still extended with . (idempotently) and the SDK default falls through to the .. form. Co-Authored-By: Claude Opus 5.5 --- agentex/src/utils/otel_metrics.py | 4 +++- agentex/tests/unit/utils/test_otel_metrics.py | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/agentex/src/utils/otel_metrics.py b/agentex/src/utils/otel_metrics.py index be6f0bc3..57b37bdb 100644 --- a/agentex/src/utils/otel_metrics.py +++ b/agentex/src/utils/otel_metrics.py @@ -95,7 +95,9 @@ def _detected_resource() -> Resource: def _unique_instance_id(resource: Resource) -> str: """Worker-unique service.instance.id (OTel #4390).""" pid = os.getpid() - existing = resource.attributes.get("service.instance.id") + # Only honor an explicitly configured id: since opentelemetry-sdk 1.45, + # Resource.create() fills service.instance.id with a random UUID by default. + existing = OTELResourceDetector().detect().attributes.get("service.instance.id") if existing: existing = str(existing) suffix = f".{pid}" diff --git a/agentex/tests/unit/utils/test_otel_metrics.py b/agentex/tests/unit/utils/test_otel_metrics.py index 7089b4c4..43f15dac 100644 --- a/agentex/tests/unit/utils/test_otel_metrics.py +++ b/agentex/tests/unit/utils/test_otel_metrics.py @@ -189,6 +189,26 @@ def test_unique_instance_id_builds_when_missing(monkeypatch): assert otel_metrics._unique_instance_id(base) == "agentex.my-pod.42" +@pytest.mark.unit +def test_unique_instance_id_ignores_sdk_generated_default(monkeypatch): + monkeypatch.setenv("OTEL_SERVICE_NAME", "agentex") + monkeypatch.setenv("OTEL_RESOURCE_ATTRIBUTES", "k8s.pod.name=my-pod") + monkeypatch.setattr(otel_metrics.os, "getpid", lambda: 42) + base = Resource.create({"service.instance.id": "sdk-generated-uuid"}) + assert otel_metrics._unique_instance_id(base) == "agentex.my-pod.42" + + +@pytest.mark.unit +def test_unique_instance_id_is_idempotent(monkeypatch): + monkeypatch.setenv( + "OTEL_RESOURCE_ATTRIBUTES", + "k8s.pod.name=my-pod,service.instance.id=agentex.my-pod.agentex.42", + ) + monkeypatch.setattr(otel_metrics.os, "getpid", lambda: 42) + base = get_aggregated_resources([OTELResourceDetector()]) + assert otel_metrics._unique_instance_id(base) == "agentex.my-pod.agentex.42" + + @pytest.mark.unit def test_sync_instance_id_to_env_updates_env(monkeypatch): monkeypatch.setenv("OTEL_SERVICE_NAME", "agentex")