Skip to content

Commit

Permalink
Adds experimental service.instance.id resource detector (open-telemet…
Browse files Browse the repository at this point in the history
…ry#1309)

* implement experimental service.instance.id attribute
  • Loading branch information
matt-hensley authored Jun 15, 2024
1 parent eebf23a commit 6bf422c
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 8 deletions.
1 change: 1 addition & 0 deletions .phan/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@
'vendor/phan/phan/src/Phan',
'vendor/phpunit/phpunit/src',
'vendor/google/protobuf/src',
'vendor/ramsey/uuid/src',
],

// A list of individual files to include in analysis
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
"php": "^8.1",
"google/protobuf": "^3.22",
"php-http/discovery": "^1.14",
"psr/http-client": "^1.0",
"psr/http-client-implementation": "^1.0",
"psr/http-factory-implementation": "^1.0",
"psr/http-client": "^1.0",
"psr/http-message": "^1.0.1|^2.0",
"psr/log": "^1.1|^2.0|^3.0",
"ramsey/uuid": "^3.0 || ^4.0",
"symfony/config": "^5.4 || ^6.4 || ^7.0",
"symfony/polyfill-mbstring": "^1.23",
"symfony/polyfill-php82": "^1.26",
Expand Down
17 changes: 11 additions & 6 deletions deptrac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,16 @@ deptrac:
regex: ^Composer\\*
- name: HttpClients
collectors:
- type: className
value: ^Symfony\\Component\\HttpClient\\*
- type: className
value: ^GuzzleHttp\\*
- type: className
value: ^Buzz\\*
- type: className
value: ^Symfony\\Component\\HttpClient\\*
- type: className
value: ^GuzzleHttp\\*
- type: className
value: ^Buzz\\*
- name: RamseyUuid
collectors:
- type: className
regex: ^Ramsey\\Uuid\\*

ruleset:
Context:
Expand All @@ -100,6 +104,7 @@ deptrac:
- HttpPlug
- Composer
- HttpClients
- RamseyUuid
Contrib:
- +SDK
- +OtelProto
Expand Down
1 change: 1 addition & 0 deletions src/SDK/Common/Configuration/KnownValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ interface KnownValues
public const VALUE_DETECTORS_PROCESS_RUNTIME = 'process_runtime';
public const VALUE_DETECTORS_SDK = 'sdk';
public const VALUE_DETECTORS_SDK_PROVIDED = 'sdk_provided';
public const VALUE_DETECTORS_SERVICE = 'service';
public const VALUE_DETECTORS_COMPOSER = 'composer';
public const OTEL_PHP_DETECTORS = [
self::VALUE_ALL,
Expand Down
29 changes: 29 additions & 0 deletions src/SDK/Resource/Detectors/Service.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Resource\Detectors;

use OpenTelemetry\SDK\Common\Attribute\Attributes;
use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SemConv\ResourceAttributes;
use Ramsey\Uuid\Uuid;

/**
* @see https://github.com/open-telemetry/semantic-conventions/tree/main/docs/resource#service-experimental
*/
final class Service implements ResourceDetectorInterface
{
public function getResource(): ResourceInfo
{
static $serviceInstanceId;
$serviceInstanceId ??= Uuid::uuid4()->toString();

$attributes = [
ResourceAttributes::SERVICE_INSTANCE_ID => $serviceInstanceId,
];

return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL);
}
}
4 changes: 4 additions & 0 deletions src/SDK/Resource/ResourceInfoFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ public static function defaultResource(): ResourceInfo

foreach ($detectors as $detector) {
switch ($detector) {
case Values::VALUE_DETECTORS_SERVICE:
$resourceDetectors[] = new Detectors\Service();

break;
case Values::VALUE_DETECTORS_ENVIRONMENT:
$resourceDetectors[] = new Detectors\Environment();

Expand Down
1 change: 1 addition & 0 deletions src/SDK/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"psr/http-client": "^1.0",
"psr/http-message": "^1.0.1|^2.0",
"psr/log": "^1.1|^2.0|^3.0",
"ramsey/uuid": "^3.0 || ^4.0",
"symfony/polyfill-mbstring": "^1.23",
"symfony/polyfill-php82": "^1.26"
},
Expand Down
22 changes: 22 additions & 0 deletions tests/Unit/SDK/Resource/Detectors/CompositeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,25 @@

use OpenTelemetry\SDK\Common\Attribute\Attributes;
use OpenTelemetry\SDK\Resource\Detectors\Composite;
use OpenTelemetry\SDK\Resource\Detectors\Environment;
use OpenTelemetry\SDK\Resource\Detectors\Service;
use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SemConv\ResourceAttributes;
use OpenTelemetry\Tests\TestState;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;

#[CoversClass(Composite::class)]
class CompositeTest extends TestCase
{
use TestState;

public function tearDown(): void
{
$this->restoreEnvironmentVariables();
}

public function test_composite_with_empty_resource_detectors(): void
{
$resourceDetector = new Composite([]);
Expand All @@ -36,4 +47,15 @@ public function test_composite_get_resource(): void
$this->assertSame('user-bar', $resource->getAttributes()->get('bar'));
$this->assertNull($resource->getSchemaUrl());
}

public function test_composite_get_resource_with_service_instance_id_from_resource_attributes()
{
$this->setEnvironmentVariable('OTEL_RESOURCE_ATTRIBUTES', 'service.instance.id=manual-id');
$resouceDetector = new Composite([
new Service(),
new Environment(),
]);
$resource = $resouceDetector->getResource();
$this->assertSame('manual-id', $resource->getAttributes()->get(ResourceAttributes::SERVICE_INSTANCE_ID));
}
}
41 changes: 41 additions & 0 deletions tests/Unit/SDK/Resource/Detectors/ServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Tests\Unit\SDK\Resource\Detectors;

use OpenTelemetry\SDK\Resource\Detectors;
use OpenTelemetry\SemConv\ResourceAttributes;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;

#[CoversClass(Detectors\Service::class)]
class ServiceTest extends TestCase
{
const UUID_REGEX = '/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i';

private Detectors\Service $detector;

public function setUp(): void
{
$this->detector = new Detectors\Service();
}

public function test_service_get_resource_with_default_service_instance_id(): void
{
$resource = $this->detector->getResource();

$this->assertNotEmpty($resource->getAttributes());

$id = $resource->getAttributes()->get(ResourceAttributes::SERVICE_INSTANCE_ID);
$this->assertMatchesRegularExpression(self::UUID_REGEX, $id);
}

public function test_service_get_resource_multiple_calls_same_service_instance_id(): void
{
$resource1 = $this->detector->getResource();
$resource2 = $this->detector->getResource();

$this->assertSame($resource1->getAttributes()->get(ResourceAttributes::SERVICE_INSTANCE_ID), $resource2->getAttributes()->get(ResourceAttributes::SERVICE_INSTANCE_ID));
}
}
2 changes: 1 addition & 1 deletion tests/Unit/SDK/Resource/ResourceInfoFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public function test_composite_default_with_extra_resource_from_registry(): void

public function test_default_with_all_sdk_detectors(): void
{
$this->setEnvironmentVariable('OTEL_PHP_DETECTORS', 'env,host,os,process,process_runtime,sdk,sdk_provided,composer');
$this->setEnvironmentVariable('OTEL_PHP_DETECTORS', 'service,env,host,os,process,process_runtime,sdk,sdk_provided,composer');
$resource = ResourceInfoFactory::defaultResource();
$keys = array_keys($resource->getAttributes()->toArray());
foreach (['service.name', 'telemetry.sdk.name', 'process.runtime.name', 'process.pid', 'host.arch'] as $key) {
Expand Down

0 comments on commit 6bf422c

Please sign in to comment.