o11y-8.x-1.x-dev/modules/o11y_metrics/modules/o11y_metrics_database/src/EventSubscriber/DatabaseCollector.php

modules/o11y_metrics/modules/o11y_metrics_database/src/EventSubscriber/DatabaseCollector.php
<?php

namespace Drupal\o11y_metrics_database\EventSubscriber;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\o11y_metrics\BaseMetricsSourceInterface;
use Drupal\o11y_metrics\Bridge\PrometheusBridgeInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\TerminateEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Gather db metrics on request end.
 */
class DatabaseCollector implements EventSubscriberInterface, BaseMetricsSourceInterface {

  const CONFIG_NAME = 'o11y_metrics_database.settings';

  /**
   * The promphp bridge.
   *
   * @var \Drupal\o11y_metrics\Bridge\PrometheusBridgeInterface
   */
  protected $promBridge;

  /**
   * The current_route_match service.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * The prometheusio database config object.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $config;

  /**
   * {@inheritdoc}
   */
  public function __construct(
    PrometheusBridgeInterface $promBridge,
    RouteMatchInterface $routeMatch,
    ConfigFactoryInterface $config
  ) {
    $this->promBridge = $promBridge;
    $this->routeMatch = $routeMatch;
    $this->config = $config->get(static::CONFIG_NAME);
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      KernelEvents::TERMINATE => ['collectPrometheusMetricsDatabase', 0],
    ];
  }

  /**
   * {@inheritDoc}
   */
  public static function getMetricsSourceId(): string {
    return 'database';
  }

  /**
   * Event callback.
   *
   * Gather the db logs on request end.
   *
   * @SuppressWarnings(PHPMD.UnusedFormalParameter)
   */
  public function collectPrometheusMetricsDatabase(TerminateEvent $event) {
    $routeName = str_replace('.', '_', $this->routeMatch->getRouteName());
    $routeObject = $this->routeMatch->getRouteObject();
    if (empty($routeName) || !$routeObject) {
      return;
    }
    $isAdminRoute = $routeObject->getOptions()['_admin_route'] ?? FALSE;
    if ($isAdminRoute && ($this->config->get('exclude_admin_paths'))) {
      return;
    }

    $buckets = $this->config->get('buckets');
    foreach (array_keys(Database::getAllConnectionInfo()) as $database_key) {
      $database = Database::getConnection('default', $database_key);

      if (!$database->getLogger()) {
        continue;
      }
      $queries = $database->getLogger()->get('o11y_metrics');
      $totalTimeInMs = $this->getTotalTimeInMs($queries);
      $this->promBridge->getHistogram(
        'drupal',
        'database_time',
        'Timing metrics for database.',
        [
          'database',
          'route',
        ],
        empty($buckets) ? NULL : $buckets,
        $this
      )
        ->observe($totalTimeInMs, [$database_key, $routeName]);
    }
  }

  /**
   * Get total time in ms of the select queries.
   *
   * @return int|float
   *   The total time of the select queries.
   */
  protected function getTotalTimeInMs(array $queries) {
    $totalTimeInMs = 0;
    foreach ($queries as $query) {
      // Consider only SELECTs.
      if (strpos($query['query'], 'SELECT') === FALSE) {
        continue;
      }
      // Queries have microsecond precision.
      $totalTimeInMs = $query['time'] * 1000;
    }
    return $totalTimeInMs;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc