prometheusio_exporter-8.x-1.x-dev/src/Prometheus/Storage/DrupalCache.php
src/Prometheus/Storage/DrupalCache.php
<?php
namespace Drupal\prometheusio_exporter\Prometheus\Storage;
use Drupal\pcb\Cache\PermanentBackendInterface;
use Drupal\prometheusio_exporter\Prometheus\RelatesSourceToMetricsInterface;
use Drupal\prometheusio_exporter\BaseMetricsSourceInterface;
use Prometheus\Collector;
use Prometheus\Storage\InMemory;
use Drupal\Core\Installer\InstallerKernel;
use Drupal\Core\Update\UpdateBackend;
/**
* 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)
{
$backendIsPermanent = ($cacheBackend instanceof PermanentBackendInterface);
if (!$backendIsPermanent && !InstallerKernel::installationAttempted() && !$cacheBackend instanceof UpdateBackend) {
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(bool $sortMetrics = true): array
{
foreach (['counters', 'gauges', 'histograms'] as $type) {
$this->{$type} = $this->cacheBackend->get('metrics:' . $type)->data ?? [];
}
return parent::collect($sortMetrics);
}
/**
* {@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);
}
}
