Loading core/lib/Drupal/Core/Database/Connection.php +3 −1 Original line number Diff line number Diff line Loading @@ -2205,7 +2205,9 @@ public static function removeDatabaseEntriesFromDebugBacktrace(array $backtrace, * The debug backtrace. */ protected function getDebugBacktrace(): array { return debug_backtrace(); // @todo: allow a backtrace including all arguments as an option. // See https://www.drupal.org/project/drupal/issues/3401906 return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); } } core/modules/system/tests/modules/performance_test/performance_test.info.yml 0 → 100644 +5 −0 Original line number Diff line number Diff line name: 'Performance test' type: module description: 'Supports performance testing with PerformanceTestTrait' package: Testing version: VERSION core/modules/system/tests/modules/performance_test/performance_test.services.yml 0 → 100644 +9 −0 Original line number Diff line number Diff line services: Drupal\performance_test\PerformanceDataCollector: tags: - { name: event_subscriber } - { name: needs_destruction, priority: -1000 } Drupal\performance_test\DatabaseEventEnabler: arguments: ['@database'] tags: - { name: http_middleware, priority: 1000, responder: true } core/modules/system/tests/modules/performance_test/src/DatabaseEventEnabler.php 0 → 100644 +32 −0 Original line number Diff line number Diff line <?php namespace Drupal\performance_test; use Drupal\Core\Database\Connection; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Drupal\Core\Database\Event\StatementExecutionEndEvent; use Drupal\Core\Database\Event\StatementExecutionStartEvent; class DatabaseEventEnabler implements HttpKernelInterface { public function __construct(protected readonly HttpKernelInterface $httpKernel, protected readonly Connection $connection) {} /** * {@inheritdoc} */ public function handle(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE): Response { if ($type === static::MAIN_REQUEST) { $this->connection->enableEvents([ // StatementExecutionStartEvent must be enabled in order for // StatementExecutionEndEvent to be fired, even though we only subscribe // to the latter event. StatementExecutionStartEvent::class, StatementExecutionEndEvent::class, ]); } return $this->httpKernel->handle($request, $type, $catch); } } core/modules/system/tests/modules/performance_test/src/PerformanceDataCollector.php 0 → 100644 +51 −0 Original line number Diff line number Diff line <?php namespace Drupal\performance_test; use Drupal\Core\Database\Event\StatementExecutionEndEvent; use Drupal\Core\DestructableInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class PerformanceDataCollector implements EventSubscriberInterface, DestructableInterface { /** * Database events collected during the request. * * @var Drupal\Core\Database\Event\StatementExecutionEndEvent[] */ protected array $databaseEvents = []; /** * {@inheritdoc} */ public static function getSubscribedEvents(): array { return [ StatementExecutionEndEvent::class => 'onStatementExecutionEnd', ]; } /** * Logs database statements. */ public function onStatementExecutionEnd(StatementExecutionEndEvent $event): void { // Use the event object as a value object. $this->databaseEvents[] = $event; } /** * {@inheritdoc} */ public function destruct(): void { // Get the events now before issuing any more database queries so that this // logging does not become part of the recorded data. $database_events = $this->databaseEvents; // Deliberately do not use an injected key value service to avoid any // overhead up until this point. $collection = \Drupal::keyValue('performance_test'); $existing_data = $collection->get('performance_test_data') ?? ['database_events' => []]; $existing_data['database_events'] = array_merge($existing_data['database_events'], $database_events); $collection->set('performance_test_data', $existing_data); } } Loading
core/lib/Drupal/Core/Database/Connection.php +3 −1 Original line number Diff line number Diff line Loading @@ -2205,7 +2205,9 @@ public static function removeDatabaseEntriesFromDebugBacktrace(array $backtrace, * The debug backtrace. */ protected function getDebugBacktrace(): array { return debug_backtrace(); // @todo: allow a backtrace including all arguments as an option. // See https://www.drupal.org/project/drupal/issues/3401906 return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); } }
core/modules/system/tests/modules/performance_test/performance_test.info.yml 0 → 100644 +5 −0 Original line number Diff line number Diff line name: 'Performance test' type: module description: 'Supports performance testing with PerformanceTestTrait' package: Testing version: VERSION
core/modules/system/tests/modules/performance_test/performance_test.services.yml 0 → 100644 +9 −0 Original line number Diff line number Diff line services: Drupal\performance_test\PerformanceDataCollector: tags: - { name: event_subscriber } - { name: needs_destruction, priority: -1000 } Drupal\performance_test\DatabaseEventEnabler: arguments: ['@database'] tags: - { name: http_middleware, priority: 1000, responder: true }
core/modules/system/tests/modules/performance_test/src/DatabaseEventEnabler.php 0 → 100644 +32 −0 Original line number Diff line number Diff line <?php namespace Drupal\performance_test; use Drupal\Core\Database\Connection; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Drupal\Core\Database\Event\StatementExecutionEndEvent; use Drupal\Core\Database\Event\StatementExecutionStartEvent; class DatabaseEventEnabler implements HttpKernelInterface { public function __construct(protected readonly HttpKernelInterface $httpKernel, protected readonly Connection $connection) {} /** * {@inheritdoc} */ public function handle(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE): Response { if ($type === static::MAIN_REQUEST) { $this->connection->enableEvents([ // StatementExecutionStartEvent must be enabled in order for // StatementExecutionEndEvent to be fired, even though we only subscribe // to the latter event. StatementExecutionStartEvent::class, StatementExecutionEndEvent::class, ]); } return $this->httpKernel->handle($request, $type, $catch); } }
core/modules/system/tests/modules/performance_test/src/PerformanceDataCollector.php 0 → 100644 +51 −0 Original line number Diff line number Diff line <?php namespace Drupal\performance_test; use Drupal\Core\Database\Event\StatementExecutionEndEvent; use Drupal\Core\DestructableInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class PerformanceDataCollector implements EventSubscriberInterface, DestructableInterface { /** * Database events collected during the request. * * @var Drupal\Core\Database\Event\StatementExecutionEndEvent[] */ protected array $databaseEvents = []; /** * {@inheritdoc} */ public static function getSubscribedEvents(): array { return [ StatementExecutionEndEvent::class => 'onStatementExecutionEnd', ]; } /** * Logs database statements. */ public function onStatementExecutionEnd(StatementExecutionEndEvent $event): void { // Use the event object as a value object. $this->databaseEvents[] = $event; } /** * {@inheritdoc} */ public function destruct(): void { // Get the events now before issuing any more database queries so that this // logging does not become part of the recorded data. $database_events = $this->databaseEvents; // Deliberately do not use an injected key value service to avoid any // overhead up until this point. $collection = \Drupal::keyValue('performance_test'); $existing_data = $collection->get('performance_test_data') ?? ['database_events' => []]; $existing_data['database_events'] = array_merge($existing_data['database_events'], $database_events); $collection->set('performance_test_data', $existing_data); } }