monitoring-8.x-1.x-dev/modules/prometheus/src/Controller/MetricsController.php

modules/prometheus/src/Controller/MetricsController.php
<?php

namespace Drupal\monitoring_prometheus\Controller;

use Drupal\Core\Access\AccessResultAllowed;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Utility\Token;
use Drupal\monitoring\SensorRunner;
use PNX\Prometheus\Gauge;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\SerializerInterface;

/**
 * A controller for exporting prometheus metrics.
 */
class MetricsController extends ControllerBase {

  /**
   * MetricsController constructor.
   */
  public function __construct(
    protected SerializerInterface $serializer,
    protected SensorRunner $sensorRunner,
    protected Token $token) {
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('monitoring_prometheus.serializer'),
      $container->get('monitoring.sensor_runner'),
      $container->get('token')
    );
  }

  /**
   * Handles metrics requests.
   */
  public function metrics() {

    if (!class_exists(Gauge::class)) {
      throw new \Exception('Required dependency not found, run composer require previousnext/php-prometheus.');
    }

    $default_labels = [];
    $labels_config = $this->config('monitoring_prometheus.settings')->get('custom_labels') ?? [];
    foreach ($labels_config as $label_name => $label_value) {
      $default_labels[$label_name] = $this->token->replace($label_value);
    }

    $results = $this->sensorRunner->runSensors();
    $output = [];

    $count_by_status = [];

    foreach ($results as $result) {
      $sensor_config = $result->getSensorConfig();

      $count_by_status[$result->getStatus()] = ($count_by_status[$result->getStatus()] ?? 0) + 1;

      $metric_type = $sensor_config->getPlugin()->getPluginDefinition()['metric_type'] ?? NULL;
      if ($metric_type != 'gauge') {
        continue;
      }
      $value_label = mb_strtolower($result->getSensorConfig()->getValueLabel() ?? 'No label');
      $value_label = preg_replace('/[^a-z]+/', '', $value_label) ?: 'total';

      $gauge = new Gauge('drupal_' . $result->getSensorId(), $value_label, $result->getSensorConfig()->label());
      $gauge->set($result->getValue() ?: 0, $default_labels);

      $output[] = $this->serializer->serialize($gauge, 'prometheus');

      if (!empty($sensor_config->getPlugin()->getPluginDefinition()['report_execution_time'])) {
        $gauge = new Gauge('drupal_' . $result->getSensorId(), 'execution_time_seconds', $result->getSensorConfig()->label());
        $gauge->set($result->getExecutionTime() / 1000, $default_labels);
        $output[] = $this->serializer->serialize($gauge, 'prometheus');
      }
    }

    $gauge = new Gauge('drupal_sensors', 'total' , $this->t('Sensor count by status'));
    $gauge->set(array_sum($count_by_status), $default_labels);
    foreach ($count_by_status as $status => $count) {
      $gauge->set($count, array_merge($default_labels, ['status' => $status]));
    }

    $output[] = $this->serializer->serialize($gauge, 'prometheus');

    $response = new Response();
    $response->setMaxAge(0);
    $response->headers->set('Content-Type', 'text/plain; version=0.0.4');
    $response->setContent(implode($output));
    return $response;
  }

  /**
   * Custom IP access check.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   If there is a list of allowed ips, check request client against it.
   */
  public function ipAccess(Request $request): AccessResultInterface {
    $allowed_ips = array_filter($this->config('monitoring_prometheus.settings')->get('allowed_ips'));
    return AccessResultAllowed::allowedIf(empty($allowed_ips) || in_array($request->getClientIp(), $allowed_ips));
  }

}

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

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