diff --git a/src/Metrics/CounterAdapter.php b/src/Metrics/CounterAdapter.php new file mode 100644 index 0000000..d76fc2f --- /dev/null +++ b/src/Metrics/CounterAdapter.php @@ -0,0 +1,41 @@ + + */ + +namespace Instrumentation\Metrics; + +use OpenTelemetry\API\Metrics\CounterInterface; +use Prometheus\CollectorRegistry; + +class CounterAdapter implements CounterInterface +{ + public function __construct( + private string $name, + private string $description, + private CollectorRegistry $collectorRegistry, + ) { + } + + /** + * @param int $amount + * @param array{labels: array} $attributes + */ + public function add($amount, iterable $attributes = [], $context = null): void + { + /** @var array $labelNames */ + $labelNames = array_keys($attributes['labels'] ?? []); + $labelValues = array_values($attributes['labels'] ?? []); + + $counter = $this->collectorRegistry->getOrRegisterCounter( + '', + $this->name, + $this->description, + $labelNames, + ); + + $counter->incBy($amount, $labelValues); + } +} diff --git a/src/Metrics/HistogramAdapter.php b/src/Metrics/HistogramAdapter.php new file mode 100644 index 0000000..4088a4c --- /dev/null +++ b/src/Metrics/HistogramAdapter.php @@ -0,0 +1,41 @@ + + */ + +namespace Instrumentation\Metrics; + +use OpenTelemetry\API\Metrics\HistogramInterface; +use Prometheus\CollectorRegistry; +use Prometheus\Histogram; + +class HistogramAdapter implements HistogramInterface +{ + public function __construct( + private string $name, + private string $description, + private CollectorRegistry $collectorRegistry, + ) { + } + + /** + * @param array{labels: array, buckets?: array} $attributes + */ + public function record($amount, iterable $attributes = [], $context = null): void + { + /** @var array $labelNames */ + $labelNames = array_keys($attributes['labels'] ?? []); + $labelValues = array_values($attributes['labels'] ?? []); + + $histogram = $this->collectorRegistry->getOrRegisterHistogram( + '', + $this->name, + $this->description, + $labelNames, + $attributes['buckets'] ?? Histogram::getDefaultBuckets(), + ); + $histogram->observe($amount, $labelValues); + } +} diff --git a/src/Metrics/Meter.php b/src/Metrics/Meter.php new file mode 100644 index 0000000..9fca58c --- /dev/null +++ b/src/Metrics/Meter.php @@ -0,0 +1,55 @@ + + */ + +namespace Instrumentation\Metrics; + +use OpenTelemetry\API\Metrics\CounterInterface; +use OpenTelemetry\API\Metrics\HistogramInterface; +use OpenTelemetry\API\Metrics\MeterInterface; +use OpenTelemetry\API\Metrics\ObservableCounterInterface; +use OpenTelemetry\API\Metrics\ObservableGaugeInterface; +use OpenTelemetry\API\Metrics\ObservableUpDownCounterInterface; +use OpenTelemetry\API\Metrics\UpDownCounterInterface; +use Prometheus\CollectorRegistry; + +class Meter implements MeterInterface +{ + public function __construct( + private CollectorRegistry $collectorRegistry, + ) { + } + + public function createCounter(string $name, string $unit = null, string $description = null): CounterInterface + { + return new CounterAdapter($name, $description ?: '', $this->collectorRegistry); + } + + public function createObservableCounter(string $name, string $unit = null, string $description = null, callable ...$callbacks): ObservableCounterInterface + { + throw new \LogicException(sprintf('Method %s is not implemented', __METHOD__)); + } + + public function createHistogram(string $name, string $unit = null, string $description = null): HistogramInterface + { + return new HistogramAdapter($name, $description ?: '', $this->collectorRegistry); + } + + public function createObservableGauge(string $name, string $unit = null, string $description = null, callable ...$callbacks): ObservableGaugeInterface + { + throw new \LogicException(sprintf('Method %s is not implemented', __METHOD__)); + } + + public function createUpDownCounter(string $name, string $unit = null, string $description = null): UpDownCounterInterface + { + return new UpDownCounterAdapter($name, $description ?: '', $this->collectorRegistry); + } + + public function createObservableUpDownCounter(string $name, string $unit = null, string $description = null, callable ...$callbacks): ObservableUpDownCounterInterface + { + throw new \LogicException(sprintf('Method %s is not implemented', __METHOD__)); + } +} diff --git a/src/Metrics/UpDownCounterAdapter.php b/src/Metrics/UpDownCounterAdapter.php new file mode 100644 index 0000000..8d64be2 --- /dev/null +++ b/src/Metrics/UpDownCounterAdapter.php @@ -0,0 +1,45 @@ + + */ + +namespace Instrumentation\Metrics; + +use OpenTelemetry\API\Metrics\UpDownCounterInterface; +use Prometheus\CollectorRegistry; + +class UpDownCounterAdapter implements UpDownCounterInterface +{ + public function __construct( + private string $name, + private string $description, + private CollectorRegistry $collectorRegistry, + ) { + } + + /** + * @param int $amount + * @param array{labels: array} $attributes + */ + public function add($amount, iterable $attributes = [], $context = null): void + { + /** @var array $labelNames */ + $labelNames = array_keys($attributes['labels'] ?? []); + $labelValues = array_values($attributes['labels'] ?? []); + + $gauge = $this->collectorRegistry->getOrRegisterGauge( + '', + $this->name, + $this->description, + $labelNames, + ); + + if ($amount > 0) { + $gauge->incBy($amount, $labelValues); + } else { + $gauge->decBy(abs($amount), $labelValues); + } + } +}