From db0a971384978b92e59f6cd4c96bac6e4a9af56d Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Wed, 15 Apr 2026 11:43:53 +0530 Subject: [PATCH 1/5] feat(sites): add screenshot success telemetry to usage stats --- app/init/constants.php | 6 ++ .../Modules/Functions/Workers/Screenshots.php | 55 ++++++++++++++++++- .../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 | 32 +++++++++++ tests/e2e/General/UsageTest.php | 14 ++++- 7 files changed, 169 insertions(+), 15 deletions(-) diff --git a/app/init/constants.php b/app/init/constants.php index f2127cd666..57763df911 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -351,6 +351,8 @@ 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'; @@ -363,6 +365,8 @@ 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'; @@ -376,6 +380,8 @@ 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 065fe477eb..fa7e394710 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php @@ -3,9 +3,12 @@ namespace Appwrite\Platform\Modules\Functions\Workers; use Ahc\Jwt\JWT; +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; @@ -43,6 +46,7 @@ class Screenshots extends Action ->inject('dbForProject') ->inject('project') ->inject('deviceForFiles') + ->inject('publisherForUsage') ->callback($this->action(...)); } @@ -52,7 +56,8 @@ class Screenshots extends Action Database $dbForPlatform, Database $dbForProject, Document $project, - Device $deviceForFiles + Device $deviceForFiles, + UsagePublisher $publisherForUsage ): void { Console::log('Screenshot action started'); @@ -257,6 +262,13 @@ class Screenshots extends Action 'deploymentScreenshotDark' => $deployment->getAttribute('screenshotDark', ''), 'deploymentScreenshotLight' => $deployment->getAttribute('screenshotLight', ''), ])); + + $this->publishUsage( + project: $project, + site: $site, + publisherForUsage: $publisherForUsage, + metric: METRIC_SCREENSHOTS_SUCCESS + ); } catch (\Throwable $th) { Console::warning("Screenshot failed to generate:"); Console::warning($th->getMessage()); @@ -265,10 +277,51 @@ class Screenshots extends Action $date = \date('H:i:s'); $this->appendToLogs($dbForProject, $deployment->getId(), $queueForRealtime, "[$date] [appwrite] Screenshot capturing failed. Deployment will continue. \n"); + $this->publishUsage( + project: $project, + site: $site, + publisherForUsage: $publisherForUsage, + metric: METRIC_SCREENSHOTS_FAILED + ); + throw $th; } } + 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 appendToLogs(Database $dbForProject, string $deploymentId, Realtime $queueForRealtime, string $logs) { $deployment = $dbForProject->getDocument('deployments', $deploymentId); diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Usage/Get.php b/src/Appwrite/Platform/Modules/Sites/Http/Usage/Get.php index a6768462d1..a1af4bd8fd 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Usage/Get.php @@ -87,6 +87,8 @@ 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), @@ -139,6 +141,9 @@ 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'], @@ -153,9 +158,12 @@ class Get extends Base 'executionsMbSecondsTotal' => $usage[$metrics[8]]['total'], 'buildsSuccessTotal' => $usage[$metrics[9]]['total'], 'buildsFailedTotal' => $usage[$metrics[10]]['total'], - 'requestsTotal' => $usage[$metrics[11]]['total'], - 'inboundTotal' => $usage[$metrics[12]]['total'], - 'outboundTotal' => $usage[$metrics[13]]['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'], 'deployments' => $usage[$metrics[0]]['data'], 'deploymentsStorage' => $usage[$metrics[1]]['data'], 'builds' => $usage[$metrics[2]]['data'], @@ -167,9 +175,11 @@ class Get extends Base 'executionsMbSeconds' => $usage[$metrics[8]]['data'], 'buildsSuccess' => $usage[$metrics[9]]['data'], 'buildsFailed' => $usage[$metrics[10]]['data'], - 'requests' => $usage[$metrics[11]]['data'], - 'inbound' => $usage[$metrics[12]]['data'], - 'outbound' => $usage[$metrics[13]]['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'], ]), 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 a90cb0cab9..3b3c759fd5 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Usage/XList.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Usage/XList.php @@ -74,6 +74,8 @@ 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, @@ -122,6 +124,10 @@ 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'], @@ -136,9 +142,12 @@ class XList extends Base 'executionsMbSecondsTotal' => $usage[$metrics[9]]['total'], 'buildsSuccessTotal' => $usage[$metrics[10]]['total'], 'buildsFailedTotal' => $usage[$metrics[11]]['total'], - 'requestsTotal' => $usage[$metrics[12]]['total'], - 'inboundTotal' => $usage[$metrics[13]]['total'], - 'outboundTotal' => $usage[$metrics[14]]['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'], 'sites' => $usage[$metrics[0]]['data'], 'deployments' => $usage[$metrics[1]]['data'], 'deploymentsStorage' => $usage[$metrics[2]]['data'], @@ -151,9 +160,11 @@ class XList extends Base 'executionsMbSeconds' => $usage[$metrics[9]]['data'], 'buildsSuccess' => $usage[$metrics[10]]['data'], 'buildsFailed' => $usage[$metrics[11]]['data'], - 'requests' => $usage[$metrics[12]]['data'], - 'inbound' => $usage[$metrics[13]]['data'], - 'outbound' => $usage[$metrics[14]]['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'], ]), Response::MODEL_USAGE_SITES); } } diff --git a/src/Appwrite/Utopia/Response/Model/UsageSite.php b/src/Appwrite/Utopia/Response/Model/UsageSite.php index c45dc831cd..27828426d3 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageSite.php +++ b/src/Appwrite/Utopia/Response/Model/UsageSite.php @@ -49,6 +49,38 @@ class UsageSite extends UsageFunction 'example' => [], 'array' => true ]) + ->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 + ]) ; } diff --git a/src/Appwrite/Utopia/Response/Model/UsageSites.php b/src/Appwrite/Utopia/Response/Model/UsageSites.php index fea87c7718..241e08e6ba 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageSites.php +++ b/src/Appwrite/Utopia/Response/Model/UsageSites.php @@ -122,6 +122,38 @@ class UsageSites extends Model 'example' => [], 'array' => true ]) + ->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('deployments', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated number of sites deployment per period.', diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index f6eb963967..0d2c0a7ed7 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -1675,11 +1675,14 @@ class UsageTest extends Scope ); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(30, count($response['body'])); + $this->assertEquals(35, 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']); @@ -1692,6 +1695,8 @@ 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']); @@ -1709,7 +1714,7 @@ class UsageTest extends Scope ); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(31, count($response['body'])); + $this->assertEquals(36, count($response['body'])); $this->assertEquals($response['body']['range'], '30d'); $this->assertIsArray($response['body']['sites']); $this->assertIsArray($response['body']['deployments']); @@ -1722,6 +1727,11 @@ 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']); From 37540aa4f5448009525de189d1e4bda98440bb65 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Wed, 15 Apr 2026 11:52:39 +0530 Subject: [PATCH 2/5] addressed comments --- .../Modules/Functions/Workers/Screenshots.php | 30 +++-- .../Utopia/Response/Model/UsageSite.php | 64 +++++----- .../Utopia/Response/Model/UsageSites.php | 116 +++++++++--------- 3 files changed, 107 insertions(+), 103 deletions(-) diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php index fa7e394710..dbd0e217c9 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php @@ -62,6 +62,7 @@ class Screenshots extends Action Console::log('Screenshot action started'); $payload = $message->getPayload() ?? []; + $screenshotCompleted = false; if (empty($payload)) { throw new \Exception('Missing payload'); @@ -262,13 +263,7 @@ class Screenshots extends Action 'deploymentScreenshotDark' => $deployment->getAttribute('screenshotDark', ''), 'deploymentScreenshotLight' => $deployment->getAttribute('screenshotLight', ''), ])); - - $this->publishUsage( - project: $project, - site: $site, - publisherForUsage: $publisherForUsage, - metric: METRIC_SCREENSHOTS_SUCCESS - ); + $screenshotCompleted = true; } catch (\Throwable $th) { Console::warning("Screenshot failed to generate:"); Console::warning($th->getMessage()); @@ -277,15 +272,24 @@ class Screenshots extends Action $date = \date('H:i:s'); $this->appendToLogs($dbForProject, $deployment->getId(), $queueForRealtime, "[$date] [appwrite] Screenshot capturing failed. Deployment will continue. \n"); - $this->publishUsage( - project: $project, - site: $site, - publisherForUsage: $publisherForUsage, - metric: METRIC_SCREENSHOTS_FAILED - ); + if (!$screenshotCompleted) { + $this->publishUsage( + project: $project, + site: $site, + publisherForUsage: $publisherForUsage, + metric: METRIC_SCREENSHOTS_FAILED + ); + } throw $th; } + + $this->publishUsage( + project: $project, + site: $site, + publisherForUsage: $publisherForUsage, + metric: METRIC_SCREENSHOTS_SUCCESS + ); } protected function publishUsage( diff --git a/src/Appwrite/Utopia/Response/Model/UsageSite.php b/src/Appwrite/Utopia/Response/Model/UsageSite.php index 27828426d3..af41a34639 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageSite.php +++ b/src/Appwrite/Utopia/Response/Model/UsageSite.php @@ -10,6 +10,38 @@ 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.', @@ -49,38 +81,6 @@ class UsageSite extends UsageFunction 'example' => [], 'array' => true ]) - ->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 - ]) ; } diff --git a/src/Appwrite/Utopia/Response/Model/UsageSites.php b/src/Appwrite/Utopia/Response/Model/UsageSites.php index 241e08e6ba..94ee6e645f 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageSites.php +++ b/src/Appwrite/Utopia/Response/Model/UsageSites.php @@ -83,6 +83,36 @@ 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.', @@ -122,38 +152,6 @@ class UsageSites extends Model 'example' => [], 'array' => true ]) - ->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('deployments', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated number of sites deployment per period.', @@ -168,18 +166,6 @@ 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.', @@ -208,6 +194,34 @@ 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.', @@ -229,20 +243,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 - ]) ; } From 23233d0dcb2b9550e56d1cc2f6dc9cf47888aef5 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Wed, 15 Apr 2026 11:59:02 +0530 Subject: [PATCH 3/5] add try catch --- .../Modules/Functions/Workers/Screenshots.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php index dbd0e217c9..d1f2b0d0bf 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php @@ -273,12 +273,16 @@ class Screenshots extends Action $this->appendToLogs($dbForProject, $deployment->getId(), $queueForRealtime, "[$date] [appwrite] Screenshot capturing failed. Deployment will continue. \n"); if (!$screenshotCompleted) { - $this->publishUsage( - project: $project, - site: $site, - publisherForUsage: $publisherForUsage, - metric: METRIC_SCREENSHOTS_FAILED - ); + 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. + } } throw $th; From 730c62bda60cbb32da196c01b01c7ac4d6c98c22 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Wed, 15 Apr 2026 18:35:09 +0530 Subject: [PATCH 4/5] 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']); From 93b9500a95af55447e438c2b04fadfd2e2a172e2 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Thu, 16 Apr 2026 15:22:45 +0530 Subject: [PATCH 5/5] align it with cloud pattern --- .../Modules/Functions/Workers/Screenshots.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php index 0cb42822b3..8fed46aa00 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php @@ -21,6 +21,7 @@ use Utopia\Queue\Message; use Utopia\Storage\Device; use Utopia\System\System; use Utopia\Telemetry\Adapter as Telemetry; +use Utopia\Telemetry\Counter; use function Swoole\Coroutine\batch; @@ -67,6 +68,7 @@ class Screenshots extends Action } $screenshotMessage = Screenshot::fromArray($payload); + $counter = $telemetry->createCounter('worker.screenshots.capture'); Console::log('Site screenshot started'); @@ -271,23 +273,21 @@ class Screenshots extends Action $date = \date('H:i:s'); $this->appendToLogs($dbForProject, $deployment->getId(), $queueForRealtime, "[$date] [appwrite] Screenshot capturing failed. Deployment will continue. \n"); - $this->recordTelemetry($telemetry, 'failure'); + $this->recordTelemetry($counter, 'failure'); throw $th; } - $this->recordTelemetry($telemetry, 'success'); + $this->recordTelemetry($counter, 'success'); } - protected function recordTelemetry(Telemetry $telemetry, string $result): void + protected function recordTelemetry(Counter $counter, string $result): void { try { - $telemetry - ->createCounter('worker.screenshots.capture') - ->add(1, [ - 'resourceType' => RESOURCE_TYPE_SITES, - 'result' => $result, - ]); + $counter->add(1, [ + 'resourceType' => RESOURCE_TYPE_SITES, + 'result' => $result, + ]); } catch (\Throwable) { // Telemetry should never affect screenshot processing. }