Skip to content
Prev Previous commit
Next Next commit
Enhance CacheMetricsDecorator to use PrometheusMetricInterface
  • Loading branch information
caleeli committed Jan 17, 2025
commit e26890ec8c9f7e91c4e50e099312e81837991716
22 changes: 19 additions & 3 deletions ProcessMaker/Cache/Monitoring/CacheMetricsDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use ProcessMaker\Cache\CacheInterface;
use ProcessMaker\Cache\Monitoring\CacheMetricsInterface;
use ProcessMaker\Contracts\PrometheusMetricInterface;

/**
* Decorator class that adds metrics tracking about cache operations
Expand Down Expand Up @@ -64,11 +65,18 @@ public function get(string $key, mixed $default = null): mixed
$endTime = microtime(true);
$duration = $endTime - $startTime;

// Get extra labels for metrics
$labels = [];
if ($value instanceof PrometheusMetricInterface) {
$labels['label'] = $value->getPrometheusMetricLabel();
} else {
$labels['label'] = $key;
}
// Record metrics based on key existence, not value comparison
if ($exists) {
$this->metrics->recordHit($key, $duration);
$this->metrics->recordHit($key, $duration, $labels);
} else {
$this->metrics->recordMiss($key, $duration);
$this->metrics->recordMiss($key, $duration, $labels);
}

return $value;
Expand All @@ -88,10 +96,18 @@ public function set(string $key, mixed $value, null|int|\DateInterval $ttl = nul
{
$result = $this->cache->set($key, $value, $ttl);

// Get extra labels for metrics
$labels = [];
if ($value instanceof PrometheusMetricInterface) {
$labels['label'] = $value->getPrometheusMetricLabel();
} else {
$labels['label'] = $key;
}

if ($result) {
// Calculate approximate size in bytes
$size = $this->calculateSize($value);
$this->metrics->recordWrite($key, $size);
$this->metrics->recordWrite($key, $size, $labels);
}

return $result;
Expand Down
7 changes: 4 additions & 3 deletions ProcessMaker/Cache/Monitoring/CacheMetricsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,23 @@ interface CacheMetricsInterface
*
* @param string $key Cache key that was accessed
* @param float $microtime Time taken for the operation in microseconds
* @param array $labels Additional labels to attach to the metric
*/
public function recordHit(string $key, $microtime): void;
public function recordHit(string $key, $microtime, array $labels = []): void;

/**
* Record a cache miss event
*
* @param string $key Cache key that was accessed
* @param float $microtime Time taken for the operation in microseconds
*/
public function recordMiss(string $key, $microtime): void;
public function recordMiss(string $key, $microtime, array $labels = []): void;

/**
* Record a cache write operation
*
* @param string $key Cache key that was written
* @param int $size Size of the cached data in bytes
*/
public function recordWrite(string $key, int $size): void;
public function recordWrite(string $key, int $size, array $labels = []): void;
}
29 changes: 16 additions & 13 deletions ProcessMaker/Cache/Monitoring/PrometheusMetricsManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,22 @@ public function __construct(string $namespace = 'cache')
* @param string $key Cache key
* @param float $microtime Time taken in microseconds
*/
public function recordHit(string $key, $microtime): void
public function recordHit(string $key, $microtime, array $labels = []): void
{
$sanitizedKey = $this->sanitizeKey($key);
$labelKeys = array_keys($labels);

$this->metrics->counter(
'cache_hits_total',
'Total number of cache hits',
['cache_key']
)->inc(['cache_key' => $sanitizedKey]);
['cache_key', ...$labelKeys]
)->inc(['cache_key' => $sanitizedKey, ...$labels]);
// record the last write timestamp
$this->metrics->gauge(
'cache_last_write_timestamp',
'Last write timestamp',
['cache_key']
)->set($microtime, ['cache_key' => $sanitizedKey]);
['cache_key', ...$labelKeys]
)->set($microtime, ['cache_key' => $sanitizedKey, ...$labels]);
}

/**
Expand All @@ -58,22 +59,23 @@ public function recordHit(string $key, $microtime): void
* @param string $key Cache key
* @param float $microtime Time taken in microseconds
*/
public function recordMiss(string $key, $microtime): void
public function recordMiss(string $key, $microtime, array $labels = []): void
{
$sanitizedKey = $this->sanitizeKey($key);
$labelKeys = array_keys($labels);

$this->metrics->counter(
'cache_misses_total',
'Total number of cache misses',
['cache_key']
)->inc(['cache_key' => $sanitizedKey]);
['cache_key', ...$labelKeys]
)->inc(['cache_key' => $sanitizedKey, ...$labels]);

// record the last write timestamp
$this->metrics->gauge(
'cache_last_write_timestamp',
'Last write timestamp',
['cache_key']
)->set($microtime, ['cache_key' => $sanitizedKey]);
['cache_key', ...$labelKeys]
)->set($microtime, ['cache_key' => $sanitizedKey, ...$labels]);
}

/**
Expand All @@ -82,15 +84,16 @@ public function recordMiss(string $key, $microtime): void
* @param string $key Cache key
* @param int $size Size in bytes
*/
public function recordWrite(string $key, int $size): void
public function recordWrite(string $key, int $size, array $labels = []): void
{
$sanitizedKey = $this->sanitizeKey($key);
$labelKeys = array_keys($labels);

$this->metrics->gauge(
'cache_memory_bytes',
'Memory usage in bytes',
['cache_key']
)->set($size, ['cache_key' => $sanitizedKey]);
['cache_key', ...$labelKeys]
)->set($size, ['cache_key' => $sanitizedKey, ...$labels]);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions ProcessMaker/Cache/Monitoring/RedisMetricsManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class RedisMetricsManager implements CacheMetricsInterface
* @param string $key Cache key
* @param float $microtime Time taken in microseconds
*/
public function recordHit(string $key, $microtime): void
public function recordHit(string $key, $microtime, array $labels = []): void
{
$baseKey = self::METRICS_PREFIX . $key;
Redis::pipeline(function ($pipe) use ($baseKey, $microtime) {
Expand All @@ -42,7 +42,7 @@ public function recordHit(string $key, $microtime): void
* @param string $key Cache key
* @param float $microtime Time taken in microseconds
*/
public function recordMiss(string $key, $microtime): void
public function recordMiss(string $key, $microtime, array $labels = []): void
{
$baseKey = self::METRICS_PREFIX . $key;
Redis::pipeline(function ($pipe) use ($baseKey, $microtime) {
Expand All @@ -58,7 +58,7 @@ public function recordMiss(string $key, $microtime): void
* @param string $key Cache key
* @param int $size Size in bytes
*/
public function recordWrite(string $key, int $size): void
public function recordWrite(string $key, int $size, array $labels = []): void
{
$baseKey = self::METRICS_PREFIX . $key;
Redis::pipeline(function ($pipe) use ($baseKey, $size) {
Expand Down