o11y-8.x-1.x-dev/modules/o11y_metrics/src/EventSubscriber/RemoveMetricsOnBucketsChange.php
modules/o11y_metrics/src/EventSubscriber/RemoveMetricsOnBucketsChange.php
<?php
namespace Drupal\o11y_metrics\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\o11y_metrics\Bridge\PrometheusBridgeInterface;
use Drupal\Core\Config\ConfigEvents;
use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\StorageTransformEvent;
/**
* Reacts on config save.
*
* This event subscriber reacts on config save, and if the buckets have
* changed, it cleans the data of the collector class.
* Site wise, wipe_client_storage_on_drush_config_import can be set to 0 but if
* we are importing a config that changes buckets then we have to make sure
* that the local storage is cleaned otherwise the new buckets do not get
* regitered by the library.
*/
class RemoveMetricsOnBucketsChange implements EventSubscriberInterface {
/**
* The promphp bridge.
*
* @var \Drupal\o11y_metrics\Bridge\PrometheusBridgeInterface
*/
protected $promBridge;
/**
* The metrics source class name.
*
* @var string
*/
protected $metricsSourceClassName;
/**
* Buckets detected before config import.
*
* @var array
*/
protected $bucketsBeforeOnConfigImport;
/**
* Constructor.
*/
public function __construct(
PrometheusBridgeInterface $promBridge,
ConfigFactoryInterface $config,
string $metricsSourceClassName
) {
$this->promBridge = $promBridge;
$this->metricsSourceClassName = $metricsSourceClassName;
$this->bucketsBeforeOnConfigImport = $config->get($metricsSourceClassName::CONFIG_NAME)->getOriginal('buckets');
}
/**
* Callback for ConfigEvents::SAVE event.
*
* Called during both config import and config form submit.
* Removes metrics if a specific configuration has changed.
*
* @param \Drupal\Core\Config\ConfigCrudEvent $event
* The Event to process.
*/
public function removeMetricsOfSourceIfBucketsHaveChanged(ConfigCrudEvent $event) {
$config = $event->getConfig();
if ($config->getName() !== $this->metricsSourceClassName::CONFIG_NAME) {
return;
}
// During config import getOriginal returns NULL, so we use the field.
// We still need to give priority to getOriginal because during config form
// submit the actual original data is found on the config object obtained
// from the $event (this callback param) and not from the config.factory
// (from the constructor) which contains the already changed value.
$bucketsBefore = $config->getOriginal('buckets') ?? $this->bucketsBeforeOnConfigImport;
$bucketsNow = $config->get('buckets');
if ($bucketsBefore != $bucketsNow) {
$this->promBridge->removeMetricsOfSource($this->metricsSourceClassName);
}
}
/**
* Callback for STORAGE_TRANSFORM_IMPORT event.
*
* Not called when the config changes by submitting the config form.
* Called only during config import.
* This handler, while empty, needs to exist in order to have drupal
* instanciate this service early in the config import process and have the
* right value assigned to $this->bucketsBeforeOnConfigImport in the
* constructor.
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function onStorageTransforImport(StorageTransformEvent $e) {
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[ConfigEvents::SAVE][] = ['removeMetricsOfSourceIfBucketsHaveChanged'];
$events[ConfigEvents::STORAGE_TRANSFORM_IMPORT][] = ['onStorageTransforImport'];
return $events;
}
}
