diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index b3e8196ccb..c428943c5f 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -2386,124 +2386,6 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu $response->noContent(); }); -App::get('/v1/databases/usage') - ->desc('Get usage stats for the database') - ->groups(['api', 'database']) - ->label('scope', 'collections.read') - ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) - ->label('sdk.namespace', 'databases') - ->label('sdk.method', 'getUsage') - ->label('sdk.response.code', Response::STATUS_CODE_OK) - ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) - ->label('sdk.response.model', Response::MODEL_USAGE_DATABASES) - ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), '`Date range.', true) - ->inject('response') - ->inject('dbForProject') - ->action(function (string $range, Response $response, Database $dbForProject) { - - // $usage = []; - // if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') { - // $periods = [ - // '24h' => [ - // 'period' => '1h', - // 'limit' => 24, - // ], - // '7d' => [ - // 'period' => '1d', - // 'limit' => 7, - // ], - // '30d' => [ - // 'period' => '1d', - // 'limit' => 30, - // ], - // '90d' => [ - // 'period' => '1d', - // 'limit' => 90, - // ], - // ]; - - // $metrics = [ - // 'databases.$all.count.total', - // 'documents.$all.count.total', - // 'collections.$all.count.total', - // 'databases.$all.requests.create', - // 'databases.$all.requests.read', - // 'databases.$all.requests.update', - // 'databases.$all.requests.delete', - // 'collections.$all.requests.create', - // 'collections.$all.requests.read', - // 'collections.$all.requests.update', - // 'collections.$all.requests.delete', - // 'documents.$all.requests.create', - // 'documents.$all.requests.read', - // 'documents.$all.requests.update', - // 'documents.$all.requests.delete' - // ]; - - // $stats = []; - - // Authorization::skip(function () use ($dbForProject, $periods, $range, $metrics, &$stats) { - // foreach ($metrics as $metric) { - // $limit = $periods[$range]['limit']; - // $period = $periods[$range]['period']; - - // $requestDocs = $dbForProject->find('stats', [ - // Query::equal('period', [$period]), - // Query::equal('metric', [$metric]), - // Query::limit($limit), - // Query::orderDesc('time'), - // ]); - - // $stats[$metric] = []; - // foreach ($requestDocs as $requestDoc) { - // $stats[$metric][] = [ - // 'value' => $requestDoc->getAttribute('value'), - // 'date' => $requestDoc->getAttribute('time'), - // ]; - // } - - // // backfill metrics with empty values for graphs - // $backfill = $limit - \count($requestDocs); - // while ($backfill > 0) { - // $last = $limit - $backfill - 1; // array index of last added metric - // $diff = match ($period) { // convert period to seconds for unix timestamp math - // '1h' => 3600, - // '1d' => 86400, - // }; - // $stats[$metric][] = [ - // 'value' => 0, - // 'date' => DateTime::formatTz(DateTime::addSeconds(new \DateTime($stats[$metric][$last]['date'] ?? null), -1 * $diff)), - // ]; - // $backfill--; - // } - // // Added 3'rd level to Index [period, metric, time] because of order by. - // $stats[$metric] = array_reverse($stats[$metric]); - // } - // }); - - // $usage = new Document([ - // 'range' => $range, - // 'databasesCount' => $stats['databases.$all.count.total'] ?? [], - // 'documentsCount' => $stats['documents.$all.count.total'] ?? [], - // 'collectionsCount' => $stats['collections.$all.count.total'] ?? [], - // 'documentsCreate' => $stats['documents.$all.requests.create'] ?? [], - // 'documentsRead' => $stats['documents.$all.requests.read'] ?? [], - // 'documentsUpdate' => $stats['documents.$all.requests.update'] ?? [], - // 'documentsDelete' => $stats['documents.$all.requests.delete'] ?? [], - // 'collectionsCreate' => $stats['collections.$all.requests.create'] ?? [], - // 'collectionsRead' => $stats['collections.$all.requests.read'] ?? [], - // 'collectionsUpdate' => $stats['collections.$all.requests.update'] ?? [], - // 'collectionsDelete' => $stats['collections.$all.requests.delete'] ?? [], - // 'databasesCreate' => $stats['databases.$all.requests.create'] ?? [], - // 'databasesRead' => $stats['databases.$all.requests.read'] ?? [], - // 'databasesUpdate' => $stats['databases.$all.requests.update'] ?? [], - // 'databasesDelete' => $stats['databases.$all.requests.delete'] ?? [], - // ]); - // } - - // $response->dynamic($usage, Response::MODEL_USAGE_DATABASES); - }); - App::get('/v1/databases/:databaseId/usage') ->desc('Get usage stats for the database') ->groups(['api', 'database']) @@ -2520,97 +2402,63 @@ App::get('/v1/databases/:databaseId/usage') ->inject('dbForProject') ->action(function (string $databaseId, string $range, Response $response, Database $dbForProject) { - // $usage = []; - // if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') { - // $periods = [ - // '24h' => [ - // 'period' => '1h', - // 'limit' => 24, - // ], - // '7d' => [ - // 'period' => '1d', - // 'limit' => 7, - // ], - // '30d' => [ - // 'period' => '1d', - // 'limit' => 30, - // ], - // '90d' => [ - // 'period' => '1d', - // 'limit' => 90, - // ], - // ]; + $database = $dbForProject->getDocument('databases', $databaseId); - // $metrics = [ - // 'collections.' . $databaseId . '.count.total', - // 'collections.' . $databaseId . '.requests.create', - // 'collections.' . $databaseId . '.requests.read', - // 'collections.' . $databaseId . '.requests.update', - // 'collections.' . $databaseId . '.requests.delete', - // 'documents.' . $databaseId . '.count.total', - // 'documents.' . $databaseId . '.requests.create', - // 'documents.' . $databaseId . '.requests.read', - // 'documents.' . $databaseId . '.requests.update', - // 'documents.' . $databaseId . '.requests.delete' - // ]; + if ($database->isEmpty()) { + throw new Exception(Exception::DATABASE_NOT_FOUND); + } - // $stats = []; + $periods = Config::getParam('usage', []); + $stats = $usage = []; + $days = $periods[$range]; + $metrics = [ + $database->getId() . '.collections', + $database->getId() . '.documents', + ]; - // Authorization::skip(function () use ($dbForProject, $periods, $range, $metrics, &$stats) { - // foreach ($metrics as $metric) { - // $limit = $periods[$range]['limit']; - // $period = $periods[$range]['period']; + Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + foreach ($metrics as $metric) { + $limit = $days['limit']; + $period = $days['period']; + $results = $dbForProject->find('stats', [ + Query::equal('period', [$period]), + Query::equal('metric', [$metric]), + Query::limit($limit), + Query::orderDesc('time'), + ]); + $stats[$metric] = []; + foreach ($results as $result) { + $stats[$metric][$result->getAttribute('time')] = [ + 'value' => $result->getAttribute('value'), + ]; + } + } + }); - // $requestDocs = $dbForProject->find('stats', [ - // Query::equal('period', [$period]), - // Query::equal('metric', [$metric]), - // Query::limit($limit), - // Query::orderDesc('time'), - // ]); + $format = match ($days['period']) { + '1h' => 'Y-m-d\TH:00:00.000P', + '1d' => 'Y-m-d\T00:00:00.000P', + }; - // $stats[$metric] = []; - // foreach ($requestDocs as $requestDoc) { - // $stats[$metric][] = [ - // 'value' => $requestDoc->getAttribute('value'), - // 'date' => $requestDoc->getAttribute('time'), - // ]; - // } + foreach ($metrics as $metric) { + $usage[$metric] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric][] = [ + 'value' => $stats[$metric][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } + $usage[$metric] = array_reverse($usage[$metric]); + } - // // backfill metrics with empty values for graphs - // $backfill = $limit - \count($requestDocs); - // while ($backfill > 0) { - // $last = $limit - $backfill - 1; // array index of last added metric - // $diff = match ($period) { // convert period to seconds for unix timestamp math - // '1h' => 3600, - // '1d' => 86400, - // }; - // $stats[$metric][] = [ - // 'value' => 0, - // 'date' => DateTime::formatTz(DateTime::addSeconds(new \DateTime($stats[$metric][$last]['date'] ?? null), -1 * $diff)), - // ]; - // $backfill--; - // } - // // TODO@kodumbeats explore performance if query is ordered by time ASC - // $stats[$metric] = array_reverse($stats[$metric]); - // } - // }); - - // $usage = new Document([ - // 'range' => $range, - // 'collectionsCount' => $stats["collections.{$databaseId}.count.total"] ?? [], - // 'collectionsCreate' => $stats["collections.{$databaseId}.requests.create"] ?? [], - // 'collectionsRead' => $stats["collections.{$databaseId}.requests.read"] ?? [], - // 'collectionsUpdate' => $stats["collections.{$databaseId}.requests.update"] ?? [], - // 'collectionsDelete' => $stats["collections.{$databaseId}.requests.delete"] ?? [], - // 'documentsCount' => $stats["documents.{$databaseId}.count.total"] ?? [], - // 'documentsCreate' => $stats["documents.{$databaseId}.requests.create"] ?? [], - // 'documentsRead' => $stats["documents.{$databaseId}.requests.read"] ?? [], - // 'documentsUpdate' => $stats["documents.{$databaseId}.requests.update"] ?? [], - // 'documentsDelete' => $stats["documents.{$databaseId}.requests.delete"] ?? [], - // ]); - // } - - // $response->dynamic($usage, Response::MODEL_USAGE_DATABASE); + $response->dynamic(new Document([ + 'range' => $range, + 'collectionsCount' => $usage[$metrics[0]], + 'documentsCount' => $usage[$metrics[1]], + ]), Response::MODEL_USAGE_DATABASE); }); App::get('/v1/databases/:databaseId/collections/:collectionId/usage') @@ -2631,93 +2479,132 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage') ->inject('dbForProject') ->action(function (string $databaseId, string $range, string $collectionId, Response $response, Database $dbForProject) { - // $database = $dbForProject->getDocument('databases', $databaseId); + $database = $dbForProject->getDocument('databases', $databaseId); - // $collectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId); - // $collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collectionDocument->getInternalId()); + $collectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId); + $collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collectionDocument->getInternalId()); - // if ($collection->isEmpty()) { - // throw new Exception(Exception::COLLECTION_NOT_FOUND); - // } + if ($collection->isEmpty()) { + throw new Exception(Exception::COLLECTION_NOT_FOUND); + } - // $usage = []; - // if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') { - // $periods = [ - // '24h' => [ - // 'period' => '1h', - // 'limit' => 24, - // ], - // '7d' => [ - // 'period' => '1d', - // 'limit' => 7, - // ], - // '30d' => [ - // 'period' => '1d', - // 'limit' => 30, - // ], - // '90d' => [ - // 'period' => '1d', - // 'limit' => 90, - // ], - // ]; + $periods = Config::getParam('usage', []); + $stats = $usage = []; + $days = $periods[$range]; + $metrics = [ + $collection->getId() . '.documents', + ]; - // $metrics = [ - // "documents.{$databaseId}/{$collectionId}.count.total", - // "documents.{$databaseId}/{$collectionId}.requests.create", - // "documents.{$databaseId}/{$collectionId}.requests.read", - // "documents.{$databaseId}/{$collectionId}.requests.update", - // "documents.{$databaseId}/{$collectionId}.requests.delete", - // ]; + Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + foreach ($metrics as $metric) { + $limit = $days['limit']; + $period = $days['period']; + $results = $dbForProject->find('stats', [ + Query::equal('period', [$period]), + Query::equal('metric', [$metric]), + Query::limit($limit), + Query::orderDesc('time'), + ]); + $stats[$metric] = []; + foreach ($results as $result) { + $stats[$metric][$result->getAttribute('time')] = [ + 'value' => $result->getAttribute('value'), + ]; + } + } + }); - // $stats = []; + $format = match ($days['period']) { + '1h' => 'Y-m-d\TH:00:00.000P', + '1d' => 'Y-m-d\T00:00:00.000P', + }; - // Authorization::skip(function () use ($dbForProject, $periods, $range, $metrics, &$stats) { - // foreach ($metrics as $metric) { - // $limit = $periods[$range]['limit']; - // $period = $periods[$range]['period']; + foreach ($metrics as $metric) { + $usage[$metric] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric][] = [ + 'value' => $stats[$metric][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } + $usage[$metric] = array_reverse($usage[$metric]); + } - // $requestDocs = $dbForProject->find('stats', [ - // Query::equal('period', [$period]), - // Query::equal('metric', [$metric]), - // Query::limit($limit), - // Query::orderDesc('time'), - // ]); - - // $stats[$metric] = []; - // foreach ($requestDocs as $requestDoc) { - // $stats[$metric][] = [ - // 'value' => $requestDoc->getAttribute('value'), - // 'date' => $requestDoc->getAttribute('time'), - // ]; - // } - - // // backfill metrics with empty values for graphs - // $backfill = $limit - \count($requestDocs); - // while ($backfill > 0) { - // $last = $limit - $backfill - 1; // array index of last added metric - // $diff = match ($period) { // convert period to seconds for unix timestamp math - // '1h' => 3600, - // '1d' => 86400, - // }; - // $stats[$metric][] = [ - // 'value' => 0, - // 'date' => DateTime::formatTz(DateTime::addSeconds(new \DateTime($stats[$metric][$last]['date'] ?? null), -1 * $diff)), - // ]; - // $backfill--; - // } - // $stats[$metric] = array_reverse($stats[$metric]); - // } - // }); - - // $usage = new Document([ - // 'range' => $range, - // 'documentsCount' => $stats["documents.{$databaseId}/{$collectionId}.count.total"] ?? [], - // 'documentsCreate' => $stats["documents.{$databaseId}/{$collectionId}.requests.create"] ?? [], - // 'documentsRead' => $stats["documents.{$databaseId}/{$collectionId}.requests.read"] ?? [], - // 'documentsUpdate' => $stats["documents.{$databaseId}/{$collectionId}.requests.update"] ?? [], - // 'documentsDelete' => $stats["documents.{$databaseId}/{$collectionId}.requests.delete" ?? []] - // ]); - // } - - // $response->dynamic($usage, Response::MODEL_USAGE_COLLECTION); + $response->dynamic(new Document([ + 'range' => $range, + 'documentsCount' => $usage[$metrics[0]], + ]), Response::MODEL_USAGE_COLLECTION); + }); + +App::get('/v1/databases/usage') + ->desc('Get usage stats for the database') + ->groups(['api', 'database']) + ->label('scope', 'collections.read') + ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) + ->label('sdk.namespace', 'databases') + ->label('sdk.method', 'getUsage') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_USAGE_DATABASES) + ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), '`Date range.', true) + ->inject('response') + ->inject('dbForProject') + ->action(function (string $range, Response $response, Database $dbForProject) { + + $periods = Config::getParam('usage', []); + $stats = $usage = []; + $days = $periods[$range]; + $metrics = [ + 'databases', + 'collections', + 'documents', + ]; + + Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + foreach ($metrics as $metric) { + $limit = $days['limit']; + $period = $days['period']; + $results = $dbForProject->find('stats', [ + Query::equal('period', [$period]), + Query::equal('metric', [$metric]), + Query::limit($limit), + Query::orderDesc('time'), + ]); + $stats[$metric] = []; + foreach ($results as $result) { + $stats[$metric][$result->getAttribute('time')] = [ + 'value' => $result->getAttribute('value'), + ]; + } + } + }); + + $format = match ($days['period']) { + '1h' => 'Y-m-d\TH:00:00.000P', + '1d' => 'Y-m-d\T00:00:00.000P', + }; + + foreach ($metrics as $metric) { + $usage[$metric] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric][] = [ + 'value' => $stats[$metric][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } + $usage[$metric] = array_reverse($usage[$metric]); + } + + $response->dynamic(new Document([ + 'range' => $range, + 'databasesCount' => $usage[$metrics[0]], + 'collectionsCount' => $usage[$metrics[1]], + 'documentsCount' => $usage[$metrics[2]], + ]), Response::MODEL_USAGE_DATABASES); }); diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index 6e5b07c64d..5665780b90 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -2,6 +2,7 @@ use Appwrite\Utopia\Response; use Utopia\App; +use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; @@ -23,90 +24,67 @@ App::get('/v1/project/usage') ->inject('response') ->inject('dbForProject') ->action(function (string $range, Response $response, Database $dbForProject) { - // $usage = []; - // if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') { - // $periods = [ - // '24h' => [ - // 'period' => '1h', - // 'limit' => 24, - // ], - // '7d' => [ - // 'period' => '1d', - // 'limit' => 7, - // ], - // '30d' => [ - // 'period' => '1d', - // 'limit' => 30, - // ], - // '90d' => [ - // 'period' => '1d', - // 'limit' => 90, - // ], - // ]; - // $metrics = [ - // 'project.$all.network.requests', - // 'project.$all.network.bandwidth', - // 'project.$all.storage.size', - // 'users.$all.count.total', - // 'databases.$all.count.total', - // 'documents.$all.count.total', - // 'executions.$all.compute.total', - // 'buckets.$all.count.total' - // ]; + $periods = Config::getParam('usage', []); + $stats = $usage = []; + $days = $periods[$range]; + $metrics = [ + 'network.inbound', + 'network.outbound', + 'executions', + 'documents', + 'databases', + 'users', + 'files.storage', + 'buckets', + ]; - // $stats = []; + Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + foreach ($metrics as $metric) { + $limit = $days['limit']; + $period = $days['period']; + $results = $dbForProject->find('stats', [ + Query::equal('period', [$period]), + Query::equal('metric', [$metric]), + Query::limit($limit), + Query::orderDesc('time'), + ]); + $stats[$metric] = []; + foreach ($results as $result) { + $stats[$metric][$result->getAttribute('time')] = [ + 'value' => $result->getAttribute('value'), + ]; + } + } + }); - // Authorization::skip(function () use ($dbForProject, $periods, $range, $metrics, &$stats) { - // foreach ($metrics as $metric) { - // $limit = $periods[$range]['limit']; - // $period = $periods[$range]['period']; + $format = match ($days['period']) { + '1h' => 'Y-m-d\TH:00:00.000P', + '1d' => 'Y-m-d\T00:00:00.000P', + }; - // $requestDocs = $dbForProject->find('stats', [ - // Query::equal('period', [$period]), - // Query::equal('metric', [$metric]), - // Query::limit($limit), - // Query::orderDesc('time'), - // ]); + foreach ($metrics as $metric) { + $usage[$metric] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric][] = [ + 'value' => $stats[$metric][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } + $usage[$metric] = array_reverse($usage[$metric]); + } - // $stats[$metric] = []; - // foreach ($requestDocs as $requestDoc) { - // $stats[$metric][] = [ - // 'value' => $requestDoc->getAttribute('value'), - // 'date' => $requestDoc->getAttribute('time'), - // ]; - // } - - // // backfill metrics with empty values for graphs - // $backfill = $limit - \count($requestDocs); - // while ($backfill > 0) { - // $last = $limit - $backfill - 1; // array index of last added metric - // $diff = match ($period) { // convert period to seconds for unix timestamp math - // '1h' => 3600, - // '1d' => 86400, - // }; - // $stats[$metric][] = [ - // 'value' => 0, - // 'date' => DateTime::formatTz(DateTime::addSeconds(new \DateTime($stats[$metric][$last]['date'] ?? null), -1 * $diff)), - // ]; - // $backfill--; - // } - // $stats[$metric] = array_reverse($stats[$metric]); - // } - // }); - - // $usage = new Document([ - // 'range' => $range, - // 'requests' => $stats[$metrics[0]] ?? [], - // 'network' => $stats[$metrics[1]] ?? [], - // 'storage' => $stats[$metrics[2]] ?? [], - // 'users' => $stats[$metrics[3]] ?? [], - // 'databases' => $stats[$metrics[4]] ?? [], - // 'documents' => $stats[$metrics[5]] ?? [], - // 'executions' => $stats[$metrics[6]] ?? [], - // 'buckets' => $stats[$metrics[7]] ?? [], - // ]); - // } - - // $response->dynamic($usage, Response::MODEL_USAGE_PROJECT); + $response->dynamic(new Document([ + 'range' => $range, + 'network' => ($usage[$metrics[0]] + $usage[$metrics[1]]), + 'executions' => $usage[$metrics[2]], + 'documents' => $usage[$metrics[3]], + 'databases' => $usage[$metrics[4]], + 'users' => $usage[$metrics[5]], + 'storage' => $usage[$metrics[6]], + 'buckets' => $usage[$metrics[8]], + ]), Response::MODEL_USAGE_PROJECT); }); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 01720b5d86..3697dddb5f 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -57,12 +57,12 @@ $databaseListener = function (string $event, Document $document, Document $proje var_dump($document->getCollection()); switch (true) { - case $document->getCollection() === 'users': - $queueForUsage->addMetric("users", $value); // per project - break; case $document->getCollection() === 'teams': $queueForUsage->addMetric("teams", $value); // per project break; + case $document->getCollection() === 'users': + $queueForUsage->addMetric("users", $value); // per project + break; case $document->getCollection() === 'sessions': $queueForUsage->addMetric("sessions", $value); // per project break; @@ -80,7 +80,6 @@ $databaseListener = function (string $event, Document $document, Document $proje $dbCollections['value'] ); } - // Documents $dbDocuments = $dbForProject->getDocument('stats', md5("_inf_" . "{$document->getId()}" . ".documents")); $projectDocuments = $dbForProject->getDocument('stats', md5("_inf_documents")); @@ -97,11 +96,24 @@ $databaseListener = function (string $event, Document $document, Document $proje case str_starts_with($document->getCollection(), 'database_'): // collections $queueForUsage->addMetric("{$document['databaseId']}" . ".collections", $value); // per database $queueForUsage->addMetric("collections", $value); // per project + if ($event === Database::EVENT_DOCUMENT_DELETE) { + // Documents + $dbDocuments = $dbForProject->getDocument('stats', md5("_inf_" . "{$document['databaseId']}" . ".documents")); + $projectDocuments = $dbForProject->getDocument('stats', md5("_inf_documents")); + if (!$dbDocuments->isEmpty()) { + $dbForProject->decreaseDocumentAttribute( + 'stats', + $projectDocuments->getId(), + 'value', + $dbDocuments['value'] + ); + } + } break; case $document->getCollection() === 'documents': $queueForUsage - ->addMetric("{$document['databaseId']}" . "." . "{$document['collectionId']}" . ".documents", $value) // per collection ->addMetric("{$document['databaseId']}" . ".documents", $value) // per database + ->addMetric("{$document['databaseId']}" . "." . "{$document['collectionId']}" . ".documents", $value) // per collection ->addMetric("documents", $value) // per project ; break; diff --git a/composer.lock b/composer.lock index f741341ef5..8e1ff6f8bb 100644 --- a/composer.lock +++ b/composer.lock @@ -3315,16 +3315,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.69", + "version": "1.3.70", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f" + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a61c949cccd086808063611ef9698eabe42ef22f", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2807d9f9bece6877577ad44acb5c801bb3ae536b", + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b", "shasum": "" }, "require": { @@ -3333,9 +3333,10 @@ "php": ">=5.3.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.0", - "matthiasmullie/scrapbook": "dev-master", - "phpunit/phpunit": ">=4.8" + "friendsofphp/php-cs-fixer": ">=2.0", + "matthiasmullie/scrapbook": ">=1.3", + "phpunit/phpunit": ">=4.8", + "squizlabs/php_codesniffer": ">=3.0" }, "suggest": { "psr/cache-implementation": "Cache implementation to use with Minify::cache" @@ -3358,12 +3359,12 @@ { "name": "Matthias Mullie", "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", + "homepage": "https://www.mullie.eu", "role": "Developer" } ], "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "http://www.minifier.org", + "homepage": "https://github.com/matthiasmullie/minify", "keywords": [ "JS", "css", @@ -3373,7 +3374,7 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.69" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.70" }, "funding": [ { @@ -3381,7 +3382,7 @@ "type": "github" } ], - "time": "2022-08-01T09:00:18+00:00" + "time": "2022-12-09T12:56:44+00:00" }, { "name": "matthiasmullie/path-converter", diff --git a/src/Appwrite/Utopia/Response/Model/UsageCollection.php b/src/Appwrite/Utopia/Response/Model/UsageCollection.php index 8b6966fcd2..1f60076d02 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageCollection.php +++ b/src/Appwrite/Utopia/Response/Model/UsageCollection.php @@ -23,34 +23,6 @@ class UsageCollection extends Model 'example' => [], 'array' => true ]) - ->addRule('documentsCreate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents created.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsRead', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents read.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsUpdate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents updated.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsDelete', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents deleted.', - 'default' => [], - 'example' => [], - 'array' => true - ]) ; } diff --git a/src/Appwrite/Utopia/Response/Model/UsageDatabase.php b/src/Appwrite/Utopia/Response/Model/UsageDatabase.php index 0c84d796ba..7f3aab29aa 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageDatabase.php +++ b/src/Appwrite/Utopia/Response/Model/UsageDatabase.php @@ -16,13 +16,6 @@ class UsageDatabase extends Model 'default' => '', 'example' => '30d', ]) - ->addRule('documentsCount', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for total number of documents.', - 'default' => [], - 'example' => [], - 'array' => true - ]) ->addRule('collectionsCount', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated stats for total number of collections.', @@ -30,58 +23,9 @@ class UsageDatabase extends Model 'example' => [], 'array' => true ]) - ->addRule('documentsCreate', [ + ->addRule('documentsCount', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents created.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsRead', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents read.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsUpdate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents updated.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsDelete', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents deleted.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('collectionsCreate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for collections created.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('collectionsRead', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for collections read.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('collectionsUpdate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for collections updated.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('collectionsDelete', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for collections delete.', + 'description' => 'Aggregated stats for total number of documents.', 'default' => [], 'example' => [], 'array' => true diff --git a/src/Appwrite/Utopia/Response/Model/UsageDatabases.php b/src/Appwrite/Utopia/Response/Model/UsageDatabases.php index 93488a47db..a37639c28e 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageDatabases.php +++ b/src/Appwrite/Utopia/Response/Model/UsageDatabases.php @@ -23,13 +23,6 @@ class UsageDatabases extends Model 'example' => [], 'array' => true ]) - ->addRule('documentsCount', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for total number of documents.', - 'default' => [], - 'example' => [], - 'array' => true - ]) ->addRule('collectionsCount', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated stats for total number of collections.', @@ -37,86 +30,9 @@ class UsageDatabases extends Model 'example' => [], 'array' => true ]) - ->addRule('databasesCreate', [ + ->addRule('documentsCount', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents created.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('databasesRead', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents read.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('databasesUpdate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents updated.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('databasesDelete', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for total number of collections.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsCreate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents created.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsRead', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents read.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsUpdate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents updated.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('documentsDelete', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for documents deleted.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('collectionsCreate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for collections created.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('collectionsRead', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for collections read.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('collectionsUpdate', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for collections updated.', - 'default' => [], - 'example' => [], - 'array' => true - ]) - ->addRule('collectionsDelete', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for collections delete.', + 'description' => 'Aggregated stats for total number of documents.', 'default' => [], 'example' => [], 'array' => true diff --git a/src/Appwrite/Utopia/Response/Model/UsageProject.php b/src/Appwrite/Utopia/Response/Model/UsageProject.php index e37bc5928d..ae099785e5 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageProject.php +++ b/src/Appwrite/Utopia/Response/Model/UsageProject.php @@ -16,13 +16,6 @@ class UsageProject extends Model 'default' => '', 'example' => '30d', ]) - ->addRule('requests', [ - 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated stats for number of requests.', - 'default' => [], - 'example' => [], - 'array' => true - ]) ->addRule('network', [ 'type' => Response::MODEL_METRIC, 'description' => 'Aggregated stats for consumed bandwidth.',