- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
168 lines
4.2 KiB
PHP
168 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Telemetry\ValueObjects;
|
|
|
|
use DateTimeImmutable;
|
|
|
|
/**
|
|
* Represents a telemetry metric (a measurable value)
|
|
*/
|
|
final class Metric
|
|
{
|
|
/**
|
|
* @param string $name Name of the metric
|
|
* @param float $value Value of the metric
|
|
* @param string $unit Unit of measurement (e.g., ms, bytes, count)
|
|
* @param string $type Type of metric (counter, gauge, histogram)
|
|
* @param DateTimeImmutable $timestamp Time when the metric was recorded
|
|
* @param array<string, mixed> $attributes Additional attributes for the metric
|
|
*/
|
|
public function __construct(
|
|
public readonly string $name,
|
|
public readonly float $value,
|
|
public readonly string $unit = '',
|
|
public readonly string $type = 'gauge',
|
|
public readonly DateTimeImmutable $timestamp = new DateTimeImmutable(),
|
|
public readonly array $attributes = []
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Convert the metric to an array
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'name' => $this->name,
|
|
'value' => $this->value,
|
|
'unit' => $this->unit,
|
|
'type' => $this->type,
|
|
'timestamp' => $this->timestamp->format('Y-m-d\TH:i:s.uP'),
|
|
'attributes' => $this->attributes,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Create a new instance with additional attributes
|
|
*
|
|
* @param array<string, mixed> $attributes
|
|
*/
|
|
public function withAttributes(array $attributes): self
|
|
{
|
|
return new self(
|
|
$this->name,
|
|
$this->value,
|
|
$this->unit,
|
|
$this->type,
|
|
$this->timestamp,
|
|
array_merge($this->attributes, $attributes)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Create a counter metric
|
|
*/
|
|
public static function counter(string $name, float $value, array $attributes = []): self
|
|
{
|
|
return new self(
|
|
$name,
|
|
$value,
|
|
'count',
|
|
'counter',
|
|
new DateTimeImmutable(),
|
|
$attributes
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Create a gauge metric
|
|
*/
|
|
public static function gauge(string $name, float $value, string $unit = '', array $attributes = []): self
|
|
{
|
|
return new self(
|
|
$name,
|
|
$value,
|
|
$unit,
|
|
'gauge',
|
|
new DateTimeImmutable(),
|
|
$attributes
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Create a histogram metric
|
|
*/
|
|
public static function histogram(string $name, float $value, string $unit = '', array $attributes = []): self
|
|
{
|
|
return new self(
|
|
$name,
|
|
$value,
|
|
$unit,
|
|
'histogram',
|
|
new DateTimeImmutable(),
|
|
$attributes
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get the formatted name for Prometheus
|
|
*/
|
|
public function getPrometheusName(): string
|
|
{
|
|
// Convert to Prometheus naming convention (lowercase with underscores)
|
|
return strtolower(str_replace(['.', '-', ' '], '_', $this->name));
|
|
}
|
|
|
|
/**
|
|
* Get the Prometheus metric type
|
|
*/
|
|
public function getPrometheusType(): string
|
|
{
|
|
return match($this->type) {
|
|
'counter' => 'counter',
|
|
'gauge' => 'gauge',
|
|
'histogram' => 'histogram',
|
|
default => 'untyped'
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get the Prometheus help text
|
|
*/
|
|
public function getPrometheusHelp(): string
|
|
{
|
|
$unitText = $this->unit ? " in {$this->unit}" : '';
|
|
|
|
return "{$this->name}{$unitText}";
|
|
}
|
|
|
|
/**
|
|
* Format the attributes as Prometheus labels
|
|
*/
|
|
public function getPrometheusLabels(): string
|
|
{
|
|
if (empty($this->attributes)) {
|
|
return '';
|
|
}
|
|
|
|
$labels = [];
|
|
foreach ($this->attributes as $key => $value) {
|
|
// Skip non-scalar values
|
|
if (is_scalar($value)) {
|
|
$escapedValue = str_replace(['\\', '"', "\n"], ['\\\\', '\\"', '\\n'], (string)$value);
|
|
$labels[] = "{$key}=\"{$escapedValue}\"";
|
|
}
|
|
}
|
|
|
|
if (empty($labels)) {
|
|
return '';
|
|
}
|
|
|
|
return '{' . implode(',', $labels) . '}';
|
|
}
|
|
}
|