cache_monitor-1.0.x-dev/src/Metrics/Aggregator.php

src/Metrics/Aggregator.php
<?php

namespace Drupal\cache_monitor\Metrics;

use ArrayObject;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Aggregates cache operation metrics during a request.
 *
 * Each operation is recorded with:
 * - bin: The cache bin name.
 * - op: The operation name (e.g. get, set, delete).
 * - calls: Number of calls made.
 * - items: Number of items affected (e.g. for getMulti/setMulti).
 * - ms: Total time spent in milliseconds.
 *
 * Metrics are stored in the current HTTP request attributes, or in a fallback
 * bucket for non-HTTP (CLI) requests.
 */
final class Aggregator {

  /**
   * Request attribute key for storing metrics.
   */
  private const ATTR = '_cache_monitor_metrics';


  /**
   * Fallback bucket for non-HTTP (CLI) requests.
   * @var \ArrayObject
   */
  private ArrayObject $cliBucket;

  /**
   * The request stack to access the current request.
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  private RequestStack $stack;

  /**
   * Constructs a new Aggregator instance.
   *
   * @param \Symfony\Component\HttpFoundation\RequestStack $stack
   *   The request stack service.
   */
  public function __construct(RequestStack $stack) {
    $this->stack = $stack;
    $this->cliBucket = new ArrayObject();
  }

  /**
   * Gets the current metrics bucket.
   *
   * Uses the current HTTP request attributes if available, otherwise falls
   * back to a CLI bucket.
   *
   * @return \ArrayObject
   *   The metrics bucket.
   */
  private function bucket(): ArrayObject {
    $req = $this->stack->getCurrentRequest();
    if (!$req) {
      return $this->cliBucket;
    }
    $bag = $req->attributes->get(self::ATTR);
    if (!$bag instanceof ArrayObject) {
      $bag = new ArrayObject();
      $req->attributes->set(self::ATTR, $bag);
    }
    return $bag;
  }

  /**
   * Adds a cache operation metric.
   *
   * @param string $bin
   *   The cache bin name.
   * @param string $op
   *   The operation name (e.g. get, set, delete).
   * @param int $count
   *   The number of items affected (e.g. for getMulti/setMulti).
   * @param float $ms
   *   The time taken in milliseconds.
   */
  public function add(string $bin, string $backend, string $op, int $count, float $ms): void {
    $b = $this->bucket();
    $key = "$bin|$op";
    if (!isset($b[$key])) {
      $b[$key] = ['bin' => $bin, 'backend' => $backend, 'op' => $op, 'calls' => 0, 'items' => 0, 'ms' => 0.0];
    }
    $row = $b[$key];
    $row['calls'] += 1;
    $row['items'] += max(0, $count);
    $row['ms']    += $ms;
    $b[$key] = $row; // re-set
  }

  /**
   * Drains and returns all collected metrics, resetting the bucket.
   *
   * @return array<int,array{bin:string,op:string,calls:int,items:int,ms:float}>
   */
  public function drain(): array {
    $b = $this->bucket();
    $out = array_values((array) $b);
    $b->exchangeArray([]);
    return $out;
  }

  /**
   * Checks if there are any collected metrics.
   *
   * @return bool
   *   TRUE if no metrics have been collected, FALSE otherwise.
   */
  public function isEmpty(): bool {
    return count((array) $this->bucket()) === 0;
  }
}

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

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