From f149ba33d45f98ce8d8fa17239a99b1376900f26 Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Mon, 8 Dec 2025 20:27:30 +0530 Subject: [PATCH] updated stats for vectordb --- app/controllers/api/project.php | 24 +++- app/controllers/shared/api.php | 1 + app/init/constants.php | 27 ++++- composer.lock | 2 +- .../Databases/Http/Databases/Action.php | 2 +- .../Collections/Documents/Action.php | 2 + .../Databases/Http/Databases/Usage/Get.php | 1 + .../Databases/Http/Databases/Usage/XList.php | 1 + .../Http/VectorDB/Collections/Usage/Get.php | 5 + .../Http/VectorDB/Embeddings/Text/Create.php | 41 ++----- .../Databases/Http/VectorDB/Usage/Get.php | 7 +- .../Databases/Http/VectorDB/Usage/XList.php | 7 +- src/Appwrite/Platform/Workers/Migrations.php | 2 + .../Platform/Workers/StatsResources.php | 18 ++- src/Appwrite/Utopia/Response.php | 6 + .../Utopia/Response/Model/UsageProject.php | 97 ++++++++++++++-- .../Utopia/Response/Model/UsageVectorDB.php | 96 +++++++++++++++ .../Utopia/Response/Model/UsageVectorDBs.php | 109 ++++++++++++++++++ tests/e2e/General/UsageTest.php | 13 +-- .../VectorDB/DatabasesConsoleClientTest.php | 2 +- .../VectorDB/DatabasesCustomServerTest.php | 6 +- 21 files changed, 400 insertions(+), 69 deletions(-) create mode 100644 src/Appwrite/Utopia/Response/Model/UsageVectorDB.php create mode 100644 src/Appwrite/Utopia/Response/Model/UsageVectorDBs.php diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index 2d17ccbafb..ae1f9041a7 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -76,6 +76,14 @@ App::get('/v1/project/usage') METRIC_DATABASES_OPERATIONS_WRITES, METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB, METRIC_FILES_IMAGES_TRANSFORMED, + // VectorDB totals + METRIC_DATABASES_VECTORDB, + METRIC_COLLECTIONS_VECTORDB, + METRIC_DOCUMENTS_VECTORDB, + METRIC_DATABASES_STORAGE_VECTORDB, + METRIC_DATABASES_OPERATIONS_READS_VECTORDB, + METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB, + // Embeddings totals METRIC_EMBEDDINGS_TEXT, METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS, METRIC_EMBEDDINGS_TEXT_TOTAL_DURATION, @@ -96,6 +104,14 @@ App::get('/v1/project/usage') METRIC_DATABASES_OPERATIONS_WRITES, METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB, METRIC_FILES_IMAGES_TRANSFORMED, + // VectorDB time series + METRIC_DATABASES_VECTORDB, + METRIC_COLLECTIONS_VECTORDB, + METRIC_DOCUMENTS_VECTORDB, + METRIC_DATABASES_STORAGE_VECTORDB, + METRIC_DATABASES_OPERATIONS_READS_VECTORDB, + METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB, + // Embeddings time series METRIC_EMBEDDINGS_TEXT, METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS, METRIC_EMBEDDINGS_TEXT_TOTAL_DURATION, @@ -403,10 +419,10 @@ App::get('/v1/project/usage') 'authPhoneCountryBreakdown' => $authPhoneCountryBreakdown, 'imageTransformations' => $usage[METRIC_FILES_IMAGES_TRANSFORMED], 'imageTransformationsTotal' => $total[METRIC_FILES_IMAGES_TRANSFORMED], - 'embeddingsText' => $usage[METRIC_EMBEDDINGS_TEXT] ?? [], - 'embeddingsTextTokens' => $usage[METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS] ?? [], - 'embeddingsTextDuration' => $usage[METRIC_EMBEDDINGS_TEXT_TOTAL_DURATION] ?? [], - 'embeddingsTextErrors' => $usage[METRIC_EMBEDDINGS_TEXT_TOTAL_ERROR] ?? [], + 'embeddingsText' => $total[METRIC_EMBEDDINGS_TEXT] ?? [], + 'embeddingsTextTokens' => $total[METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS], + 'embeddingsTextDuration' => $total[METRIC_EMBEDDINGS_TEXT_TOTAL_DURATION], + 'embeddingsTextErrors' => $total[METRIC_EMBEDDINGS_TEXT_TOTAL_ERROR], ]), Response::MODEL_USAGE_PROJECT); }); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index cfb43ce5e7..dea8bd6f42 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -529,6 +529,7 @@ App::init() $path = $route->getMatchedPath(); $databaseType = match (true) { str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB, + str_contains($path, '/vectordb') => DATABASE_TYPE_VECTORDB, default => '', }; diff --git a/app/init/constants.php b/app/init/constants.php index 02576c6478..c8fd7db64f 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -280,6 +280,29 @@ const METRIC_DATABASE_ID_OPERATIONS_READS_DOCUMENTSDB = 'documentsdb.{databaseIn const METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB = 'documentsdb.databases.operations.writes'; const METRIC_DATABASE_ID_OPERATIONS_WRITES_DOCUMENTSDB = 'documentsdb.{databaseInternalId}.databases.operations.writes'; +// vectordb +const METRIC_DATABASES_VECTORDB = 'vectordb.databases'; +const METRIC_COLLECTIONS_VECTORDB = 'vectordb.collections'; +const METRIC_DATABASES_STORAGE_VECTORDB = 'vectordb.databases.storage'; +const METRIC_DATABASE_ID_COLLECTIONS_VECTORDB = 'vectordb.{databaseInternalId}.collections'; +const METRIC_DATABASE_ID_STORAGE_VECTORDB = 'vectordb.{databaseInternalId}.databases.storage'; +const METRIC_DOCUMENTS_VECTORDB = 'vectordb.documents'; +const METRIC_DATABASE_ID_DOCUMENTS_VECTORDB = 'vectordb.{databaseInternalId}.documents'; +const METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS_VECTORDB = 'vectordb.{databaseInternalId}.{collectionInternalId}.documents'; +const METRIC_DATABASE_ID_COLLECTION_ID_STORAGE_VECTORDB = 'vectordb.{databaseInternalId}.{collectionInternalId}.databases.storage'; +const METRIC_DATABASES_OPERATIONS_READS_VECTORDB = 'vectordb.databases.operations.reads'; +const METRIC_DATABASE_ID_OPERATIONS_READS_VECTORDB = 'vectordb.{databaseInternalId}.databases.operations.reads'; +const METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB = 'vectordb.databases.operations.writes'; +const METRIC_DATABASE_ID_OPERATIONS_WRITES_VECTORDB = 'vectordb.{databaseInternalId}.databases.operations.writes'; +const METRIC_EMBEDDINGS_TEXT = 'embeddings.text'; +const METRIC_EMBEDDINGS_MODEL_TEXT = 'embeddings.text.{embeddingModel}'; +const METRIC_EMBEDDINGS_TEXT_TOTAL_ERROR = 'embeddings.text.totalErrors'; +const METRIC_EMBEDDINGS_MODEL_TEXT_TOTAL_ERROR = 'embeddings.text.{embeddingModel}.totalErrors'; +const METRIC_EMBEDDINGS_TEXT_TOTAL_DURATION = 'embeddings.text.totalDuration'; +const METRIC_EMBEDDINGS_MODEL_TEXT_TOTAL_DURATION = 'embeddings.text.{embeddingModel}.totalDuration'; +const METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS = 'embeddings.text.totalTokens'; +const METRIC_EMBEDDINGS_MODEL_TEXT_TOTAL_TOKENS = 'embeddings.text.{embeddingModel}.totalTokens'; + const METRIC_BUCKETS = 'buckets'; const METRIC_FILES = 'files'; const METRIC_FILES_STORAGE = 'files.storage'; @@ -353,10 +376,6 @@ const METRIC_SITES_ID_OUTBOUND = 'sites.{siteInternalId}.outbound'; const METRIC_AVATARS_SCREENSHOTS_GENERATED = 'avatars.screenshotsGenerated'; const METRIC_FUNCTIONS_RUNTIME = 'functions.runtimes.{runtime}'; const METRIC_SITES_FRAMEWORK = 'sites.frameworks.{framework}'; -const METRIC_EMBEDDINGS_TEXT = 'embeddings.text.{embeddingModel}'; -const METRIC_EMBEDDINGS_TEXT_TOTAL_ERROR = 'embeddings.text.{embeddingModel}.totalErrors'; -const METRIC_EMBEDDINGS_TEXT_TOTAL_DURATION = 'embeddings.text.{embeddingModel}.totalDuration'; -const METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS = 'embeddings.text.{embeddingModel}.totalTokens'; // Resource types const RESOURCE_TYPE_PROJECTS = 'projects'; diff --git a/composer.lock b/composer.lock index 065713e446..ad58e5406b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "86c19fdb3d6a9faf68a310d96def667f", + "content-hash": "4a44da365c2e5b931f007f72437144dc", "packages": [ { "name": "adhocore/jwt", diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php index 0347d4365b..3411e06b27 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php @@ -26,7 +26,7 @@ class Action extends AppwriteAction $this->context = DATABASE_TYPE_DOCUMENTSDB; } if (\str_contains($path, '/vectordb')) { - $this->context = 'vectordb'; + $this->context = DATABASE_TYPE_VECTORDB; } return parent::setHttpPath($path); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php index b6f95dd27c..83862f8ba8 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php @@ -28,6 +28,8 @@ abstract class Action extends DatabasesAction $this->context = ROWS; } elseif (str_contains($path, '/documentsdb/')) { $this->databaseType = DATABASE_TYPE_DOCUMENTSDB; + } elseif (str_contains($path, '/vectordb/')) { + $this->databaseType = DATABASE_TYPE_VECTORDB; } $contextId = '$' . $this->getCollectionsEventsContext() . 'Id'; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php index 45a36a859d..00dc62a9d3 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php @@ -32,6 +32,7 @@ class Get extends Action { $this->databaseType = match (true) { str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB, + str_contains($path, '/vectordb') => DATABASE_TYPE_VECTORDB, default => DATABASE_TYPE_LEGACY, }; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/XList.php index 5e244bb3d7..70f1792971 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/XList.php @@ -30,6 +30,7 @@ class XList extends Action { $this->databaseType = match (true) { str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB, + str_contains($path, '/vectordb') => DATABASE_TYPE_VECTORDB, default => DATABASE_TYPE_LEGACY, }; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Usage/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Usage/Get.php index 2e26e9d6b5..00a5eedfb8 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Usage/Get.php @@ -24,6 +24,11 @@ class Get extends CollectionUsageGet return UtopiaResponse::MODEL_USAGE_COLLECTION; } + protected function getMetric(): string + { + return METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS_VECTORDB; + } + public function __construct() { $this diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Embeddings/Text/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Embeddings/Text/Create.php index ba6a4c9a22..c6c058408a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Embeddings/Text/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Embeddings/Text/Create.php @@ -141,39 +141,16 @@ class Create extends CreateDocumentAction ->dynamic($embeddings, $this->getBulkResponseModel()); $queueForStatsUsage - ->addMetric( - \str_replace( - '{embeddingModel}', - $model, - METRIC_EMBEDDINGS_TEXT - ), - \count($texts) - ) - ->addMetric( - \str_replace( - '{embeddingModel}', - $model, - METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS - ), - $totalTokens - ) - ->addMetric( - \str_replace( - '{embeddingModel}', - $model, - METRIC_EMBEDDINGS_TEXT_TOTAL_DURATION - ), - $totalDuration - ) - ->addMetric( - \str_replace( - '{embeddingModel}', - $model, - METRIC_EMBEDDINGS_TEXT_TOTAL_ERROR - ), - $totalErrors - ) + ->addMetric(METRIC_EMBEDDINGS_TEXT, \count($texts)) + ->addMetric(\str_replace('{embeddingModel}', $model, METRIC_EMBEDDINGS_MODEL_TEXT), \count($texts)) + ->addMetric(METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS, $totalTokens) + ->addMetric(\str_replace('{embeddingModel}', $model, METRIC_EMBEDDINGS_MODEL_TEXT_TOTAL_TOKENS), $totalTokens) + ->addMetric(METRIC_EMBEDDINGS_TEXT_TOTAL_DURATION, $totalDuration) + ->addMetric(\str_replace('{embeddingModel}', $model, METRIC_EMBEDDINGS_MODEL_TEXT_TOTAL_DURATION), $totalDuration) + ->addMetric(METRIC_EMBEDDINGS_TEXT_TOTAL_ERROR, $totalErrors) + ->addMetric(\str_replace('{embeddingModel}', $model, METRIC_EMBEDDINGS_MODEL_TEXT_TOTAL_ERROR), $totalErrors) ->trigger(); + $queueForStatsUsage->reset(); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/Get.php index 075837b9cb..5508a9dc91 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/Get.php @@ -19,6 +19,11 @@ class Get extends DatabaseUsageGet return 'getVectorDBUsage'; } + public function getResponseModel(): string + { + return UtopiaResponse::MODEL_USAGE_VECTORDB; + } + public function __construct() { $this @@ -38,7 +43,7 @@ class Get extends DatabaseUsageGet responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_USAGE_DATABASE, + model: UtopiaResponse::MODEL_USAGE_VECTORDB, ) ], contentType: ContentType::JSON, diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/XList.php index fe6ed3622b..3201864b50 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/XList.php @@ -18,6 +18,11 @@ class XList extends DatabaseUsageXList return 'listVectorDBUsage'; } + public function getResponseModel(): string + { + return UtopiaResponse::MODEL_USAGE_VECTORDBS; + } + public function __construct() { $this @@ -37,7 +42,7 @@ class XList extends DatabaseUsageXList responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_USAGE_DATABASES, + model: UtopiaResponse::MODEL_USAGE_VECTORDBS, ) ], contentType: ContentType::JSON diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 836cbbc9c8..266eabb4f3 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -288,6 +288,8 @@ class Migrations extends Action METRIC_DATABASES_OPERATIONS_WRITES, METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB, METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB, + METRIC_DATABASES_OPERATIONS_READS_VECTORDB, + METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB, METRIC_NETWORK_REQUESTS, METRIC_NETWORK_INBOUND, METRIC_NETWORK_OUTBOUND, diff --git a/src/Appwrite/Platform/Workers/StatsResources.php b/src/Appwrite/Platform/Workers/StatsResources.php index b745fac367..dabda146dc 100644 --- a/src/Appwrite/Platform/Workers/StatsResources.php +++ b/src/Appwrite/Platform/Workers/StatsResources.php @@ -125,6 +125,7 @@ class StatsResources extends Action $databases = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_LEGACY, DATABASE_TYPE_TABLESDB])]); $documentsdb = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_DOCUMENTSDB])]); + $vectordb = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_VECTORDB])]); $buckets = $dbForProject->count('buckets'); $users = $dbForProject->count('users'); @@ -160,6 +161,7 @@ class StatsResources extends Action $metrics = [ METRIC_DATABASES => $databases, METRIC_DATABASES_DOCUMENTSDB => $documentsdb, + METRIC_DATABASES_VECTORDB => $vectordb, METRIC_BUCKETS => $buckets, METRIC_USERS => $users, METRIC_FUNCTIONS => $functions, @@ -268,8 +270,13 @@ class StatsResources extends Action $totalDocumentsDocumentsdb = 0; $totalDatabaseStorageDocumentsdb = 0; + // vectordb + $totalCollectionsVectordb = 0; + $totalDocumentsVectordb = 0; + $totalDatabaseStorageVectordb = 0; - $this->foreachDocument($dbForProject, 'databases', [], function ($database) use ($dbForProject, $getDatabasesDB, $region, &$totalCollections, &$totalDocuments, &$totalDatabaseStorage, &$totalCollectionsDocumentsdb, &$totalDocumentsDocumentsdb, &$totalDatabaseStorageDocumentsdb) { + + $this->foreachDocument($dbForProject, 'databases', [], function ($database) use ($dbForProject, $getDatabasesDB, $region, &$totalCollections, &$totalDocuments, &$totalDatabaseStorage, &$totalCollectionsDocumentsdb, &$totalDocumentsDocumentsdb, &$totalDatabaseStorageDocumentsdb, &$totalCollectionsVectordb, &$totalDocumentsVectordb, &$totalDatabaseStorageVectordb) { $dbForDatabases = $getDatabasesDB($database); $collections = $dbForProject->count('database_' . $database->getSequence()); @@ -289,6 +296,11 @@ class StatsResources extends Action $totalDocumentsDocumentsdb += $documents; $totalCollectionsDocumentsdb += $collections; break; + case DATABASE_TYPE_VECTORDB: + $totalDatabaseStorageVectordb += $storage; + $totalDocumentsVectordb += $documents; + $totalCollectionsVectordb += $collections; + break; default: $totalDatabaseStorage += $storage; $totalDocuments += $documents; @@ -303,6 +315,10 @@ class StatsResources extends Action $this->createStatsDocuments($region, METRIC_COLLECTIONS_DOCUMENTSDB, $totalCollectionsDocumentsdb); $this->createStatsDocuments($region, METRIC_DOCUMENTS_DOCUMENTSDB, $totalDocumentsDocumentsdb); $this->createStatsDocuments($region, METRIC_DATABASES_STORAGE_DOCUMENTSDB, $totalDatabaseStorageDocumentsdb); + + $this->createStatsDocuments($region, METRIC_COLLECTIONS_VECTORDB, $totalCollectionsVectordb); + $this->createStatsDocuments($region, METRIC_DOCUMENTS_VECTORDB, $totalDocumentsVectordb); + $this->createStatsDocuments($region, METRIC_DATABASES_STORAGE_VECTORDB, $totalDatabaseStorageVectordb); } protected function countForCollections(Database $dbForProject, Database $dbForDatabases, Document $database, string $region): array { diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 80c7060b9a..1843e695cd 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -145,6 +145,8 @@ use Appwrite\Utopia\Response\Model\UsageSites; use Appwrite\Utopia\Response\Model\UsageStorage; use Appwrite\Utopia\Response\Model\UsageTable; use Appwrite\Utopia\Response\Model\UsageUsers; +use Appwrite\Utopia\Response\Model\UsageVectorDB; +use Appwrite\Utopia\Response\Model\UsageVectorDBs; use Appwrite\Utopia\Response\Model\User; use Appwrite\Utopia\Response\Model\Variable; use Appwrite\Utopia\Response\Model\VcsContent; @@ -179,6 +181,8 @@ class Response extends SwooleResponse public const MODEL_USAGE_DATABASE = 'usageDatabase'; public const MODEL_USAGE_DOCUMENTSDBS = 'usageDocumentsDBs'; public const MODEL_USAGE_DOCUMENTSDB = 'usageDocumentsDB'; + public const MODEL_USAGE_VECTORDBS = 'usageVectorDBs'; + public const MODEL_USAGE_VECTORDB = 'usageVectorDB'; public const MODEL_USAGE_TABLE = 'usageTable'; public const MODEL_USAGE_COLLECTION = 'usageCollection'; public const MODEL_USAGE_USERS = 'usageUsers'; @@ -618,6 +622,8 @@ class Response extends SwooleResponse ->setModel(new UsageDatabase()) ->setModel(new UsageDocumentsDBs()) ->setModel(new UsageDocumentsDB()) + ->setModel(new UsageVectorDBs()) + ->setModel(new UsageVectorDB()) ->setModel(new UsageTable()) ->setModel(new UsageCollection()) ->setModel(new UsageUsers()) diff --git a/src/Appwrite/Utopia/Response/Model/UsageProject.php b/src/Appwrite/Utopia/Response/Model/UsageProject.php index 02047265c7..a6ddf4abf0 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageProject.php +++ b/src/Appwrite/Utopia/Response/Model/UsageProject.php @@ -267,33 +267,108 @@ class UsageProject extends Model 'default' => 0, 'example' => 0, ]) - ->addRule('embeddingsText', [ + // VectorDB aggregates + ->addRule('vectordbDatabasesTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of VectorDB databases.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('vectordbCollectionsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of VectorDB collections.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('vectordbDocumentsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of VectorDB documents.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('vectordbDatabasesStorageTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated VectorDB storage (bytes).', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('vectordbDatabasesReadsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of VectorDB reads.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('vectordbDatabasesWritesTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of VectorDB writes.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('vectordbDatabases', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated number of text embedding calls per period.', + 'description' => 'Aggregated VectorDB databases per period.', 'default' => [], 'example' => [], 'array' => true ]) + ->addRule('vectordbCollections', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated VectorDB collections per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('vectordbDocuments', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated VectorDB documents per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('vectordbDatabasesStorage', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated VectorDB storage per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('vectordbDatabasesReads', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated VectorDB reads per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('vectordbDatabasesWrites', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated VectorDB writes per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('embeddingsText', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated number of text embedding calls per period.', + 'default' => 0, + 'example' => 0 + ]) ->addRule('embeddingsTextTokens', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated number of tokens processed by text embeddings per period.', - 'default' => [], - 'example' => [], - 'array' => true + 'default' => 0, + 'example' => 0 ]) ->addRule('embeddingsTextDuration', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated duration spent generating text embeddings per period.', - 'default' => [], - 'example' => [], - 'array' => true + 'default' => 0, + 'example' => 0 ]) ->addRule('embeddingsTextErrors', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated number of errors while generating text embeddings per period.', - 'default' => [], - 'example' => [], - 'array' => true + 'default' => 0, + 'example' => 0 ]) ; } diff --git a/src/Appwrite/Utopia/Response/Model/UsageVectorDB.php b/src/Appwrite/Utopia/Response/Model/UsageVectorDB.php new file mode 100644 index 0000000000..a90f593c7e --- /dev/null +++ b/src/Appwrite/Utopia/Response/Model/UsageVectorDB.php @@ -0,0 +1,96 @@ +addRule('range', [ + 'type' => self::TYPE_STRING, + 'description' => 'Time range of the usage stats.', + 'default' => '', + 'example' => '30d', + ]) + ->addRule('collectionsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of collections.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('documentsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of documents.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('storageTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated storage used in bytes.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('databaseReadsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total number of database reads.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('databaseWritesTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total number of database writes.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('collections', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated number of collections per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('documents', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated number of documents per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('storage', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated storage used in bytes per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('databaseReads', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'An array of aggregated number of database reads.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('databaseWrites', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'An array of aggregated number of database writes.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ; + } + + public function getName(): string + { + return 'UsageVectorDB'; + } + + public function getType(): string + { + return Response::MODEL_USAGE_VECTORDB; + } +} diff --git a/src/Appwrite/Utopia/Response/Model/UsageVectorDBs.php b/src/Appwrite/Utopia/Response/Model/UsageVectorDBs.php new file mode 100644 index 0000000000..da63120c5c --- /dev/null +++ b/src/Appwrite/Utopia/Response/Model/UsageVectorDBs.php @@ -0,0 +1,109 @@ +addRule('range', [ + 'type' => self::TYPE_STRING, + 'description' => 'Time range of the usage stats.', + 'default' => '', + 'example' => '30d', + ]) + ->addRule('databasesTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of VectorDB databases.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('collectionsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of collections.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('documentsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated number of documents.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('storageTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total aggregated storage in bytes.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('databasesReadsTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total number of database reads.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('databasesWritesTotal', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Total number of database writes.', + 'default' => 0, + 'example' => 0, + ]) + ->addRule('databases', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated number of databases per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('collections', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated number of collections per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('documents', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated number of documents per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('storage', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'Aggregated storage in bytes per period.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('databasesReads', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'An array of aggregated number of database reads.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ->addRule('databasesWrites', [ + 'type' => Response::MODEL_METRIC, + 'description' => 'An array of aggregated number of database writes.', + 'default' => [], + 'example' => [], + 'array' => true + ]) + ; + } + + public function getName(): string + { + return 'UsageVectorDBs'; + } + + public function getType(): string + { + return Response::MODEL_USAGE_VECTORDBS; + } +} diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index ad5cb1414e..7660861347 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -1646,15 +1646,10 @@ class UsageTest extends Scope $this->assertArrayHasKey('embeddingsTextErrors', $response['body']); $this->assertArrayHasKey('embeddingsTextTokens', $response['body']); $this->assertArrayHasKey('embeddingsTextDuration', $response['body']); - $this->assertGreaterThanOrEqual(0, count($response['body']['embeddingsText'])); - $this->assertGreaterThanOrEqual(0, count($response['body']['embeddingsTextErrors'])); - $this->assertGreaterThanOrEqual(0, count($response['body']['embeddingsTextTokens'])); - $this->assertGreaterThanOrEqual(0, count($response['body']['embeddingsTextDuration'])); - - $this->validateDates($response['body']['embeddingsText']); - $this->validateDates($response['body']['embeddingsTextErrors']); - $this->validateDates($response['body']['embeddingsTextTokens']); - $this->validateDates($response['body']['embeddingsTextDuration']); + $this->assertGreaterThan(0, $response['body']['embeddingsText']); + $this->assertGreaterThanOrEqual(0, $response['body']['embeddingsTextErrors']); + $this->assertGreaterThan(0, $response['body']['embeddingsTextTokens']); + $this->assertGreaterThan(0, $response['body']['embeddingsTextDuration']); }); } diff --git a/tests/e2e/Services/Databases/VectorDB/DatabasesConsoleClientTest.php b/tests/e2e/Services/Databases/VectorDB/DatabasesConsoleClientTest.php index 8d711e68a5..8ca4822e68 100644 --- a/tests/e2e/Services/Databases/VectorDB/DatabasesConsoleClientTest.php +++ b/tests/e2e/Services/Databases/VectorDB/DatabasesConsoleClientTest.php @@ -226,7 +226,7 @@ class DatabasesConsoleClientTest extends Scope ]); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(15, count($response['body'])); + $this->assertEquals(11, count($response['body'])); $this->assertEquals('24h', $response['body']['range']); $this->assertIsNumeric($response['body']['documentsTotal']); $this->assertIsNumeric($response['body']['collectionsTotal']); diff --git a/tests/e2e/Services/Databases/VectorDB/DatabasesCustomServerTest.php b/tests/e2e/Services/Databases/VectorDB/DatabasesCustomServerTest.php index 7f6aeeccbd..58cb48440e 100644 --- a/tests/e2e/Services/Databases/VectorDB/DatabasesCustomServerTest.php +++ b/tests/e2e/Services/Databases/VectorDB/DatabasesCustomServerTest.php @@ -594,7 +594,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ], [ - 'embeddingModel' => 'embeddinggemma', + 'model' => 'embeddinggemma', 'texts' => [ 'hello world', 'second sentence', @@ -627,7 +627,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ], [ - 'embeddingModel' => 'embeddinggemma', + 'model' => 'embeddinggemma', 'texts' => [ 'valid text', 123, // invalid, not a string @@ -641,7 +641,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ], [ - 'embeddingModel' => 'nonexistent-model', + 'model' => 'nonexistent-model', 'texts' => ['hello'], ]); $this->assertEquals(400, $unknownModel['headers']['status-code']);