o11y-8.x-1.x-dev/modules/o11y_metrics/modules/o11y_metrics_requests/src/EventSubscriber/RequestCollector.php

modules/o11y_metrics/modules/o11y_metrics_requests/src/EventSubscriber/RequestCollector.php
<?php

namespace Drupal\o11y_metrics_requests\EventSubscriber;

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

/**
 * Gathers prometheus http metrics on kernel request+terminate.
 */
class RequestCollector implements EventSubscriberInterface, BaseMetricsSourceInterface {

  const TIMER_NAME = 'prometheus_metrics_request_timer';
  const CONFIG_NAME = 'o11y_metrics_requests.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 requests 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::REQUEST => ['startPrometheusMetricsTimer', 1000],
      KernelEvents::TERMINATE => ['collectPrometheusMetricsTimer', 0],
    ];
  }

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

  /**
   * Event callback.
   *
   * Starts the request timer.
   *
   * @SuppressWarnings(PHPMD.UnusedFormalParameter)
   */
  public function startPrometheusMetricsTimer(RequestEvent $event) {
    Timer::start(self::TIMER_NAME);
  }

  /**
   * Event callback.
   *
   * Stops the request timer and collect events.
   */
  public function collectPrometheusMetricsTimer(TerminateEvent $event) {
    if ($this->routeMatch->getRouteName() == 'o11y_metrics.metrics') {
      return;
    }

    $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;
    }


    Timer::stop(self::TIMER_NAME);
    $timeInMs = Timer::read(self::TIMER_NAME);
    $timeInS = $timeInMs / 1000;
    $request = $event->getRequest();
    $method = $request->getMethod();
    $this->promBridge->getCounter(
      'drupal',
      'http_requests_total',
      'Total number of requests.',
      [],
      $this
    )->inc();

    $httpCode = (((string) $event->getResponse()->getStatusCode())[0] ?? 'x') . 'xx';
    $buckets = $this->config->get('buckets');
    $this->promBridge->getHistogram(
      'drupal',
      'http_requests',
      'Timing metrics for requests.',
      [
        'method',
        'route',
        'status',
      ],
      empty($buckets) ? NULL : $buckets,
      $this
    )
      ->observe($timeInS, [$method, $routeName, $httpCode]);
  }

}

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

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