2025-04-14

首先定义一个事件服务.

mymodule.services.yml

services
  mymodule.event_subscriber:
    class: Drupal\mymodule\EventSubscriber\MariadbProfileSubscriber
    tags:
      - { name: event_subscriber }

定义服务内容

<?php
declare(strict_types=1);
namespace Drupal\mymodule\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
 * @todo Add description for this subscriber.
 */
final class MariadbProfileSubscriber implements EventSubscriberInterface {
  /**
   * Kernel request event handler.
   */
  public function onKernelRequest(RequestEvent $event): void {
    // 开启profiles
    \Drupal::database()->query('set profiling=1')->execute();
  }
  public function onResponse(ResponseEvent $event):void {
    if ($event->isMainRequest()) {
      $is_debug_more = true;
      $strings = '';
      // 通过show profiles查看页面所有query的相应速度.
      $query_list = \Drupal::database()->query('show profiles;')->fetchAll();
      uasort($query_list, function($a, $b) {
        return ($a->Duration < $b->Duration) ? 1 : -1;
      });
      foreach ($query_list as $item) {
        $strings .= <<<EOF
QueryID = {$item->Query_ID}
Query = {$item->Query}
Duration = {$item->Duration}
EOF;
        if ($is_debug_more) {
          // 通过select INFORMATION_SCHEMA.PROFILING表来查看单条sql为什么会漫.
          // 设置query id.
          \Drupal::database()->query('set @query_id=' . $item->Query_ID);
          $query = <<<EOF
  SELECT STATE, SUM(DURATION) AS Total_R,
      ROUND(
      100* SUM(DURATION)/
      (SELECT SUM(DURATION) FROM INFORMATION_SCHEMA.PROFILING WHERE QUERY_ID = @query_id), 2) AS Pct_R,
      COUNT(*) AS Calls,
      SUM(DURATION)/COUNT(*) AS "R/Ca11"
  FROM INFORMATION_SCHEMA.PROFILING
    WHERE QUERY_ID = @query_id
    GROUP BY STATE
    ORDER BY Total_R DESC;
  EOF;
          $res = \Drupal::database()->query($query)->fetchAll();
          foreach ($res as $sub_item) {
            $sub_item = (array)$sub_item;
            $strings .= <<<EOF
  STATE:{$sub_item["STATE"]}, Total_R:{$sub_item["Total_R"]}, Pct_R:{$sub_item["Pct_R"]}, Calls:{$sub_item["Calls"]}, R/Ca11:{$sub_item['R/Ca11']}
  EOF;
            $strings .= "\r\n";
          }
        }
        $strings .= "\r\n\r\n";
      }
      \Drupal::logger('debug_sql')->notice("<pre>{$strings}</pre>");
    }
  }
  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    return [
      KernelEvents::REQUEST => ['onKernelRequest'],
      KernelEvents::RESPONSE => ['onResponse']
    ];
  }
}

标签: Drupal mysql