From 7162185400311766b4cb8fe5db450bed81cdc7b1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 13 Aug 2026 10:58:28 +0200 Subject: [PATCH] fix(metrics): convert container memory samples from bytes to MB Sentinel stores container used memory in bytes while application and database charts label the series as megabytes. Convert those samples before they reach the frontend so the graph is not inflated by ~1024x. --- app/Traits/HasMetrics.php | 11 +++++-- bootstrap/helpers/shared.php | 17 ++++++++++ .../ContainerMemoryMetricsConversionTest.php | 33 +++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/ContainerMemoryMetricsConversionTest.php diff --git a/app/Traits/HasMetrics.php b/app/Traits/HasMetrics.php index 20b3752f5..712f09a48 100644 --- a/app/Traits/HasMetrics.php +++ b/app/Traits/HasMetrics.php @@ -15,9 +15,16 @@ trait HasMetrics public function getMemoryMetrics(int $mins = 5): ?array { - $field = $this->isServerMetrics() ? 'usedPercent' : 'used'; + if ($this->isServerMetrics()) { + return $this->getMetrics('memory', $mins, 'usedPercent'); + } - return $this->getMetrics('memory', $mins, $field); + $metrics = $this->getMetrics('memory', $mins, 'used'); + if ($metrics === null) { + return null; + } + + return convertContainerMemoryBytesToMegabytes($metrics); } private function getMetrics(string $type, int $mins, string $valueField): ?array diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index b183f5903..cf63c4776 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -4724,6 +4724,23 @@ function downsampleLTTB(array $data, int $threshold): array return $sampled; } +/** + * Convert Sentinel container memory samples from bytes to megabytes. + * + * Sentinel stores container `used` memory in bytes. Application and database + * metric charts label the series as megabytes, so the values must be converted + * before they are sent to the frontend. + * + * @param array $metrics + * @return array + */ +function convertContainerMemoryBytesToMegabytes(array $metrics): array +{ + return array_map(static function (array $point): array { + return [(int) $point[0], round(((float) $point[1]) / 1024 / 1024, 2)]; + }, $metrics); +} + /** * Resolve shared environment variable patterns like {{environment.VAR}}, {{project.VAR}}, {{team.VAR}}. * diff --git a/tests/Unit/ContainerMemoryMetricsConversionTest.php b/tests/Unit/ContainerMemoryMetricsConversionTest.php new file mode 100644 index 000000000..8ad4ca79e --- /dev/null +++ b/tests/Unit/ContainerMemoryMetricsConversionTest.php @@ -0,0 +1,33 @@ +toBe([ + [1_700_000_000_000, 81.06], + [1_700_000_005_000, 100.0], + ]); +}); + +it('preserves timestamps and converts a zero byte sample to zero megabytes', function () { + expect(convertContainerMemoryBytesToMegabytes([ + [1_700_000_000_000, 0.0], + ]))->toBe([ + [1_700_000_000_000, 0.0], + ]); +}); + +it('leaves an empty series unchanged', function () { + expect(convertContainerMemoryBytesToMegabytes([]))->toBe([]); +});