o11y-8.x-1.x-dev/modules/o11y_metrics/src/Prometheus/Storage/DrupalCache.php

modules/o11y_metrics/src/Prometheus/Storage/DrupalCache.php
<?php

namespace Drupal\o11y_metrics\Prometheus\Storage;

use Drupal\pcb\Cache\PermanentDatabaseBackend;
use Drupal\pcb_memcache\Cache\PermanentMemcacheBackend;
use Drupal\pcb_redis\Cache\PermanentRedisBackend;
use Drupal\o11y_metrics\Prometheus\RelatesSourceToMetricsInterface;
use Drupal\o11y_metrics\BaseMetricsSourceInterface;
use Drupal\webprofiler\Cache\CacheBackendWrapper;
use Prometheus\Collector;
use Prometheus\Storage\InMemory;
use Drupal\Core\Installer\InstallerKernel;

/**
 * Alternative promphp storage class based on drupal cache.
 */
class DrupalCache extends InMemory implements RelatesSourceToMetricsInterface {

  /**
   * The underlying cache backend.
   *
   * @var \Drupal\pcb\Cache\PermanentDatabaseBackend|\Drupal\pcb_memcache\Cache\PermanentMemcacheBackend|\Drupal\pcb_redis\Cache\PermanentRedisBackend
   */
  protected $cacheBackend;

  /**
   * Constructor.
   */
  public function __construct($cacheBackend) {
    if ($cacheBackend instanceof CacheBackendWrapper) {
      $cacheBackend = $cacheBackend->getWrapped();
    }

    $backendIsPermanent = ($cacheBackend instanceof PermanentDatabaseBackend)
      || ($cacheBackend instanceof PermanentMemcacheBackend)
      || ($cacheBackend instanceof PermanentRedisBackend);
    if (!$backendIsPermanent && !InstallerKernel::installationAttempted()) {
      throw new \RuntimeException(<<<EOD
Please configure the drupal prometheusio_bin cache bin to use either
- cache.backend.permanent_database
- cache.backend.permanent_redis
- cache.backend.permanent_memcache
EOD);
    }
    $this->cacheBackend = $cacheBackend;
  }

  /**
   * {@inheritdoc}
   */
  public function collect(): array {
    foreach (['counters', 'gauges', 'histograms'] as $type) {
      $this->{$type} = $this->cacheBackend->get('metrics:' . $type)->data ?? [];
    }
    return parent::collect();
  }

  /**
   * {@inheritdoc}
   */
  public function updateHistogram(array $data): void {
    $this->commonUpdateMetric('histograms', __FUNCTION__, $data);
  }

  /**
   * {@inheritdoc}
   */
  public function updateGauge(array $data): void {
    $this->commonUpdateMetric('gauges', __FUNCTION__, $data);
  }

  /**
   * {@inheritdoc}
   */
  public function updateCounter(array $data): void {
    $this->commonUpdateMetric('counters', __FUNCTION__, $data);
  }

  /**
   * Common metrics function.
   */
  protected function commonUpdateMetric(string $classFieldName, string $method, array $data) {
    $this->{$classFieldName} = $this->cacheBackend->get('metrics:' . $classFieldName)->data ?? [];
    parent::$method($data);
    $this->cacheBackend->set('metrics:' . $classFieldName, $this->{$classFieldName});
  }

  /**
   * {@inheritdoc}
   */
  public function wipeStorage(): void {
    $this->cacheBackend->deleteAllPermanent();
    parent::wipeStorage();
  }

  /**
   * {@inheritdoc}
   */
  public function associateSourceToMetric(
    BaseMetricsSourceInterface $metricsSource,
    Collector $metric
  ) {
    $metrictype = $metric->getType();
    $metricname = $metric->getName();
    $metricsSourceId = $metricsSource::getMetricsSourceId();
    $cid_association = 'source_metrics_associations:' . $metricsSourceId;
    $associations = $this->cacheBackend->get($cid_association)->data ?? [];
    $mappingMetricTypeClassField = [
      'counter' => 'counters',
      'histogram' => 'histograms',
      'gauge' => 'gauges',
    ];
    $metakey = $this->metaKey(['type' => $metrictype, 'name' => $metricname]);
    $associations[$mappingMetricTypeClassField[$metrictype]][$metakey] = TRUE;
    $this->cacheBackend->set($cid_association, $associations);
  }

  /**
   * {@inheritdoc}
   */
  public function removeMetricsOfSource(string $metricsSourceId) {
    $cid_association = 'source_metrics_associations:' . $metricsSourceId;
    $associations = $this->cacheBackend->get($cid_association)->data ?? [];
    $classFieldNames = array_keys($associations);
    foreach ($classFieldNames as $classFieldName) {
      $cid = 'metrics:' . $classFieldName;
      $cached = $this->cacheBackend->get($cid)->data ?? [];
      foreach (array_keys($associations[$classFieldName]) as $metakey) {
        unset($cached[$metakey]);
      }
      $this->cacheBackend->set($cid, $cached);
    }
    $this->cacheBackend->delete($cid_association);
  }

  /**
   * {@inheritdoc}
   */
  public function hasMetricsOfSource(string $metricsSourceId) {
    $cid_association = 'source_metrics_associations:' . $metricsSourceId;
    $associations = $this->cacheBackend->get($cid_association)->data ?? [];
    return !empty($associations);
  }

}

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

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