From bb9eb40a5033abb2157994e087fdc6dd0a3cc559 Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Mon, 1 Apr 2024 18:20:09 -0400 Subject: [PATCH] Add host.id for non-containerized systems (#1266) Co-authored-by: Tobias Bachert Co-authored-by: Chris Lightfoot-Wild --- src/SDK/Resource/Detectors/Host.php | 72 +++++++++++++++++++ .../Unit/SDK/Resource/Detectors/HostTest.php | 53 ++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/src/SDK/Resource/Detectors/Host.php b/src/SDK/Resource/Detectors/Host.php index dd2554540..af5082778 100644 --- a/src/SDK/Resource/Detectors/Host.php +++ b/src/SDK/Resource/Detectors/Host.php @@ -15,13 +15,85 @@ */ final class Host implements ResourceDetectorInterface { + private const PATH_ETC_MACHINEID = 'etc/machine-id'; + private const PATH_VAR_LIB_DBUS_MACHINEID = 'var/lib/dbus/machine-id'; + private const PATH_ETC_HOSTID = 'etc/hostid'; + + public function __construct( + private readonly string $dir = '/', + private readonly string $os = PHP_OS_FAMILY, + ) { + } + public function getResource(): ResourceInfo { $attributes = [ ResourceAttributes::HOST_NAME => php_uname('n'), ResourceAttributes::HOST_ARCH => php_uname('m'), + ResourceAttributes::HOST_ID => $this->getMachineId(), ]; return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL); } + + private function getMachineId(): ?string + { + return match ($this->os) { + 'Linux' => $this->getLinuxId(), + 'BSD' => $this->getBsdId(), + 'Darwin' => $this->getMacOsId(), + 'Windows' => $this->getWindowsId(), + default => null, + }; + } + + private function getLinuxId(): ?string + { + $paths = [self::PATH_ETC_MACHINEID, self::PATH_VAR_LIB_DBUS_MACHINEID]; + + foreach ($paths as $path) { + if (file_exists($this->dir . $path)) { + return trim(file_get_contents($this->dir . $path)); + } + } + + return null; + } + + private function getBsdId(): ?string + { + if (file_exists($this->dir . self::PATH_ETC_HOSTID)) { + return trim(file_get_contents($this->dir . self::PATH_ETC_HOSTID)); + } + + $out = exec('kenv -q smbios.system.uuid'); + + if ($out != false) { + return $out; + } + + return null; + } + + private function getMacOsId(): ?string + { + $out = exec('ioreg -rd1 -c IOPlatformExpertDevice | awk \'/IOPlatformUUID/ { split($0, line, "\""); printf("%s\n", line[4]); }\''); + + if ($out != false) { + return $out; + } + + return null; + } + + private function getWindowsId(): ?string + { + $out = exec('powershell.exe -Command "Get-ItemPropertyValue -Path HKLM:\SOFTWARE\Microsoft\Cryptography -Name MachineGuid"'); + + if ($out != false) { + return $out; + } + + return null; + } } diff --git a/tests/Unit/SDK/Resource/Detectors/HostTest.php b/tests/Unit/SDK/Resource/Detectors/HostTest.php index 9264dc0e6..2bcddfddd 100644 --- a/tests/Unit/SDK/Resource/Detectors/HostTest.php +++ b/tests/Unit/SDK/Resource/Detectors/HostTest.php @@ -6,6 +6,7 @@ use OpenTelemetry\SDK\Resource\Detectors; use OpenTelemetry\SemConv\ResourceAttributes; +use org\bovigo\vfs\vfsStream; use PHPUnit\Framework\TestCase; /** @@ -22,4 +23,56 @@ public function test_host_get_resource(): void $this->assertIsString($resource->getAttributes()->get(ResourceAttributes::HOST_NAME)); $this->assertIsString($resource->getAttributes()->get(ResourceAttributes::HOST_ARCH)); } + + /** + * @dataProvider hostIdData + */ + public function test_host_id_filesystem(string $os, array $files, ?string $expectedId): void + { + $root = vfsStream::setup('/', null, $files); + $resouceDetector = new Detectors\Host($root->url(), $os); + $resource = $resouceDetector->getResource(); + + if ($expectedId === null) { + $this->assertFalse($resource->getAttributes()->has(ResourceAttributes::HOST_ID)); + + return; + } + + $hostId = $resource->getAttributes()->get(ResourceAttributes::HOST_ID); + $this->assertIsString($hostId); + $this->assertSame($expectedId, $hostId); + } + + public static function hostIdData(): array + { + $etc_machineid = [ + 'etc' => [ + 'machine-id' => '1234567890', + ], + ]; + $varLibDbus = [ + 'var' => [ + 'lib' => [ + 'dbus' => [ + 'machine-id' => '0987654321', + ], + ], + ], + ]; + $etc_hostid = [ + 'etc' => [ + 'hostid' => '1234567890', + ], + ]; + + return [ + ['Linux', [], null], + ['Linux', $etc_machineid, '1234567890'], + ['Linux', array_merge($etc_machineid, $varLibDbus), '1234567890'], + ['Linux', $etc_machineid, '1234567890'], + ['BSD', [], null], + ['BSD', $etc_hostid, '1234567890'], + ]; + } }