diff --git a/composer.lock b/composer.lock index b634585..e41dcbf 100644 --- a/composer.lock +++ b/composer.lock @@ -107,16 +107,16 @@ }, { "name": "utopia-php/framework", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "cc880ec41f7f163d4f9956fec26cc6be51b412cf" + "reference": "fc63ec61c720190a5ea5bb484c615145850951e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/cc880ec41f7f163d4f9956fec26cc6be51b412cf", - "reference": "cc880ec41f7f163d4f9956fec26cc6be51b412cf", + "url": "https://api.github.com/repos/utopia-php/http/zipball/fc63ec61c720190a5ea5bb484c615145850951e6", + "reference": "fc63ec61c720190a5ea5bb484c615145850951e6", "shasum": "" }, "require": { @@ -151,22 +151,22 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/1.0.0" + "source": "https://github.com/utopia-php/http/tree/1.0.2" }, - "time": "2024-09-05T15:38:08+00:00" + "time": "2024-09-10T09:04:19+00:00" }, { "name": "utopia-php/servers", - "version": "0.1.0", + "version": "0.1.1", "source": { "type": "git", "url": "https://github.com/utopia-php/servers.git", - "reference": "7d9e4f364fb1ab1889fb89ca96eb9946467cb09c" + "reference": "fd5c8d32778f265256c1936372a071b944f5ba8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/servers/zipball/7d9e4f364fb1ab1889fb89ca96eb9946467cb09c", - "reference": "7d9e4f364fb1ab1889fb89ca96eb9946467cb09c", + "url": "https://api.github.com/repos/utopia-php/servers/zipball/fd5c8d32778f265256c1936372a071b944f5ba8a", + "reference": "fd5c8d32778f265256c1936372a071b944f5ba8a", "shasum": "" }, "require": { @@ -204,9 +204,9 @@ ], "support": { "issues": "https://github.com/utopia-php/servers/issues", - "source": "https://github.com/utopia-php/servers/tree/0.1.0" + "source": "https://github.com/utopia-php/servers/tree/0.1.1" }, - "time": "2024-08-08T14:31:39+00:00" + "time": "2024-09-06T02:25:56+00:00" } ], "packages-dev": [ @@ -282,16 +282,16 @@ }, { "name": "laravel/pint", - "version": "v1.17.3", + "version": "v1.18.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "9d77be916e145864f10788bb94531d03e1f7b482" + "reference": "35c00c05ec43e6b46d295efc0f4386ceb30d50d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/9d77be916e145864f10788bb94531d03e1f7b482", - "reference": "9d77be916e145864f10788bb94531d03e1f7b482", + "url": "https://api.github.com/repos/laravel/pint/zipball/35c00c05ec43e6b46d295efc0f4386ceb30d50d9", + "reference": "35c00c05ec43e6b46d295efc0f4386ceb30d50d9", "shasum": "" }, "require": { @@ -344,20 +344,20 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-09-03T15:00:28+00:00" + "time": "2024-09-24T17:22:50+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.12.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -396,7 +396,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -404,20 +404,20 @@ "type": "tidelift" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "nikic/php-parser", - "version": "v5.1.0", + "version": "v5.3.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", "shasum": "" }, "require": { @@ -460,9 +460,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" }, - "time": "2024-07-01T20:03:41+00:00" + "time": "2024-10-08T18:51:32+00:00" }, { "name": "phar-io/manifest", @@ -584,16 +584,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.2", + "version": "1.12.11", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0ca1c7bb55fca8fe6448f16fff0f311ccec960a1" + "reference": "0d1fc20a962a91be578bcfe7cf939e6e1a2ff733" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0ca1c7bb55fca8fe6448f16fff0f311ccec960a1", - "reference": "0ca1c7bb55fca8fe6448f16fff0f311ccec960a1", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d1fc20a962a91be578bcfe7cf939e6e1a2ff733", + "reference": "0d1fc20a962a91be578bcfe7cf939e6e1a2ff733", "shasum": "" }, "require": { @@ -638,7 +638,7 @@ "type": "github" } ], - "time": "2024-09-05T16:09:28+00:00" + "time": "2024-11-17T14:08:01+00:00" }, { "name": "phpunit/php-code-coverage", @@ -961,16 +961,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.20", + "version": "9.6.21", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "49d7820565836236411f5dc002d16dd689cde42f" + "reference": "de6abf3b6f8dd955fac3caad3af7a9504e8c2ffa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/49d7820565836236411f5dc002d16dd689cde42f", - "reference": "49d7820565836236411f5dc002d16dd689cde42f", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/de6abf3b6f8dd955fac3caad3af7a9504e8c2ffa", + "reference": "de6abf3b6f8dd955fac3caad3af7a9504e8c2ffa", "shasum": "" }, "require": { @@ -985,7 +985,7 @@ "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.31", + "phpunit/php-code-coverage": "^9.2.32", "phpunit/php-file-iterator": "^3.0.6", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.4", @@ -1044,7 +1044,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.20" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.21" }, "funding": [ { @@ -1060,7 +1060,7 @@ "type": "tidelift" } ], - "time": "2024-07-10T11:45:39+00:00" + "time": "2024-09-19T10:50:18+00:00" }, { "name": "sebastian/cli-parser", @@ -2078,12 +2078,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=8.0" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/src/Orchestration/Adapter/DockerAPI.php b/src/Orchestration/Adapter/DockerAPI.php index 44eb4e5..e5e76c9 100644 --- a/src/Orchestration/Adapter/DockerAPI.php +++ b/src/Orchestration/Adapter/DockerAPI.php @@ -311,68 +311,72 @@ public function getStats(?string $container = null, array $filters = []): array $list = []; foreach ($containerIds as $containerId) { - $result = $this->call('http://localhost/containers/'.$containerId.'/stats?stream=false', 'GET'); + try { + $result = $this->call('http://localhost/containers/'.$containerId.'/stats?stream=false', 'GET'); - if ($result['code'] !== 200 || empty($result['response'])) { - throw new Orchestration($result['response']); - } + if ($result['code'] !== 200 || empty($result['response'])) { + continue; // Skip to the next container + } - $stats = \json_decode($result['response'], true); + $stats = \json_decode($result['response'], true); - if (! isset($stats['id']) || ! isset($stats['precpu_stats']) || ! isset($stats['cpu_stats']) || ! isset($stats['memory_stats']) || ! isset($stats['networks'])) { - throw new Orchestration('Failed to get stats for container: '.$containerId); - } + if (! isset($stats['id']) || ! isset($stats['precpu_stats']) || ! isset($stats['cpu_stats']) || ! isset($stats['memory_stats']) || ! isset($stats['networks'])) { + continue; // Skip to the next container + } - // Calculate CPU usage - $cpuDelta = $stats['cpu_stats']['cpu_usage']['total_usage'] - $stats['precpu_stats']['cpu_usage']['total_usage']; - $systemCpuDelta = $stats['cpu_stats']['system_cpu_usage'] - $stats['precpu_stats']['system_cpu_usage']; - $numberCpus = $stats['cpu_stats']['online_cpus']; - if ($systemCpuDelta > 0 && $cpuDelta > 0) { - $cpuUsage = ($cpuDelta / $systemCpuDelta) * $numberCpus; - } else { - $cpuUsage = 0.0; - } + // Calculate CPU usage + $cpuDelta = $stats['cpu_stats']['cpu_usage']['total_usage'] - $stats['precpu_stats']['cpu_usage']['total_usage']; + $systemCpuDelta = $stats['cpu_stats']['system_cpu_usage'] - $stats['precpu_stats']['system_cpu_usage']; + $numberCpus = $stats['cpu_stats']['online_cpus']; + if ($systemCpuDelta > 0 && $cpuDelta > 0) { + $cpuUsage = ($cpuDelta / $systemCpuDelta) * $numberCpus; + } else { + $cpuUsage = 0.0; + } - // Calculate memory usage (unsafe div /0) - $memoryUsage = 0.0; - if ($stats['memory_stats']['limit'] > 0 && $stats['memory_stats']['usage'] > 0) { - $memoryUsage = ($stats['memory_stats']['usage'] / $stats['memory_stats']['limit']) * 100.0; - } + // Calculate memory usage (unsafe div /0) + $memoryUsage = 0.0; + if ($stats['memory_stats']['limit'] > 0 && $stats['memory_stats']['usage'] > 0) { + $memoryUsage = ($stats['memory_stats']['usage'] / $stats['memory_stats']['limit']) * 100.0; + } - // Calculate network I/O - $networkIn = 0; - $networkOut = 0; - foreach ($stats['networks'] as $network) { - $networkIn += $network['rx_bytes']; - $networkOut += $network['tx_bytes']; - } + // Calculate network I/O + $networkIn = 0; + $networkOut = 0; + foreach ($stats['networks'] as $network) { + $networkIn += $network['rx_bytes']; + $networkOut += $network['tx_bytes']; + } - // Calculate disk I/O - $diskRead = 0; - $diskWrite = 0; - if (isset($stats['blkio_stats']['io_service_bytes_recursive'])) { - foreach ($stats['blkio_stats']['io_service_bytes_recursive'] as $entry) { - if ($entry['op'] === 'Read') { - $diskRead += $entry['value']; - } elseif ($entry['op'] === 'Write') { - $diskWrite += $entry['value']; + // Calculate disk I/O + $diskRead = 0; + $diskWrite = 0; + if (isset($stats['blkio_stats']['io_service_bytes_recursive'])) { + foreach ($stats['blkio_stats']['io_service_bytes_recursive'] as $entry) { + if ($entry['op'] === 'Read') { + $diskRead += $entry['value']; + } elseif ($entry['op'] === 'Write') { + $diskWrite += $entry['value']; + } } } - } - // Calculate memory I/O (approximated) - $memoryIn = $stats['memory_stats']['usage'] ?? 0; - $memoryOut = $stats['memory_stats']['max_usage'] ?? 0; - - $list[] = new Stats( - containerId: $stats['id'], - containerName: \ltrim($stats['name'], '/'), // Remove '/' prefix - cpuUsage: $cpuUsage, - memoryUsage: $memoryUsage, - diskIO: ['in' => $diskRead, 'out' => $diskWrite], - memoryIO: ['in' => $memoryIn, 'out' => $memoryOut], - networkIO: ['in' => $networkIn, 'out' => $networkOut], - ); + // Calculate memory I/O (approximated) + $memoryIn = $stats['memory_stats']['usage'] ?? 0; + $memoryOut = $stats['memory_stats']['max_usage'] ?? 0; + + $list[] = new Stats( + containerId: $stats['id'], + containerName: \ltrim($stats['name'], '/'), // Remove '/' prefix + cpuUsage: $cpuUsage, + memoryUsage: $memoryUsage, + diskIO: ['in' => $diskRead, 'out' => $diskWrite], + memoryIO: ['in' => $memoryIn, 'out' => $memoryOut], + networkIO: ['in' => $networkIn, 'out' => $networkOut], + ); + } catch (\Throwable $e) { + continue; + } } return $list; diff --git a/src/Orchestration/Adapter/DockerCLI.php b/src/Orchestration/Adapter/DockerCLI.php index e23f0b3..dcb81c6 100644 --- a/src/Orchestration/Adapter/DockerCLI.php +++ b/src/Orchestration/Adapter/DockerCLI.php @@ -123,7 +123,7 @@ public function getStats(?string $container = null, array $filters = []): array $result = Console::execute('docker stats --no-trunc --format "id={{.ID}}&name={{.Name}}&cpu={{.CPUPerc}}&memory={{.MemPerc}}&diskIO={{.BlockIO}}&memoryIO={{.MemUsage}}&networkIO={{.NetIO}}" --no-stream'.$containersString, '', $output); if ($result !== 0) { - throw new Orchestration("Docker Error: {$output}"); + return []; } $lines = \explode("\n", $output); diff --git a/tests/Orchestration/Base.php b/tests/Orchestration/Base.php index 5cf7082..77ccfa5 100644 --- a/tests/Orchestration/Base.php +++ b/tests/Orchestration/Base.php @@ -712,9 +712,8 @@ public function testUsageStats(): void /** * Test for Failure */ - $this->expectException(\Exception::class); - $stats = static::getOrchestration()->getStats('IDontExist'); + $this->assertCount(0, $stats); } public function testNetworkExists(): void