diff --git a/src/SDK/Logs/EventLogger.php b/src/SDK/Logs/EventLogger.php index 5ffbdddf3..62c303970 100644 --- a/src/SDK/Logs/EventLogger.php +++ b/src/SDK/Logs/EventLogger.php @@ -40,6 +40,12 @@ public function emit( iterable $attributes = [], ): void { $logRecord = new LogRecord(); + /** + * Set event.name twice: first to position it as the initial attribute entry, + * then again after setAttributes() to prevent its value from being overwritten. + * This ensures event.name won't be dropped by attribute limits. + * @see https://github.com/open-telemetry/opentelemetry-php/pull/1768#issuecomment-3527425474 + */ $logRecord->setAttribute('event.name', $name); $logRecord->setAttributes($attributes); $logRecord->setAttribute('event.name', $name); diff --git a/tests/Unit/SDK/Logs/EventLoggerTest.php b/tests/Unit/SDK/Logs/EventLoggerTest.php index c902036ee..98297a077 100644 --- a/tests/Unit/SDK/Logs/EventLoggerTest.php +++ b/tests/Unit/SDK/Logs/EventLoggerTest.php @@ -4,6 +4,7 @@ namespace OpenTelemetry\Tests\Unit\SDK\Logs; +use OpenTelemetry\API\Behavior\Internal\Logging; use OpenTelemetry\API\Common\Time\Clock; use OpenTelemetry\API\Common\Time\TestClock; use OpenTelemetry\API\Logs\LoggerInterface; @@ -12,7 +13,12 @@ use OpenTelemetry\Context\Context; use OpenTelemetry\SDK\Logs\EventLogger; use OpenTelemetry\SDK\Logs\EventLoggerProvider; +use OpenTelemetry\SDK\Logs\Exporter\InMemoryExporter; +use OpenTelemetry\SDK\Logs\LoggerProviderBuilder; use OpenTelemetry\SDK\Logs\LoggerProviderInterface; +use OpenTelemetry\SDK\Logs\Processor\SimpleLogRecordProcessor; +use OpenTelemetry\SDK\Logs\ReadableLogRecord; +use PHPUnit\Framework\Attributes\BackupGlobals; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -96,4 +102,32 @@ public function test_event_name_attribute_is_ignored(): void $eventLogger = $this->eventLoggerProvider->getEventLogger('event.logger'); $eventLogger->emit('my.event', attributes: ['event.name' => 'not.my.event']); } + + /** + * "The event.name attribute MUST be the first attribute added to the LogRecord" + * @see https://github.com/open-telemetry/opentelemetry-php/pull/1768#issuecomment-3527425474 + */ + #[BackupGlobals(true)] + public function test_event_name_is_not_dropped_first(): void + { + $_SERVER['OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT'] = 1; + $eventLoggerProvider = new EventLoggerProvider((new LoggerProviderBuilder()) + ->addLogRecordProcessor(new SimpleLogRecordProcessor($exporter = new InMemoryExporter())) + ->build()); + $eventLogger = $eventLoggerProvider->getEventLogger('test'); + + Logging::disable(); + + try { + $eventLogger->emit('my.event', attributes: ['other.attribute' => 'not.my.event']); + } finally { + Logging::reset(); + } + $eventLoggerProvider->forceFlush(); + + /** @var list $logs */ + $logs = $exporter->getStorage()->getArrayCopy(); + $this->assertCount(1, $logs); + $this->assertArrayHasKey('event.name', $logs[0]->getAttributes()->toArray()); + } }