From 730c62bda60cbb32da196c01b01c7ac4d6c98c22 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Wed, 15 Apr 2026 18:35:09 +0530 Subject: [PATCH] remove usage stats --- app/init/constants.php | 6 -- .../Modules/Functions/Workers/Screenshots.php | 74 ++++------------ .../Platform/Modules/Sites/Http/Usage/Get.php | 22 ++--- .../Modules/Sites/Http/Usage/XList.php | 23 ++--- .../Utopia/Response/Model/UsageSite.php | 32 ------- .../Utopia/Response/Model/UsageSites.php | 84 ++++++------------- tests/e2e/General/UsageTest.php | 14 +--- 7 files changed, 57 insertions(+), 198 deletions(-) diff --git a/app/init/constants.php b/app/init/constants.php index 57763df911..f2127cd666 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -351,8 +351,6 @@ const METRIC_BUILDS_STORAGE = 'builds.storage'; const METRIC_BUILDS_COMPUTE = 'builds.compute'; const METRIC_BUILDS_COMPUTE_SUCCESS = 'builds.compute.success'; const METRIC_BUILDS_COMPUTE_FAILED = 'builds.compute.failed'; -const METRIC_SCREENSHOTS_SUCCESS = 'screenshots.success'; -const METRIC_SCREENSHOTS_FAILED = 'screenshots.failed'; const METRIC_BUILDS_MB_SECONDS = 'builds.mbSeconds'; const METRIC_EXECUTIONS = 'executions'; const METRIC_EXECUTIONS_COMPUTE = 'executions.compute'; @@ -365,8 +363,6 @@ const METRIC_RESOURCE_TYPE_ID_BUILDS_FAILED = '{resourceType}.{resourceInternal const METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE = '{resourceType}.{resourceInternalId}.builds.compute'; const METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE_SUCCESS = '{resourceType}.{resourceInternalId}.builds.compute.success'; const METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE_FAILED = '{resourceType}.{resourceInternalId}.builds.compute.failed'; -const METRIC_RESOURCE_TYPE_ID_SCREENSHOTS_SUCCESS = '{resourceType}.{resourceInternalId}.screenshots.success'; -const METRIC_RESOURCE_TYPE_ID_SCREENSHOTS_FAILED = '{resourceType}.{resourceInternalId}.screenshots.failed'; const METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS = '{resourceType}.{resourceInternalId}.builds.mbSeconds'; const METRIC_RESOURCE_TYPE_ID_BUILDS = '{resourceType}.{resourceInternalId}.builds'; const METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE = '{resourceType}.{resourceInternalId}.builds.storage'; @@ -380,8 +376,6 @@ const METRIC_RESOURCE_TYPE_BUILDS_FAILED = '{resourceType}.builds.failed'; const METRIC_RESOURCE_TYPE_BUILDS_COMPUTE = '{resourceType}.builds.compute'; const METRIC_RESOURCE_TYPE_BUILDS_COMPUTE_SUCCESS = '{resourceType}.builds.compute.success'; const METRIC_RESOURCE_TYPE_BUILDS_COMPUTE_FAILED = '{resourceType}.builds.compute.failed'; -const METRIC_RESOURCE_TYPE_SCREENSHOTS_SUCCESS = '{resourceType}.screenshots.success'; -const METRIC_RESOURCE_TYPE_SCREENSHOTS_FAILED = '{resourceType}.screenshots.failed'; const METRIC_RESOURCE_TYPE_BUILDS_MB_SECONDS = '{resourceType}.builds.mbSeconds'; const METRIC_RESOURCE_TYPE_BUILDS = '{resourceType}.builds'; const METRIC_RESOURCE_TYPE_BUILDS_STORAGE = '{resourceType}.builds.storage'; diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php index bac72b993f..0cb42822b3 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php @@ -4,12 +4,9 @@ namespace Appwrite\Platform\Modules\Functions\Workers; use Ahc\Jwt\JWT; use Appwrite\Event\Message\Screenshot; -use Appwrite\Event\Message\Usage as UsageMessage; -use Appwrite\Event\Publisher\Usage as UsagePublisher; use Appwrite\Event\Realtime; use Appwrite\Permission; use Appwrite\Role; -use Appwrite\Usage\Context; use Exception; use Utopia\Compression\Compression; use Utopia\Config\Config; @@ -23,6 +20,7 @@ use Utopia\Platform\Action; use Utopia\Queue\Message; use Utopia\Storage\Device; use Utopia\System\System; +use Utopia\Telemetry\Adapter as Telemetry; use function Swoole\Coroutine\batch; @@ -47,7 +45,7 @@ class Screenshots extends Action ->inject('dbForProject') ->inject('project') ->inject('deviceForFiles') - ->inject('publisherForUsage') + ->inject('telemetry') ->callback($this->action(...)); } @@ -58,12 +56,11 @@ class Screenshots extends Action Database $dbForProject, Document $project, Device $deviceForFiles, - UsagePublisher $publisherForUsage + Telemetry $telemetry ): void { Console::log('Screenshot action started'); $payload = $message->getPayload() ?? []; - $screenshotCompleted = false; if (empty($payload)) { throw new \Exception('Missing payload'); @@ -266,7 +263,6 @@ class Screenshots extends Action 'deploymentScreenshotDark' => $deployment->getAttribute('screenshotDark', ''), 'deploymentScreenshotLight' => $deployment->getAttribute('screenshotLight', ''), ])); - $screenshotCompleted = true; } catch (\Throwable $th) { Console::warning("Screenshot failed to generate:"); Console::warning($th->getMessage()); @@ -275,62 +271,26 @@ class Screenshots extends Action $date = \date('H:i:s'); $this->appendToLogs($dbForProject, $deployment->getId(), $queueForRealtime, "[$date] [appwrite] Screenshot capturing failed. Deployment will continue. \n"); - if (!$screenshotCompleted) { - try { - $this->publishUsage( - project: $project, - site: $site, - publisherForUsage: $publisherForUsage, - metric: METRIC_SCREENSHOTS_FAILED - ); - } catch (\Throwable) { - // Usage publish is best-effort; preserve the original screenshot exception. - } - } + $this->recordTelemetry($telemetry, 'failure'); throw $th; } - $this->publishUsage( - project: $project, - site: $site, - publisherForUsage: $publisherForUsage, - metric: METRIC_SCREENSHOTS_SUCCESS - ); + $this->recordTelemetry($telemetry, 'success'); } - protected function publishUsage( - Document $project, - Document $site, - UsagePublisher $publisherForUsage, - string $metric - ): void { - [$resourceMetric, $resourceIdMetric] = match ($metric) { - METRIC_SCREENSHOTS_SUCCESS => [ - METRIC_RESOURCE_TYPE_SCREENSHOTS_SUCCESS, - METRIC_RESOURCE_TYPE_ID_SCREENSHOTS_SUCCESS, - ], - METRIC_SCREENSHOTS_FAILED => [ - METRIC_RESOURCE_TYPE_SCREENSHOTS_FAILED, - METRIC_RESOURCE_TYPE_ID_SCREENSHOTS_FAILED, - ], - default => throw new \InvalidArgumentException('Unknown screenshot metric: ' . $metric), - }; - - $usage = (new Context()) - ->addMetric($metric, 1) - ->addMetric(str_replace('{resourceType}', RESOURCE_TYPE_SITES, $resourceMetric), 1) - ->addMetric(str_replace( - ['{resourceType}', '{resourceInternalId}'], - [RESOURCE_TYPE_SITES, $site->getSequence()], - $resourceIdMetric - ), 1); - - $publisherForUsage->enqueue(new UsageMessage( - project: $project, - metrics: $usage->getMetrics(), - reduce: $usage->getReduce() - )); + protected function recordTelemetry(Telemetry $telemetry, string $result): void + { + try { + $telemetry + ->createCounter('worker.screenshots.capture') + ->add(1, [ + 'resourceType' => RESOURCE_TYPE_SITES, + 'result' => $result, + ]); + } catch (\Throwable) { + // Telemetry should never affect screenshot processing. + } } protected function appendToLogs(Database $dbForProject, string $deploymentId, Realtime $queueForRealtime, string $logs) diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Usage/Get.php b/src/Appwrite/Platform/Modules/Sites/Http/Usage/Get.php index a1af4bd8fd..a6768462d1 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Usage/Get.php @@ -87,8 +87,6 @@ class Get extends Base str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_SITES, $site->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS), str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_SITES, $site->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_SUCCESS), str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_SITES, $site->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_FAILED), - str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_SITES, $site->getSequence()], METRIC_RESOURCE_TYPE_ID_SCREENSHOTS_SUCCESS), - str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_SITES, $site->getSequence()], METRIC_RESOURCE_TYPE_ID_SCREENSHOTS_FAILED), str_replace(['{siteInternalId}'], [$site->getSequence()], METRIC_SITES_ID_REQUESTS), str_replace(['{siteInternalId}'], [$site->getSequence()], METRIC_SITES_ID_INBOUND), str_replace(['{siteInternalId}'], [$site->getSequence()], METRIC_SITES_ID_OUTBOUND), @@ -141,9 +139,6 @@ class Get extends Base $buildsTimeTotal = $usage[$metrics[4]]['total'] ?? 0; $buildsTotal = $usage[$metrics[2]]['total'] ?? 0; - $screenshotsSuccessTotal = $usage[$metrics[11]]['total'] ?? 0; - $screenshotsFailedTotal = $usage[$metrics[12]]['total'] ?? 0; - $screenshotsTotal = $screenshotsSuccessTotal + $screenshotsFailedTotal; $response->dynamic(new Document([ 'range' => $range, 'deploymentsTotal' => $usage[$metrics[0]]['total'], @@ -158,12 +153,9 @@ class Get extends Base 'executionsMbSecondsTotal' => $usage[$metrics[8]]['total'], 'buildsSuccessTotal' => $usage[$metrics[9]]['total'], 'buildsFailedTotal' => $usage[$metrics[10]]['total'], - 'screenshotsSuccessTotal' => $screenshotsSuccessTotal, - 'screenshotsFailedTotal' => $screenshotsFailedTotal, - 'screenshotsSuccessRate' => $screenshotsTotal === 0 ? 0 : $screenshotsSuccessTotal / $screenshotsTotal, - 'requestsTotal' => $usage[$metrics[13]]['total'], - 'inboundTotal' => $usage[$metrics[14]]['total'], - 'outboundTotal' => $usage[$metrics[15]]['total'], + 'requestsTotal' => $usage[$metrics[11]]['total'], + 'inboundTotal' => $usage[$metrics[12]]['total'], + 'outboundTotal' => $usage[$metrics[13]]['total'], 'deployments' => $usage[$metrics[0]]['data'], 'deploymentsStorage' => $usage[$metrics[1]]['data'], 'builds' => $usage[$metrics[2]]['data'], @@ -175,11 +167,9 @@ class Get extends Base 'executionsMbSeconds' => $usage[$metrics[8]]['data'], 'buildsSuccess' => $usage[$metrics[9]]['data'], 'buildsFailed' => $usage[$metrics[10]]['data'], - 'screenshotsSuccess' => $usage[$metrics[11]]['data'], - 'screenshotsFailed' => $usage[$metrics[12]]['data'], - 'requests' => $usage[$metrics[13]]['data'], - 'inbound' => $usage[$metrics[14]]['data'], - 'outbound' => $usage[$metrics[15]]['data'], + 'requests' => $usage[$metrics[11]]['data'], + 'inbound' => $usage[$metrics[12]]['data'], + 'outbound' => $usage[$metrics[13]]['data'], ]), Response::MODEL_USAGE_SITE); } } diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Usage/XList.php b/src/Appwrite/Platform/Modules/Sites/Http/Usage/XList.php index 3b3c759fd5..a90cb0cab9 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Usage/XList.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Usage/XList.php @@ -74,8 +74,6 @@ class XList extends Base str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_EXECUTIONS_MB_SECONDS), str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_BUILDS_SUCCESS), str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_BUILDS_FAILED), - str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_SCREENSHOTS_SUCCESS), - str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_SCREENSHOTS_FAILED), METRIC_SITES_REQUESTS, METRIC_SITES_INBOUND, METRIC_SITES_OUTBOUND, @@ -124,10 +122,6 @@ class XList extends Base ]; } } - $screenshotsSuccessTotal = $usage[$metrics[12]]['total'] ?? 0; - $screenshotsFailedTotal = $usage[$metrics[13]]['total'] ?? 0; - $screenshotsTotal = $screenshotsSuccessTotal + $screenshotsFailedTotal; - $response->dynamic(new Document([ 'range' => $range, 'sitesTotal' => $usage[$metrics[0]]['total'], @@ -142,12 +136,9 @@ class XList extends Base 'executionsMbSecondsTotal' => $usage[$metrics[9]]['total'], 'buildsSuccessTotal' => $usage[$metrics[10]]['total'], 'buildsFailedTotal' => $usage[$metrics[11]]['total'], - 'screenshotsSuccessTotal' => $screenshotsSuccessTotal, - 'screenshotsFailedTotal' => $screenshotsFailedTotal, - 'screenshotsSuccessRate' => $screenshotsTotal === 0 ? 0 : $screenshotsSuccessTotal / $screenshotsTotal, - 'requestsTotal' => $usage[$metrics[14]]['total'], - 'inboundTotal' => $usage[$metrics[15]]['total'], - 'outboundTotal' => $usage[$metrics[16]]['total'], + 'requestsTotal' => $usage[$metrics[12]]['total'], + 'inboundTotal' => $usage[$metrics[13]]['total'], + 'outboundTotal' => $usage[$metrics[14]]['total'], 'sites' => $usage[$metrics[0]]['data'], 'deployments' => $usage[$metrics[1]]['data'], 'deploymentsStorage' => $usage[$metrics[2]]['data'], @@ -160,11 +151,9 @@ class XList extends Base 'executionsMbSeconds' => $usage[$metrics[9]]['data'], 'buildsSuccess' => $usage[$metrics[10]]['data'], 'buildsFailed' => $usage[$metrics[11]]['data'], - 'screenshotsSuccess' => $usage[$metrics[12]]['data'], - 'screenshotsFailed' => $usage[$metrics[13]]['data'], - 'requests' => $usage[$metrics[14]]['data'], - 'inbound' => $usage[$metrics[15]]['data'], - 'outbound' => $usage[$metrics[16]]['data'], + 'requests' => $usage[$metrics[12]]['data'], + 'inbound' => $usage[$metrics[13]]['data'], + 'outbound' => $usage[$metrics[14]]['data'], ]), Response::MODEL_USAGE_SITES); } } diff --git a/src/Appwrite/Utopia/Response/Model/UsageSite.php b/src/Appwrite/Utopia/Response/Model/UsageSite.php index af41a34639..c45dc831cd 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageSite.php +++ b/src/Appwrite/Utopia/Response/Model/UsageSite.php @@ -10,38 +10,6 @@ class UsageSite extends UsageFunction { parent::__construct(); $this - ->addRule('screenshotsSuccessTotal', [ - 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of successful site screenshots.', - 'default' => 0, - 'example' => 0, - ]) - ->addRule('screenshotsFailedTotal', [ - 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of failed site screenshots.', - 'default' => 0, - 'example' => 0, - ]) - ->addRule('screenshotsSuccessRate', [ - 'type' => self::TYPE_FLOAT, - 'description' => 'Success rate of site screenshots from 0 to 1.', - 'default' => 0, - 'example' => 0, - ]) - ->addRule('screenshotsSuccess', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of successful site screenshots per period.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('screenshotsFailed', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of failed site screenshots per period.', - 'default' => [], - 'example' => [], - 'array' => true - ]) ->addRule('requestsTotal', [ 'type' => self::TYPE_INTEGER, 'description' => 'Total aggregated number of requests.', diff --git a/src/Appwrite/Utopia/Response/Model/UsageSites.php b/src/Appwrite/Utopia/Response/Model/UsageSites.php index 94ee6e645f..fea87c7718 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageSites.php +++ b/src/Appwrite/Utopia/Response/Model/UsageSites.php @@ -83,36 +83,6 @@ class UsageSites extends Model 'default' => 0, 'example' => 0, ]) - ->addRule('buildsSuccessTotal', [ - 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of successful site builds.', - 'default' => 0, - 'example' => 0, - ]) - ->addRule('buildsFailedTotal', [ - 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of failed site builds.', - 'default' => 0, - 'example' => 0, - ]) - ->addRule('screenshotsSuccessTotal', [ - 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of successful site screenshots.', - 'default' => 0, - 'example' => 0, - ]) - ->addRule('screenshotsFailedTotal', [ - 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of failed site screenshots.', - 'default' => 0, - 'example' => 0, - ]) - ->addRule('screenshotsSuccessRate', [ - 'type' => self::TYPE_FLOAT, - 'description' => 'Success rate of site screenshots from 0 to 1.', - 'default' => 0, - 'example' => 0, - ]) ->addRule('requestsTotal', [ 'type' => self::TYPE_INTEGER, 'description' => 'Total aggregated number of requests.', @@ -166,6 +136,18 @@ class UsageSites extends Model 'example' => [], 'array' => true ]) + ->addRule('buildsSuccessTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of successful site builds.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('buildsFailedTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of failed site builds.', + 'default' => 0, + 'example' => 0, + ]) ->addRule('builds', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated number of sites build per period.', @@ -194,34 +176,6 @@ class UsageSites extends Model 'example' => [], 'array' => true ]) - ->addRule('buildsSuccess', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of successful site builds per period.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('buildsFailed', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of failed site builds per period.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('screenshotsSuccess', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of successful site screenshots per period.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('screenshotsFailed', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of failed site screenshots per period.', - 'default' => [], - 'example' => [], - 'array' => true - ]) ->addRule('executions', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated number of sites execution per period.', @@ -243,6 +197,20 @@ class UsageSites extends Model 'example' => [], 'array' => true ]) + ->addRule('buildsSuccess', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated number of successful site builds per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('buildsFailed', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated number of failed site builds per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) ; } diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 0d2c0a7ed7..f6eb963967 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -1675,14 +1675,11 @@ class UsageTest extends Scope ); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(35, count($response['body'])); + $this->assertEquals(30, count($response['body'])); $this->assertEquals('30d', $response['body']['range']); $this->assertIsArray($response['body']['deployments']); $this->assertEquals($deploymentsSuccess, $response['body']['buildsSuccessTotal']); $this->assertEquals($deploymentsFailed, $response['body']['buildsFailedTotal']); - $this->assertGreaterThanOrEqual(1, $response['body']['screenshotsSuccessTotal']); - $this->assertEquals(0, $response['body']['screenshotsFailedTotal']); - $this->assertEquals(1.0, $response['body']['screenshotsSuccessRate']); $this->assertIsArray($response['body']['deploymentsStorage']); $this->assertIsNumeric($response['body']['deploymentsStorageTotal']); $this->assertIsNumeric($response['body']['buildsMbSecondsTotal']); @@ -1695,8 +1692,6 @@ class UsageTest extends Scope $this->assertIsArray($response['body']['executionsMbSeconds']); $this->assertIsArray($response['body']['buildsSuccess']); $this->assertIsArray($response['body']['buildsFailed']); - $this->assertIsArray($response['body']['screenshotsSuccess']); - $this->assertIsArray($response['body']['screenshotsFailed']); $this->assertIsArray($response['body']['requests']); $this->assertIsArray($response['body']['inbound']); $this->assertIsArray($response['body']['outbound']); @@ -1714,7 +1709,7 @@ class UsageTest extends Scope ); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(36, count($response['body'])); + $this->assertEquals(31, count($response['body'])); $this->assertEquals($response['body']['range'], '30d'); $this->assertIsArray($response['body']['sites']); $this->assertIsArray($response['body']['deployments']); @@ -1727,11 +1722,6 @@ class UsageTest extends Scope $this->assertIsArray($response['body']['executionsMbSeconds']); $this->assertIsArray($response['body']['buildsSuccess']); $this->assertIsArray($response['body']['buildsFailed']); - $this->assertGreaterThanOrEqual(1, $response['body']['screenshotsSuccessTotal']); - $this->assertEquals(0, $response['body']['screenshotsFailedTotal']); - $this->assertEquals(1.0, $response['body']['screenshotsSuccessRate']); - $this->assertIsArray($response['body']['screenshotsSuccess']); - $this->assertIsArray($response['body']['screenshotsFailed']); $this->assertIsArray($response['body']['requests']); $this->assertIsArray($response['body']['inbound']); $this->assertIsArray($response['body']['outbound']);