mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-12 15:53:46 -04:00
feat(metrics): add bucket series merge and container ranking
This commit is contained in:
@@ -61,6 +61,50 @@ class FleetMetricsAggregator
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<int, array{0: int, 1: float}>> $seriesPerServer
|
||||
* @return array<int, array{0: int, 1: float}>
|
||||
*/
|
||||
public static function sumSeriesByBucket(array $seriesPerServer, string $mode): array
|
||||
{
|
||||
$totals = [];
|
||||
$counts = [];
|
||||
|
||||
foreach ($seriesPerServer as $series) {
|
||||
foreach ($series as [$ts, $value]) {
|
||||
$totals[$ts] = ($totals[$ts] ?? 0.0) + (float) $value;
|
||||
$counts[$ts] = ($counts[$ts] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
ksort($totals);
|
||||
|
||||
$out = [];
|
||||
foreach ($totals as $ts => $sum) {
|
||||
$out[] = [(int) $ts, $mode === 'avg' ? round($sum / $counts[$ts], 2) : round($sum, 2)];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $containers
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public static function rankContainers(array $containers, string $metric, int $limit = 20): array
|
||||
{
|
||||
$key = match ($metric) {
|
||||
'memory' => 'memUsed',
|
||||
'disk' => 'diskBytes',
|
||||
'network' => 'net',
|
||||
default => 'cpu',
|
||||
};
|
||||
|
||||
usort($containers, fn ($a, $b) => ($b[$key] ?? 0) <=> ($a[$key] ?? 0));
|
||||
|
||||
return array_slice($containers, 0, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $rows
|
||||
* @return array<int, float>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use App\Services\FleetMetricsAggregator;
|
||||
|
||||
it('sums series by bucket timestamp and sorts ascending', function () {
|
||||
$merged = FleetMetricsAggregator::sumSeriesByBucket([
|
||||
[[2000, 5.0], [1000, 1.0]],
|
||||
[[1000, 2.0], [3000, 9.0]],
|
||||
], 'sum');
|
||||
|
||||
expect($merged)->toBe([[1000, 3.0], [2000, 5.0], [3000, 9.0]]);
|
||||
});
|
||||
|
||||
it('averages series across servers per bucket', function () {
|
||||
$merged = FleetMetricsAggregator::sumSeriesByBucket([
|
||||
[[1000, 20.0]],
|
||||
[[1000, 40.0]],
|
||||
], 'avg');
|
||||
|
||||
expect($merged)->toBe([[1000, 30.0]]);
|
||||
});
|
||||
|
||||
it('ranks containers by the selected metric and caps the list', function () {
|
||||
$containers = [
|
||||
['id' => 'a', 'cpu' => 10.0, 'memUsed' => 500, 'diskBytes' => 5, 'net' => 1.0],
|
||||
['id' => 'b', 'cpu' => 90.0, 'memUsed' => 100, 'diskBytes' => 9, 'net' => 2.0],
|
||||
['id' => 'c', 'cpu' => 50.0, 'memUsed' => 900, 'diskBytes' => 1, 'net' => 3.0],
|
||||
];
|
||||
|
||||
expect(array_column(FleetMetricsAggregator::rankContainers($containers, 'cpu', 2), 'id'))->toBe(['b', 'c']);
|
||||
expect(array_column(FleetMetricsAggregator::rankContainers($containers, 'memory'), 'id'))->toBe(['c', 'a', 'b']);
|
||||
expect(array_column(FleetMetricsAggregator::rankContainers($containers, 'network'), 'id'))->toBe(['c', 'b', 'a']);
|
||||
});
|
||||
Reference in New Issue
Block a user