Skip to content

Commit f7040e4

Browse files
committed
sdk: Implement basic os resource detector
Based on OS resource semantics: https://opentelemetry.io/docs/specs/semconv/resource/os/ Currently implements `os.type` and `os.version`, attempting to be in line with what's reported by other runtimes (like java and node).
1 parent 754fc36 commit f7040e4

File tree

2 files changed

+103
-1
lines changed

2 files changed

+103
-1
lines changed

opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import concurrent.futures
6060
import logging
6161
import os
62+
import platform
6263
import sys
6364
import typing
6465
from json import dumps
@@ -119,8 +120,9 @@
119120
KUBERNETES_JOB_NAME = ResourceAttributes.K8S_JOB_NAME
120121
KUBERNETES_CRON_JOB_UID = ResourceAttributes.K8S_CRONJOB_UID
121122
KUBERNETES_CRON_JOB_NAME = ResourceAttributes.K8S_CRONJOB_NAME
122-
OS_TYPE = ResourceAttributes.OS_TYPE
123123
OS_DESCRIPTION = ResourceAttributes.OS_DESCRIPTION
124+
OS_TYPE = ResourceAttributes.OS_TYPE
125+
OS_VERSION = ResourceAttributes.OS_VERSION
124126
PROCESS_PID = ResourceAttributes.PROCESS_PID
125127
PROCESS_PARENT_PID = ResourceAttributes.PROCESS_PARENT_PID
126128
PROCESS_EXECUTABLE_NAME = ResourceAttributes.PROCESS_EXECUTABLE_NAME
@@ -371,6 +373,72 @@ def detect(self) -> "Resource":
371373
return Resource(resource_info)
372374

373375

376+
class OsResourceDetector(ResourceDetector):
377+
"""Detect os resources based on `Operating System conventions <https://opentelemetry.io/docs/specs/semconv/resource/os/`_."""
378+
379+
def detect(self) -> "Resource":
380+
"""Returns a resource with with `os.type` and `os.version`. Example of
381+
return values for `platform` calls in different systems:
382+
383+
Linux:
384+
>>> platform.system()
385+
'Linux'
386+
>>> platform.release()
387+
'6.5.0-35-generic'
388+
>>> platform.version()
389+
'#35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 7 09:00:52 UTC 2'
390+
391+
MacOS:
392+
>>> platform.system()
393+
'Darwin'
394+
>>> platform.release()
395+
'23.0.0'
396+
>>> platform.version()
397+
'Darwin Kernel Version 23.0.0: Fri Sep 15 14:42:57 PDT 2023; root:xnu-10002.1.13~1/RELEASE_ARM64_T8112'
398+
399+
Windows:
400+
>>> platform.system()
401+
'Windows'
402+
>>> platform.release()
403+
'2022Server'
404+
>>> platform.version()
405+
'10.0.20348'
406+
407+
FreeBSD:
408+
>>> platform.system()
409+
'FreeBSD'
410+
>>> platform.release()
411+
'14.1-RELEASE'
412+
>>> platform.version()
413+
'FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC'
414+
415+
Solaris:
416+
>>> platform.system()
417+
'SunOS'
418+
>>> platform.release()
419+
'5.11'
420+
>>> platform.version()
421+
'11.4.0.15.0'
422+
"""
423+
424+
os_type = platform.system().lower()
425+
os_version = platform.release()
426+
427+
# See docstring
428+
if os_type == "windows":
429+
os_version = platform.version()
430+
# Align SunOS with conventions
431+
if os_type == "sunos":
432+
os_type = "solaris"
433+
434+
return Resource(
435+
{
436+
OS_TYPE: os_type,
437+
OS_VERSION: os_version,
438+
}
439+
)
440+
441+
374442
def get_aggregated_resources(
375443
detectors: typing.List["ResourceDetector"],
376444
initial_resource: typing.Optional[Resource] = None,

opentelemetry-sdk/tests/resources/test_resources.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
_DEFAULT_RESOURCE,
2929
_EMPTY_RESOURCE,
3030
_OPENTELEMETRY_SDK_VERSION,
31+
OS_TYPE,
32+
OS_VERSION,
3133
OTEL_RESOURCE_ATTRIBUTES,
3234
OTEL_SERVICE_NAME,
3335
PROCESS_COMMAND,
@@ -45,6 +47,7 @@
4547
TELEMETRY_SDK_LANGUAGE,
4648
TELEMETRY_SDK_NAME,
4749
TELEMETRY_SDK_VERSION,
50+
OsResourceDetector,
4851
OTELResourceDetector,
4952
ProcessResourceDetector,
5053
Resource,
@@ -723,3 +726,34 @@ def test_resource_detector_entry_points_otel(self):
723726
)
724727
self.assertIn(PROCESS_RUNTIME_VERSION, resource.attributes.keys())
725728
self.assertEqual(resource.schema_url, "")
729+
730+
@patch("platform.system", lambda: "Linux")
731+
@patch("platform.release", lambda: "666.5.0-35-generic")
732+
def test_os_detector_linux(self):
733+
resource = get_aggregated_resources(
734+
[OsResourceDetector()],
735+
Resource({}),
736+
)
737+
738+
self.assertEqual(resource.attributes[OS_TYPE], "linux")
739+
self.assertEqual(resource.attributes[OS_VERSION], "666.5.0-35-generic")
740+
741+
@patch("platform.system", lambda: "Windows")
742+
@patch("platform.version", lambda: "10.0.666")
743+
def test_os_detector_windows(self):
744+
resource = get_aggregated_resources(
745+
[OsResourceDetector()],
746+
Resource({}),
747+
)
748+
749+
self.assertEqual(resource.attributes[OS_TYPE], "windows")
750+
self.assertEqual(resource.attributes[OS_VERSION], "10.0.666")
751+
752+
@patch("platform.system", lambda: "SunOS")
753+
def test_os_detector_solaris(self):
754+
resource = get_aggregated_resources(
755+
[OsResourceDetector()],
756+
Resource({}),
757+
)
758+
759+
self.assertEqual(resource.attributes[OS_TYPE], "solaris")

0 commit comments

Comments
 (0)