Skip to content

Commit

Permalink
Implemented remove method for metric
Browse files Browse the repository at this point in the history
  • Loading branch information
luzrain committed Nov 14, 2024
1 parent 02ac176 commit 98b142b
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 30 deletions.
2 changes: 2 additions & 0 deletions src/BundledPlugin/Metrics/Counter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

final class Counter extends Metric
{
protected const TYPE = 'counter';

private array $buffer = [];

/**
Expand Down
2 changes: 2 additions & 0 deletions src/BundledPlugin/Metrics/Gauge.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

final class Gauge extends Metric
{
protected const TYPE = 'gauge';

private array $buffer = [];

/**
Expand Down
2 changes: 2 additions & 0 deletions src/BundledPlugin/Metrics/Histogram.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

final class Histogram extends Metric
{
protected const TYPE = 'histogram';

private array $buffer = [];

/**
Expand Down
32 changes: 32 additions & 0 deletions src/BundledPlugin/Metrics/Internal/InMemory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal;

use Prometheus\Storage\InMemory as PrometheusInMemory;

final class InMemory extends PrometheusInMemory
{
public function remove(string $type, string $namespace, string $name, array $labels): void
{
$data = [
'type' => $type,
'name' => $namespace . '_' . $name,
'labelValues' => $labels,
];

$metaKey = $this->metaKey($data);
$valueKey = $this->valueKey($data);

if ($type === 'counter') {
unset($this->counters[$metaKey]['samples'][$valueKey]);
} elseif($type === 'gauge') {
unset($this->gauges[$metaKey]['samples'][$valueKey]);
} elseif($type === 'histogram') {
unset($this->histograms[$metaKey]['samples'][$valueKey]);
} elseif($type === 'summary') {
unset($this->summaries[$metaKey]['samples'][$valueKey]);
}
}
}
13 changes: 4 additions & 9 deletions src/BundledPlugin/Metrics/Internal/Message/GetMetricMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
*/
final readonly class GetMetricMessage implements MessageInterface
{
public const TYPE_COUNTER = 'counter';
public const TYPE_GAUGE = 'gauge';
public const TYPE_HISTOGRAM = 'histogram';
public const TYPE_SUMMARY = 'summary';

private function __construct(
public string $type,
public string $namespace,
Expand All @@ -25,21 +20,21 @@ private function __construct(

public static function counter(string $namespace, string $name): self
{
return new self(self::TYPE_COUNTER, $namespace, $name);
return new self('counter', $namespace, $name);
}

public static function gauge(string $namespace, string $name): self
{
return new self(self::TYPE_GAUGE, $namespace, $name);
return new self('gauge', $namespace, $name);
}

public static function histogram(string $namespace, string $name): self
{
return new self(self::TYPE_HISTOGRAM, $namespace, $name);
return new self('histogram', $namespace, $name);
}

public static function summary(string $namespace, string $name): self
{
return new self(self::TYPE_SUMMARY, $namespace, $name);
return new self('summary', $namespace, $name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
*/
final readonly class RegisterMetricMessage implements MessageInterface
{
public const TYPE_COUNTER = 'counter';
public const TYPE_GAUGE = 'gauge';
public const TYPE_HISTOGRAM = 'histogram';
public const TYPE_SUMMARY = 'summary';

private function __construct(
public string $type,
public string $namespace,
Expand All @@ -28,21 +23,21 @@ private function __construct(

public static function counter(string $namespace, string $name, string $help, array $labels): self
{
return new self(self::TYPE_COUNTER, $namespace, $name, $help, $labels);
return new self('counter', $namespace, $name, $help, $labels);
}

public static function gauge(string $namespace, string $name, string $help, array $labels): self
{
return new self(self::TYPE_GAUGE, $namespace, $name, $help, $labels);
return new self('gauge', $namespace, $name, $help, $labels);
}

public static function histogram(string $namespace, string $name, string $help, array $labels, array $buckets): self
{
return new self(self::TYPE_HISTOGRAM, $namespace, $name, $help, $labels, $buckets);
return new self('histogram', $namespace, $name, $help, $labels, $buckets);
}

public static function summary(string $namespace, string $name, string $help, array $labels, array|null $buckets = null): self
{
return new self(self::TYPE_SUMMARY, $namespace, $name, $help, $labels, $buckets);
return new self('summary', $namespace, $name, $help, $labels, $buckets);
}
}
21 changes: 21 additions & 0 deletions src/BundledPlugin/Metrics/Internal/Message/RemoveMetricMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal\Message;

use Luzrain\PHPStreamServer\MessageBus\MessageInterface;

/**
* @implements MessageInterface<null>
*/
final readonly class RemoveMetricMessage implements MessageInterface
{
public function __construct(
public string $type,
public string $namespace,
public string $name,
public array $labels,
) {
}
}
47 changes: 35 additions & 12 deletions src/BundledPlugin/Metrics/Internal/MessageBusRegistryHandler.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal;

use Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal\Message\GetMetricMessage;
Expand All @@ -8,46 +10,49 @@
use Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal\Message\ObserveHistorgamMessage;
use Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal\Message\ObserveSummaryMessage;
use Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal\Message\RegisterMetricMessage;
use Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal\Message\RemoveMetricMessage;
use Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal\Message\SetGaugeMessage;
use Luzrain\PHPStreamServer\MessageBus\MessageHandlerInterface;
use Prometheus\CollectorRegistry;
use Prometheus\Exception\MetricNotFoundException as PrometheusMetricNotFoundException;
use Prometheus\Exception\MetricsRegistrationException as PrometheusMetricRegistrationException;
use Prometheus\RegistryInterface as PrometheusRegistryInterface;
use Prometheus\RenderTextFormat;
use Prometheus\Storage\InMemory;
use function Amp\weakClosure;

final class MessageBusRegistryHandler
{
private InMemory $adapter;
private PrometheusRegistryInterface $registry;

public function __construct(MessageHandlerInterface $messageHandler)
{
$this->registry = new CollectorRegistry(new InMemory(), false);
$this->adapter = new InMemory();
$this->registry = new CollectorRegistry($this->adapter, false);

$messageHandler->subscribe(RegisterMetricMessage::class, weakClosure($this->registerMetric(...)));
$messageHandler->subscribe(GetMetricMessage::class, weakClosure($this->getMetric(...)));
$messageHandler->subscribe(IncreaseCounterMessage::class, weakClosure($this->increaseCounter(...)));
$messageHandler->subscribe(SetGaugeMessage::class, weakClosure($this->setGauge(...)));
$messageHandler->subscribe(ObserveHistorgamMessage::class, weakClosure($this->observeHistogram(...)));
$messageHandler->subscribe(ObserveSummaryMessage::class, weakClosure($this->observeSummary(...)));
$messageHandler->subscribe(RemoveMetricMessage::class, weakClosure($this->removeMetric(...)));
}

private function registerMetric(RegisterMetricMessage $message): bool
{
try {
match ($message->type) {
RegisterMetricMessage::TYPE_COUNTER => $this->registry->registerCounter(
'counter' => $this->registry->registerCounter(
$message->namespace, $message->name, $message->help, $message->labels,
),
RegisterMetricMessage::TYPE_GAUGE => $this->registry->registerGauge(
'gauge' => $this->registry->registerGauge(
$message->namespace, $message->name, $message->help, $message->labels,
),
RegisterMetricMessage::TYPE_HISTOGRAM => $this->registry->registerHistogram(
'histogram' => $this->registry->registerHistogram(
$message->namespace, $message->name, $message->help, $message->labels, $message->buckets,
),
RegisterMetricMessage::TYPE_SUMMARY => $this->registry->registerSummary(
'summary' => $this->registry->registerSummary(
$message->namespace, $message->name, $message->help, $message->labels, 600, $message->buckets,
),
};
Expand All @@ -61,17 +66,35 @@ private function registerMetric(RegisterMetricMessage $message): bool
private function getMetric(GetMetricMessage $message): GetMetricResponse|false
{
try {
$counter = match ($message->type) {
GetMetricMessage::TYPE_COUNTER => $this->registry->getCounter($message->namespace, $message->name),
GetMetricMessage::TYPE_GAUGE => $this->registry->getGauge($message->namespace, $message->name),
GetMetricMessage::TYPE_HISTOGRAM => $this->registry->getHistogram($message->namespace, $message->name),
GetMetricMessage::TYPE_SUMMARY => $this->registry->getSummary($message->namespace, $message->name),
$metric = match ($message->type) {
'counter' => $this->registry->getCounter($message->namespace, $message->name),
'gauge' => $this->registry->getGauge($message->namespace, $message->name),
'histogram' => $this->registry->getHistogram($message->namespace, $message->name),
'summary' => $this->registry->getSummary($message->namespace, $message->name),
};
} catch (PrometheusMetricNotFoundException) {
return false;
}

return new GetMetricResponse($message->type, $message->namespace, $message->name, $counter->getHelp(), $counter->getLabelNames());
return new GetMetricResponse($message->type, $message->namespace, $message->name, $metric->getHelp(), $metric->getLabelNames());
}

private function removeMetric(RemoveMetricMessage $message): void
{
try {
$metric = match ($message->type) {
'counter' => $this->registry->getCounter($message->namespace, $message->name),
'gauge' => $this->registry->getGauge($message->namespace, $message->name),
'histogram' => $this->registry->getHistogram($message->namespace, $message->name),
'summary' => $this->registry->getSummary($message->namespace, $message->name),
};
} catch (PrometheusMetricNotFoundException) {
return;
}

$labels = [...\array_flip($metric->getLabelNames()), ...$message->labels];

$this->adapter->remove($message->type, $message->namespace, $message->name, $labels);
}

private function increaseCounter(IncreaseCounterMessage $message): void
Expand Down
8 changes: 8 additions & 0 deletions src/BundledPlugin/Metrics/Internal/Metric.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
namespace Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal;

use Luzrain\PHPStreamServer\BundledPlugin\Metrics\Exception\LabelsNotMatchException;
use Luzrain\PHPStreamServer\BundledPlugin\Metrics\Internal\Message\RemoveMetricMessage;
use Luzrain\PHPStreamServer\MessageBus\MessageBusInterface;

abstract class Metric
{
protected const TYPE = '';
protected const FLUSH_TIMEOUT = 0.2;

private int $labelsCount;
Expand All @@ -23,6 +25,12 @@ public function __construct(
$this->labelsCount = \count($this->labels);
}

public function remove(array $labels = []): void
{
$this->checkLabels($labels);
$this->messageBus->dispatch(new RemoveMetricMessage(static::TYPE, $this->namespace, $this->name, $labels));
}

/**
* @throws LabelsNotMatchException
*/
Expand Down
2 changes: 2 additions & 0 deletions src/BundledPlugin/Metrics/Summary.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

final class Summary extends Metric
{
protected const TYPE = 'summary';

private array $buffer = [];

/**
Expand Down

0 comments on commit 98b142b

Please sign in to comment.