Skip to content
Merged
1 change: 1 addition & 0 deletions .changelog/5259.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`opentelemetry-sdk`: add `ServiceInstanceIdResourceDetector` for populating `service.instance.id`
1 change: 1 addition & 0 deletions opentelemetry-sdk/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ otel = "opentelemetry.sdk.resources:OTELResourceDetector"
process = "opentelemetry.sdk.resources:ProcessResourceDetector"
os = "opentelemetry.sdk.resources:OsResourceDetector"
host = "opentelemetry.sdk.resources:_HostResourceDetector"
service_instance = "opentelemetry.sdk.resources:ServiceInstanceIdResourceDetector"

[project.urls]
Homepage = "https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-sdk"
Expand Down
16 changes: 16 additions & 0 deletions opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import socket
import sys
import typing
import uuid
from collections.abc import Sequence
from json import dumps
from os import environ
Expand Down Expand Up @@ -462,6 +463,21 @@ def detect(self) -> "Resource":
)


class ServiceInstanceIdResourceDetector(ResourceDetector):
"""Detects service.instance.id as a random UUID v4.

Per the OpenTelemetry specification, SDKs SHOULD generate a random v1/v4
UUID for service.instance.id to uniquely identify each service instance.
"""

def __init__(self, raise_on_error: bool = False) -> None:
super().__init__(raise_on_error)
self._instance_id = str(uuid.uuid4())

def detect(self) -> "Resource":
return Resource({SERVICE_INSTANCE_ID: self._instance_id})
Comment thread
herin049 marked this conversation as resolved.
Outdated


def _build_resource_detectors() -> list["ResourceDetector"]:
"""Returns the ordered list of resource detectors to use for Resource.create.

Expand Down
39 changes: 39 additions & 0 deletions opentelemetry-sdk/tests/resources/test_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
PROCESS_RUNTIME_DESCRIPTION,
PROCESS_RUNTIME_NAME,
PROCESS_RUNTIME_VERSION,
SERVICE_INSTANCE_ID,
SERVICE_NAME,
TELEMETRY_SDK_LANGUAGE,
TELEMETRY_SDK_NAME,
Expand All @@ -43,6 +44,7 @@
ProcessResourceDetector,
Resource,
ResourceDetector,
ServiceInstanceIdResourceDetector,
_HostResourceDetector,
get_aggregated_resources,
)
Expand Down Expand Up @@ -912,3 +914,40 @@ def test_resource_detector_entry_points_tolerate_missing_detector(self):
resource.attributes["telemetry.sdk.language"], "python"
)
self.assertIn(HOST_NAME, resource.attributes)


class TestServiceInstanceIdResourceDetector(unittest.TestCase):
def test_detect_value_is_valid_uuid4(self):
detector = ServiceInstanceIdResourceDetector()
value = detector.detect().attributes[SERVICE_INSTANCE_ID]
parsed = uuid.UUID(value)
self.assertEqual(parsed.version, 4)

def test_detect_stable_within_instance(self):
detector = ServiceInstanceIdResourceDetector()
id1 = detector.detect().attributes[SERVICE_INSTANCE_ID]
id2 = detector.detect().attributes[SERVICE_INSTANCE_ID]
self.assertEqual(id1, id2)

def test_detect_unique_across_instances(self):
id1 = (
ServiceInstanceIdResourceDetector()
.detect()
.attributes[SERVICE_INSTANCE_ID]
)
id2 = (
ServiceInstanceIdResourceDetector()
.detect()
.attributes[SERVICE_INSTANCE_ID]
)
self.assertNotEqual(id1, id2)
Comment thread
herin049 marked this conversation as resolved.
Outdated

@patch.dict(
environ,
{OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "service_instance"},
clear=True,
)
def test_resource_detector_entry_points_service_instance(self):
resource = Resource.create()
self.assertIn(SERVICE_INSTANCE_ID, resource.attributes)
uuid.UUID(resource.attributes[SERVICE_INSTANCE_ID])
Loading