Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
LogIntegrationTest.php 3.34 KiB
<?php

declare(strict_types=1);

namespace Drupal\Tests\otlog\Functional;

use Drupal\Component\OTUnit\FileExporterTrait;
use Drupal\Component\OTUnit\ProtoHelpersTrait;
use Drupal\Component\OTUnit\SdkAutoloadingTrait;
use Drupal\otlog\Logger\OtLog;
use Drupal\Tests\BrowserTestBase;
use Opentelemetry\Proto\Logs\V1\LogRecord;
use OpenTelemetry\SemConv\TraceAttributes;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;

/**
 * End-to-end test for OpenTelemetry SDK autoloading and configuration.
 */
#[Group('otlog')]
#[CoversClass(OtLog::class)]
final class LogIntegrationTest extends BrowserTestBase {

  use FileExporterTrait;
  use ProtoHelpersTrait;
  use SdkAutoloadingTrait;

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected static $modules = ['otlog', 'otlog_test'];

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $this->setupSdkAutoloading($this->getFileExporterConfigurationVariables());
  }

  /**
   * Tests a controller generating a debug message.
   */
  public function testDebugMessage(): void {
    $this->resetFileExporterResultFiles();
    $this->drupalGet('/otlog_test/debug');

    [$logMessage] = $this->waitForLogs();

    // Check resource attribute.
    $traceResource = $this->getLogResource($logMessage);
    $sdkName = $this->getAttributeValue(
      TraceAttributes::TELEMETRY_SDK_NAME,
      $traceResource->getAttributes()
    );
    $this->assertNotNull($sdkName);
    $this->assertTrue($sdkName->hasStringValue());
    $this->assertEquals('opentelemetry', $sdkName->getStringValue());

    // Check scope.
    $scope = $this->getLogScope($logMessage);
    $this->assertEquals(
      'org.drupal.otlog',
      $scope->getName()
    );

    $logs = $this->getLogRecords($logMessage);
    assert($logs[0] instanceof LogRecord);

    $body = $logs[0]->getBody();
    $this->assertNotNull($body);
    $this->assertTrue($body->hasStringValue());
    $this->assertEquals('[test controller] [debug] test debug message', $body->getStringValue());

    $this->assertEquals(5, $logs[0]->getSeverityNumber());
    $this->assertEquals('debug', $logs[0]->getSeverityText());
  }

  /**
   * Tests controller causing an uncaught exception.
   */
  public function testException(): void {
    $this->resetFileExporterResultFiles();
    $this->drupalGet('/otlog_test/error');

    [$logMessage] = $this->waitForLogs();

    $logs = $this->getLogRecords($logMessage);
    assert($logs[0] instanceof LogRecord);

    $body = $logs[0]->getBody();
    $this->assertNotNull($body);
    $this->assertTrue($body->hasStringValue());
    $this->assertStringStartsWith('[php] [error] RuntimeException: test exception in Drupal\otlog_test\TestControllers->exception() (line ', $body->getStringValue());
    $this->assertStringEndsWith('/otlrs_test/src/TestControllers.php).', $body->getStringValue());

    $this->assertEquals(17, $logs[0]->getSeverityNumber());
    $this->assertEquals('error', $logs[0]->getSeverityText());

    $codeStacktrace = $this->getAttributeValue(
      TraceAttributes::CODE_STACKTRACE,
      $logs[0]->getAttributes(),
    );
    $this->assertNotNull($codeStacktrace);
    $this->assertTrue($codeStacktrace->hasStringValue());
    $this->assertStringContainsString('TestControllers->exception()', $codeStacktrace->getStringValue());
  }

}