diff --git a/.phan/config.php b/.phan/config.php index d8c6d47e0..9a20886d7 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -375,7 +375,6 @@ 'vendor/guzzlehttp', 'vendor/psr', 'vendor/php-http', - 'vendor/phan/phan/src/Phan', 'vendor/phpunit/phpunit/src', 'vendor/google/protobuf/src', ], diff --git a/src/SDK/Trace/Span.php b/src/SDK/Trace/Span.php index 9ef5315fa..4196ff96f 100644 --- a/src/SDK/Trace/Span.php +++ b/src/SDK/Trace/Span.php @@ -4,6 +4,7 @@ namespace OpenTelemetry\SDK\Trace; +use OpenTelemetry\API\Behavior\LogsMessagesTrait; use OpenTelemetry\API\Common\Time\Clock; use OpenTelemetry\API\Trace as API; use OpenTelemetry\API\Trace\SpanContextInterface; @@ -17,6 +18,7 @@ final class Span extends API\Span implements ReadWriteSpanInterface { + use LogsMessagesTrait; /** @var list */ private array $events = []; @@ -249,6 +251,15 @@ public function end(int $endEpochNanos = null): void return; } + $spanData = $this->toSpanData(); + if ($spanData->getTotalDroppedLinks() || $spanData->getTotalDroppedEvents() || $spanData->getAttributes()->getDroppedAttributesCount()) { + self::logWarning('Dropped span attributes, links or events', [ + 'attributes' => $spanData->getAttributes()->getDroppedAttributesCount(), + 'links' => $spanData->getTotalDroppedLinks(), + 'events' => $spanData->getTotalDroppedEvents(), + ]); + } + $this->endEpochNanos = $endEpochNanos ?? Clock::getDefault()->now(); $this->hasEnded = true; diff --git a/tests/Integration/SDK/SpanBuilderTest.php b/tests/Integration/SDK/SpanBuilderTest.php index 702c21423..12cd77a16 100644 --- a/tests/Integration/SDK/SpanBuilderTest.php +++ b/tests/Integration/SDK/SpanBuilderTest.php @@ -7,6 +7,7 @@ use Mockery; use Mockery\Adapter\Phpunit\MockeryTestCase; use Mockery\MockInterface; +use OpenTelemetry\API\Behavior\Internal\Logging; use OpenTelemetry\API\Trace as API; use OpenTelemetry\API\Trace\SpanContext; use OpenTelemetry\API\Trace\SpanContextValidator; @@ -96,6 +97,7 @@ public function test_add_link_invalid(): void public function test_add_link_dropping_links(): void { + Logging::disable(); $maxNumberOfLinks = 8; $tracerProvider = new TracerProvider([], null, null, (new SpanLimitsBuilder())->setLinkCountLimit($maxNumberOfLinks)->build()); $spanBuilder = $tracerProvider diff --git a/tests/Integration/SDK/TracerTest.php b/tests/Integration/SDK/TracerTest.php index 44f2b8fa6..b38171f7a 100644 --- a/tests/Integration/SDK/TracerTest.php +++ b/tests/Integration/SDK/TracerTest.php @@ -4,6 +4,7 @@ namespace OpenTelemetry\Tests\Integration\SDK; +use OpenTelemetry\API\Behavior\Internal\Logging; use OpenTelemetry\API\Trace as API; use OpenTelemetry\API\Trace\NonRecordingSpan; use OpenTelemetry\API\Trace\SpanContext; @@ -113,6 +114,7 @@ public function test_factory_returns_noop_tracer_when_sdk_disabled(): void public function test_general_identity_attributes_are_dropped_by_default(): void { + Logging::disable(); $exporter = new InMemoryExporter(); $tracerProvider = new TracerProvider(new SimpleSpanProcessor($exporter)); $tracer = $tracerProvider->getTracer('test'); diff --git a/tests/Unit/SDK/Trace/SpanTest.php b/tests/Unit/SDK/Trace/SpanTest.php index 077b9edee..810dd2370 100644 --- a/tests/Unit/SDK/Trace/SpanTest.php +++ b/tests/Unit/SDK/Trace/SpanTest.php @@ -48,6 +48,8 @@ #[CoversClass(Span::class)] class SpanTest extends MockeryTestCase { + private const TRACE_ID = 'e4a8d4e0d75c0702200af2882cb16c6b'; + private const SPAN_ID = '46701247e52c2d1b'; private const SPAN_NAME = 'test_span'; private const NEW_SPAN_NAME = 'new_test_span'; private const START_EPOCH = 1000123789654; @@ -655,6 +657,7 @@ public function test_attribute_length(): void public function test_dropping_attributes(): void { $maxNumberOfAttributes = 8; + $this->expectDropped(8, 0, 0); $span = $this->createTestSpan(API\SpanKind::KIND_INTERNAL, (new SpanLimitsBuilder())->setAttributeCountLimit($maxNumberOfAttributes)->build()); foreach (range(1, $maxNumberOfAttributes * 2) as $idx) { @@ -676,6 +679,7 @@ public function test_dropping_attributes(): void public function test_dropping_attributes_provided_via_span_builder(): void { $maxNumberOfAttributes = 8; + $this->expectDropped(8, 0, 0); $attributesBuilder = Attributes::factory()->builder(); @@ -704,6 +708,7 @@ public function test_dropping_attributes_provided_via_span_builder(): void public function test_dropping_events(): void { + $this->expectDropped(0, 8, 0); $maxNumberOfEvents = 8; $span = $this->createTestSpan(API\SpanKind::KIND_INTERNAL, (new SpanLimitsBuilder())->setEventCountLimit($maxNumberOfEvents)->build()); @@ -719,6 +724,26 @@ public function test_dropping_events(): void $span->end(); } + public function test_dropping_links(): void + { + $maxNumberOfLinks = 8; + $expectedDroppedLinks = 9; //test span contains one link by default + $this->expectDropped(0, 0, $expectedDroppedLinks); + $span = $this->createTestSpan(API\SpanKind::KIND_INTERNAL, (new SpanLimitsBuilder())->setLinkCountLimit($maxNumberOfLinks)->build()); + $ctx = SpanContext::create(self::TRACE_ID, self::SPAN_ID); + + foreach (range(1, $maxNumberOfLinks * 2) as $_idx) { + $span->addLink($ctx); + $this->testClock->advanceSeconds(); + } + + $spanData = $span->toSpanData(); + $this->assertCount($maxNumberOfLinks, $spanData->getLinks()); + $this->assertSame($expectedDroppedLinks, $spanData->getTotalDroppedLinks()); + + $span->end(); + } + // endregion SDK #[Group('trace-compliance')] public function test_set_attributes_merges_attributes(): void @@ -915,4 +940,18 @@ private function assertSpanData( $this->assertSame($hasEnded, $spanData->hasEnded()); $this->assertEquals($attributes, $spanData->getAttributes()); } + + private function expectDropped(int $attributes, int $events, int $links): void + { + $this->logWriter->expects($this->once())->method('write')->with( + $this->anything(), + $this->stringContains('Dropped span attributes'), + $this->equalTo([ + 'attributes' => $attributes, + 'links' => $links, + 'events' => $events, + 'source' => 'OpenTelemetry\\SDK\\Trace\\Span', + ]) + ); + } }