Skip to content

Commit

Permalink
Fixed bug that prometheus cannot collect histograms.
Browse files Browse the repository at this point in the history
  • Loading branch information
yansongda authored Jun 1, 2023
1 parent 074b693 commit 6e9bf3f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
5 changes: 3 additions & 2 deletions src/Adapter/Prometheus/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ protected function collectHistograms(): array
unset($raw['__meta']);
// Add the Inf bucket, so we can compute it later on
$histogram['buckets'][] = '+Inf';
$allLabelValues = [];

foreach (array_keys($raw) as $k) {
$d = Json::decode($k);
Expand All @@ -251,7 +252,7 @@ protected function collectHistograms(): array
}
// We need set semantics.
// This is the equivalent of array_unique but for arrays of arrays.
$allLabelValues = array_map('unserialize', array_unique(array_map('serialize', $allLabelValues ?? [])));
$allLabelValues = array_map('unserialize', array_unique(array_map('serialize', $allLabelValues)));
sort($allLabelValues);

foreach ($allLabelValues as $labelValues) {
Expand Down Expand Up @@ -350,7 +351,7 @@ protected function collectSamples(string $metricType): array
protected function toMetricKey(array $data): string
{
// TODO: This is a hack, we should remove it since v3.1.
if (! str_ends_with(':', self::$prefix)) {
if (! str_ends_with(self::$prefix, ':')) {
$prefix = self::$prefix . ':';
}

Expand Down
56 changes: 55 additions & 1 deletion tests/Adapter/Prometheus/RedisTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,15 @@ public function testToMetricKey()
'name' => 'hyperf_metric',
];

Redis::setPrefix('prometheus:');
$method = new ReflectionMethod(Redis::class, 'toMetricKey');
$method->setAccessible(true);
self::assertEquals('prometheus:counter:hyperf_metric{counter}', $method->invoke(new Redis(new \Redis()), $data));

// 兼容 < v3.1
Redis::setPrefix('PROMETHEUS_');
$method = new ReflectionMethod(Redis::class, 'toMetricKey');
$method->setAccessible(true);
self::assertEquals('PROMETHEUS_:counter:hyperf_metric{counter}', $method->invoke(new Redis(new \Redis()), $data));
}

Expand Down Expand Up @@ -175,8 +181,9 @@ public function testCollectHistograms()
$redis = Mockery::mock(\Redis::class);
$redis->shouldReceive('sMembers')->withArgs(['prometheus:histogram:metric_keys{histogram}'])->times(1)->andReturn([
'hyperf:prometheus:histogram:hyperf_metric1{histogram}',
'hyperf:prometheus:histogram:hyperf_metric2{histogram}',
]);
$redis->shouldReceive('_prefix')->times(1)->andReturn('hyperf:');
$redis->shouldReceive('_prefix')->times(2)->andReturn('hyperf:');
$redis->shouldReceive('hGetAll')->with('prometheus:histogram:hyperf_metric1{histogram}')->times(1)->andReturn(
[
'__meta' => '{"type":"histogram","name":"hyperf_metric1","help":"hyperf_metric1","labelNames":["class","method"],"buckets":[0.1,1.0]}',
Expand All @@ -185,6 +192,14 @@ public function testCollectHistograms()
'{"b":1,"labelValues":["class_name","method_name"]}' => 1, // 0.5
],
);
$redis->shouldReceive('hGetAll')->with('prometheus:histogram:hyperf_metric2{histogram}')->times(1)->andReturn(
[
'__meta' => '{"type":"histogram","name":"hyperf_metric2","help":"hyperf_metric2","labelNames":["class2","method2"],"buckets":[0.1,1.0]}',
'{"b":"sum","labelValues":["class_name2","method_name2"]}' => 0.55,
'{"b":0.1,"labelValues":["class_name2","method_name2"]}' => 1, // 0.05
'{"b":1,"labelValues":["class_name2","method_name2"]}' => 1, // 0.5
],
);

$method = new ReflectionMethod(Redis::class, 'collectHistograms');
$method->setAccessible(true);
Expand Down Expand Up @@ -230,6 +245,45 @@ public function testCollectHistograms()
],
'buckets' => [0.1, 1.0, '+Inf'],
],
[
'type' => Histogram::TYPE,
'name' => 'hyperf_metric2',
'help' => 'hyperf_metric2',
'labelNames' => ['class2', 'method2'],
'samples' => [
[
'name' => 'hyperf_metric2_bucket',
'labelNames' => ['le'],
'labelValues' => ['class_name2', 'method_name2', 0.1],
'value' => 1,
],
[
'name' => 'hyperf_metric2_bucket',
'labelNames' => ['le'],
'labelValues' => ['class_name2', 'method_name2', 1.0],
'value' => 2,
],
[
'name' => 'hyperf_metric2_bucket',
'labelNames' => ['le'],
'labelValues' => ['class_name2', 'method_name2', '+Inf'],
'value' => 2,
],
[
'name' => 'hyperf_metric2_count',
'labelNames' => [],
'labelValues' => ['class_name2', 'method_name2'],
'value' => 2,
],
[
'name' => 'hyperf_metric2_sum',
'labelNames' => [],
'labelValues' => ['class_name2', 'method_name2'],
'value' => 0.55,
],
],
'buckets' => [0.1, 1.0, '+Inf'],
],
], $result);
}

Expand Down

0 comments on commit 6e9bf3f

Please sign in to comment.