From 00a1612b2431967cae6388a195e5b5b3ff167e7b Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 16 Aug 2021 14:38:34 +0545 Subject: [PATCH] users and sessions stats --- app/controllers/api/account.php | 150 +++++++++++++++++++++++++++----- app/controllers/api/users.php | 2 +- app/tasks/usage.php | 83 ++++++------------ src/Appwrite/Stats/Stats.php | 36 +++++++- 4 files changed, 189 insertions(+), 82 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index ef0880511..b2baa4fcb 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -52,12 +52,14 @@ App::post('/v1/account') ->inject('project') ->inject('dbForInternal') ->inject('audits') - ->action(function ($userId, $email, $password, $name, $request, $response, $project, $dbForInternal, $audits) { + ->inject('usage') + ->action(function ($userId, $email, $password, $name, $request, $response, $project, $dbForInternal, $audits, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Usage\Usage $usage */ $email = \strtolower($email); if ('console' === $project->getId()) { @@ -120,6 +122,9 @@ App::post('/v1/account') ->setParam('resource', 'users/' . $user->getId()) ; + $usage + ->setParam('users.create', 1) + ; $response->setStatusCode(Response::STATUS_CODE_CREATED); $response->dynamic($user, Response::MODEL_USER); }); @@ -147,13 +152,15 @@ App::post('/v1/account/sessions') ->inject('locale') ->inject('geodb') ->inject('audits') - ->action(function ($email, $password, $request, $response, $dbForInternal, $locale, $geodb, $audits) { + ->inject('usage') + ->action(function ($email, $password, $request, $response, $dbForInternal, $locale, $geodb, $audits, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Usage\Usage $usage */ $email = \strtolower($email); $protocol = $request->getProtocol(); @@ -227,6 +234,11 @@ App::post('/v1/account/sessions') ->setAttribute('countryName', $countryName) ; + $usage + ->setParam('users.update', 1) + ->setParam('users.sessions.create', 1) + ->setParam('provider', 'email') + ; $response->dynamic($session, Response::MODEL_SESSION); }); @@ -357,7 +369,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') ->inject('geodb') ->inject('audits') ->inject('events') - ->action(function ($provider, $code, $state, $request, $response, $project, $user, $dbForInternal, $geodb, $audits, $events) use ($oauthDefaultSuccess) { + ->inject('usage') + ->action(function ($provider, $code, $state, $request, $response, $project, $user, $dbForInternal, $geodb, $audits, $events, $usage) use ($oauthDefaultSuccess) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ @@ -365,6 +378,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') /** @var Utopia\Database\Database $dbForInternal */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Stats\Stats $usage */ $protocol = $request->getProtocol(); $callback = $protocol . '://' . $request->getHostname() . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId(); @@ -545,6 +559,11 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $events->setParam('eventData', $response->output($session, Response::MODEL_SESSION)); + $usage + ->setParam('users.sessions.create', 1) + ->setParam('projectId', $project->getId()) + ->setParam('provider', $provider) + ; if (!Config::getParam('domainVerification')) { $response ->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)])) @@ -595,7 +614,8 @@ App::post('/v1/account/sessions/anonymous') ->inject('dbForInternal') ->inject('geodb') ->inject('audits') - ->action(function ($request, $response, $locale, $user, $project, $dbForInternal, $geodb, $audits) { + ->inject('usage') + ->action(function ($request, $response, $locale, $user, $project, $dbForInternal, $geodb, $audits, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Locale\Locale $locale */ @@ -604,6 +624,7 @@ App::post('/v1/account/sessions/anonymous') /** @var Utopia\Database\Database $dbForInternal */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Stats\Stats $usage */ $protocol = $request->getProtocol(); @@ -686,6 +707,11 @@ App::post('/v1/account/sessions/anonymous') ->setParam('resource', 'users/' . $user->getId()) ; + $usage + ->setParam('users.sessions.create', 1) + ->setParam('provider', 'anonymous') + ; + if (!Config::getParam('domainVerification')) { $response ->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)])) @@ -771,10 +797,15 @@ App::get('/v1/account') ->label('sdk.response.model', Response::MODEL_USER) ->inject('response') ->inject('user') - ->action(function ($response, $user) { + ->inject('usage') + ->action(function ($response, $user, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ + /** @var Appwrite\Stats\Stats $usage */ + $usage + ->setParam('users.read', 1) + ; $response->dynamic($user, Response::MODEL_USER); }); @@ -791,12 +822,17 @@ App::get('/v1/account/prefs') ->label('sdk.response.model', Response::MODEL_PREFERENCES) ->inject('response') ->inject('user') - ->action(function ($response, $user) { + ->inject('usage') + ->action(function ($response, $user, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ + /** @var Appwrite\Stats\Stats $usage */ $prefs = $user->getAttribute('prefs', new \stdClass()); + $usage + ->setParam('users.read', 1) + ; $response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES); }); @@ -814,10 +850,12 @@ App::get('/v1/account/sessions') ->inject('response') ->inject('user') ->inject('locale') - ->action(function ($response, $user, $locale) { + ->inject('usage') + ->action(function ($response, $user, $locale, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Locale\Locale $locale */ + /** @var Appwrite\Stats\Stats $usage */ $sessions = $user->getAttribute('sessions', []); $current = Auth::sessionVerify($sessions, Auth::$secret); @@ -831,6 +869,9 @@ App::get('/v1/account/sessions') $sessions[$key] = $session; } + $usage + ->setParam('users.read', 1) + ; $response->dynamic(new Document([ 'sessions' => $sessions, 'sum' => count($sessions), @@ -853,13 +894,15 @@ App::get('/v1/account/logs') ->inject('locale') ->inject('geodb') ->inject('dbForInternal') - ->action(function ($response, $user, $locale, $geodb, $dbForInternal) { + ->inject('usage') + ->action(function ($response, $user, $locale, $geodb, $dbForInternal, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ /** @var Utopia\Database\Database $dbForInternal */ + /** @var Appwrite\Stats\Stats $usage */ $audit = new Audit($dbForInternal); @@ -906,6 +949,9 @@ App::get('/v1/account/logs') } + $usage + ->setParam('users.read', 1) + ; $response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST); }); @@ -925,11 +971,13 @@ App::get('/v1/account/sessions/:sessionId') ->inject('user') ->inject('locale') ->inject('dbForInternal') - ->action(function ($sessionId, $response, $user, $locale, $dbForInternal) { + ->inject('usage') + ->action(function ($sessionId, $response, $user, $locale, $dbForInternal, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Database\Database $dbForInternal */ + /** @var Appwrite\Stats\Stats $usage */ $sessions = $user->getAttribute('sessions', []); $sessionId = ($sessionId === 'current') @@ -948,6 +996,10 @@ App::get('/v1/account/sessions/:sessionId') ->setAttribute('countryName', $countryName) ; + $usage + ->setParam('users.read', 1) + ; + return $response->dynamic($session, Response::MODEL_SESSION); } } @@ -972,11 +1024,13 @@ App::patch('/v1/account/name') ->inject('user') ->inject('dbForInternal') ->inject('audits') - ->action(function ($name, $response, $user, $dbForInternal, $audits) { + ->inject('usage') + ->action(function ($name, $response, $user, $dbForInternal, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Stats\Stats $usage */ $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('name', $name)); @@ -986,6 +1040,10 @@ App::patch('/v1/account/name') ->setParam('resource', 'users/' . $user->getId()) ; + $usage + ->setParam('users.update', 1) + ; + $response->dynamic($user, Response::MODEL_USER); }); @@ -1007,11 +1065,13 @@ App::patch('/v1/account/password') ->inject('user') ->inject('dbForInternal') ->inject('audits') - ->action(function ($password, $oldPassword, $response, $user, $dbForInternal, $audits) { + ->inject('usage') + ->action(function ($password, $oldPassword, $response, $user, $dbForInternal, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Stats\Stats $usage */ // Check old password only if its an existing user. if ($user->getAttribute('passwordUpdate') !== 0 && !Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password @@ -1029,6 +1089,9 @@ App::patch('/v1/account/password') ->setParam('resource', 'users/' . $user->getId()) ; + $usage + ->setParam('users.update', 1) + ; $response->dynamic($user, Response::MODEL_USER); }); @@ -1050,11 +1113,13 @@ App::patch('/v1/account/email') ->inject('user') ->inject('dbForInternal') ->inject('audits') - ->action(function ($email, $password, $response, $user, $dbForInternal, $audits) { + ->inject('usage') + ->action(function ($email, $password, $response, $user, $dbForInternal, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Stats\Stats $usage */ $isAnonymousUser = is_null($user->getAttribute('email')) && is_null($user->getAttribute('password')); // Check if request is from an anonymous account for converting @@ -1084,6 +1149,9 @@ App::patch('/v1/account/email') ->setParam('resource', 'users/' . $user->getId()) ; + $usage + ->setParam('users.update', 1) + ; $response->dynamic($user, Response::MODEL_USER); }); @@ -1104,11 +1172,13 @@ App::patch('/v1/account/prefs') ->inject('user') ->inject('dbForInternal') ->inject('audits') - ->action(function ($prefs, $response, $user, $dbForInternal, $audits) { + ->inject('usage') + ->action(function ($prefs, $response, $user, $dbForInternal, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Stats\Stats $usage */ $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs)); @@ -1117,6 +1187,9 @@ App::patch('/v1/account/prefs') ->setParam('resource', 'users/' . $user->getId()) ; + $usage + ->setParam('users.update', 1) + ; $response->dynamic($user, Response::MODEL_USER); }); @@ -1137,13 +1210,15 @@ App::delete('/v1/account') ->inject('dbForInternal') ->inject('audits') ->inject('events') - ->action(function ($request, $response, $user, $dbForInternal, $audits, $events) { + ->inject('usage') + ->action(function ($request, $response, $user, $dbForInternal, $audits, $events, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ + /** @var Appwrite\Stats\Stats $usage */ $protocol = $request->getProtocol(); $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('status', false)); @@ -1173,6 +1248,9 @@ App::delete('/v1/account') ; } + $usage + ->setParam('users.delete', 1) + ; $response ->addCookie(Auth::$cookieName . '_legacy', '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null) ->addCookie(Auth::$cookieName, '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite')) @@ -1200,7 +1278,8 @@ App::delete('/v1/account/sessions/:sessionId') ->inject('locale') ->inject('audits') ->inject('events') - ->action(function ($sessionId, $request, $response, $user, $dbForInternal, $locale, $audits, $events) { + ->inject('usage') + ->action(function ($sessionId, $request, $response, $user, $dbForInternal, $locale, $audits, $events, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ @@ -1208,6 +1287,7 @@ App::delete('/v1/account/sessions/:sessionId') /** @var Utopia\Locale\Locale $locale */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ + /** @var Appwrite\Stats\Stats $usage */ $protocol = $request->getProtocol(); $sessionId = ($sessionId === 'current') @@ -1254,6 +1334,10 @@ App::delete('/v1/account/sessions/:sessionId') ->setParam('eventData', $response->output($session, Response::MODEL_SESSION)) ; + $usage + ->setParam('users.sessions.delete', 1) + ->setParam('users.update', 1) + ; return $response->noContent(); } } @@ -1280,7 +1364,8 @@ App::delete('/v1/account/sessions') ->inject('locale') ->inject('audits') ->inject('events') - ->action(function ($request, $response, $user, $dbForInternal, $locale, $audits, $events) { + ->inject('usage') + ->action(function ($request, $response, $user, $dbForInternal, $locale, $audits, $events, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ @@ -1288,6 +1373,7 @@ App::delete('/v1/account/sessions') /** @var Utopia\Locale\Locale $locale */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ + /** @var Appwrite\Stats\Stats $usage */ $protocol = $request->getProtocol(); $sessions = $user->getAttribute('sessions', []); @@ -1330,6 +1416,10 @@ App::delete('/v1/account/sessions') ]), Response::MODEL_SESSION_LIST)) ; + $usage + ->setParam('users.sessions.delete', 1) + ->setParam('users.update', 1) + ; $response->noContent(); }); @@ -1357,7 +1447,8 @@ App::post('/v1/account/recovery') ->inject('mails') ->inject('audits') ->inject('events') - ->action(function ($email, $url, $request, $response, $dbForInternal, $project, $locale, $mails, $audits, $events) { + ->inject('usage') + ->action(function ($email, $url, $request, $response, $dbForInternal, $project, $locale, $mails, $audits, $events, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ @@ -1366,6 +1457,7 @@ App::post('/v1/account/recovery') /** @var Appwrite\Event\Event $mails */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ + /** @var Appwrite\Stats\Stats $usage */ $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles); $isAppUser = Auth::isAppUser(Authorization::$roles); @@ -1433,6 +1525,9 @@ App::post('/v1/account/recovery') ->setParam('resource', 'users/' . $profile->getId()) ; + $usage + ->setParam('users.update', 1) + ; $response->setStatusCode(Response::STATUS_CODE_CREATED); $response->dynamic($recovery, Response::MODEL_TOKEN); }); @@ -1458,10 +1553,12 @@ App::put('/v1/account/recovery') ->inject('response') ->inject('dbForInternal') ->inject('audits') - ->action(function ($userId, $secret, $password, $passwordAgain, $response, $dbForInternal, $audits) { + ->inject('usage') + ->action(function ($userId, $secret, $password, $passwordAgain, $response, $dbForInternal, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Stats\Stats $usage */ if ($password !== $passwordAgain) { throw new Exception('Passwords must match', 400); @@ -1508,6 +1605,9 @@ App::put('/v1/account/recovery') ->setParam('resource', 'users/' . $profile->getId()) ; + $usage + ->setParam('users.update', 1) + ; $response->dynamic($recovery, Response::MODEL_TOKEN); }); @@ -1535,7 +1635,8 @@ App::post('/v1/account/verification') ->inject('audits') ->inject('events') ->inject('mails') - ->action(function ($url, $request, $response, $project, $user, $dbForInternal, $locale, $audits, $events, $mails) { + ->inject('usage') + ->action(function ($url, $request, $response, $project, $user, $dbForInternal, $locale, $audits, $events, $mails, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ @@ -1545,6 +1646,7 @@ App::post('/v1/account/verification') /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $mails */ + /** @var Appwrite\Stats\Stats $usage */ $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles); $isAppUser = Auth::isAppUser(Authorization::$roles); @@ -1602,6 +1704,9 @@ App::post('/v1/account/verification') ->setParam('resource', 'users/' . $user->getId()) ; + $usage + ->setParam('users.update', 1) + ; $response->setStatusCode(Response::STATUS_CODE_CREATED); $response->dynamic($verification, Response::MODEL_TOKEN); }); @@ -1626,11 +1731,13 @@ App::put('/v1/account/verification') ->inject('user') ->inject('dbForInternal') ->inject('audits') - ->action(function ($userId, $secret, $response, $user, $dbForInternal, $audits) { + ->inject('usage') + ->action(function ($userId, $secret, $response, $user, $dbForInternal, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Stats\Stats $usage */ $profile = $dbForInternal->getDocument('users', $userId); @@ -1668,5 +1775,8 @@ App::put('/v1/account/verification') ->setParam('resource', 'users/' . $user->getId()) ; + $usage + ->setParam('users.update', 1) + ; $response->dynamic($verification, Response::MODEL_TOKEN); }); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index eb3abd12c..ad600ce48 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -573,7 +573,7 @@ App::delete('/v1/users/:userId') ->inject('dbForInternal') ->inject('events') ->inject('deletes') - ->inject('users') + ->inject('usage') ->action(function ($userId, $response, $dbForInternal, $events, $deletes, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ diff --git a/app/tasks/usage.php b/app/tasks/usage.php index 523096309..fc8d0478c 100644 --- a/app/tasks/usage.php +++ b/app/tasks/usage.php @@ -11,37 +11,8 @@ use Utopia\CLI\Console; use Utopia\Database\Adapter\MariaDB; use Utopia\Database\Database; use Utopia\Database\Document; -use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; -/** - * 1. Load all the projects - * 2. Load latest data entered entered for each project, for each period - * 3. Start the loop - * 4. Fore each project, for each metric, for each period - sync data - */ - -/** - * Only succefull operations - * - * database.collections.CRUD (project=x) - * database.documents.CRUD (project=x,collection=y) - * - * users.CRUD - * users.sessions.create (project=x,provider=y) - * users.sessions.delete (project=x,provider=y) - * - * storage.buckets.CRUD (project=x) - * storage.files.CRUD (project=x,bucket=y) - * - * refactor later - * - functions - * - realtime - * - teams - * - webhooks - * - keys - really later! - */ - $cli ->task('usage') ->desc('Schedules syncing data from influxdb to Appwrite console db') @@ -61,93 +32,91 @@ $cli ], ]; - //use projectId from influxdb instead of iterating over projects from DB - $globalMetrics = [ 'requests' => [ - 'method' => 'getGlobalMetrics', 'table' => 'appwrite_usage_requests_all', ], 'network' => [ - 'method' => 'getGlobalMetrics', 'table' => 'appwrite_usage_network_all', ], 'executions' => [ - 'method' => 'getGlobalMetrics', 'table' => 'appwrite_usage_executions_all', ], 'database.collections.create' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_collections_create', ], 'database.collections.read' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_collections_read', ], 'database.collections.update' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_collections_update', ], 'database.collections.delete' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_collections_delete', ], 'database.documents.create' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_documents_create', ], 'database.documents.read' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_documents_read', ], 'database.documents.update' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_documents_update', ], 'database.documents.delete' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_documents_delete', ], 'database.documents.collectionId.create' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_documents_create', 'groupBy' => 'collectionId', ], 'database.documents.collectionId.read' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_documents_read', 'groupBy' => 'collectionId', ], 'database.documents.collectionId.update' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_documents_update', 'groupBy' => 'collectionId', ], 'database.documents.collectionId.delete' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_database_documents_delete', 'groupBy' => 'collectionId', ], 'storage.buckets.bucketId.files.create' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_storage_files_create', 'groupBy' => 'bucketId', ], 'storage.buckets.bucketId.files.read' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_storage_files_read', 'groupBy' => 'bucketId', ], 'storage.buckets.bucketId.files.update' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_storage_files_update', 'groupBy' => 'bucketId', ], 'storage.buckets.bucketId.files.delete' => [ - 'method' => 'getDatabaseMetrics', 'table' => 'appwrite_usage_storage_files_delete', 'groupBy' => 'bucketId', ], + 'users.create' => [ + 'table' => 'appwrite_usage_users_create', + ], + 'users.read' => [ + 'table' => 'appwrite_usage_users_read', + ], + 'users.update' => [ + 'table' => 'appwrite_usage_users_update', + ], + 'users.delete' => [ + 'table' => 'appwrite_usage_users_delete', + ], + 'users.sessions.create' => [ + 'table' => 'appwrite_usage_users_sessions_create', + 'groupBy' => 'provider', + ], + 'users.sessions.delete' => [ + 'table' => 'appwrite_usage_users_sessions_delete', + ], ]; $attempts = 0; @@ -169,18 +138,16 @@ $cli } while ($attempts < $max); $cacheAdapter = new Cache(new Redis($redis)); - $dbForConsole = new Database(new MariaDB($db), $cacheAdapter); - $dbForConsole->setNamespace('project_console_internal'); $dbForProject = new Database(new MariaDB($db), $cacheAdapter); Authorization::disable(); - $latestData = []; - $firstRun = true; - Console::loop(function () use ($interval, $register, &$latestData, $dbForProject, $dbForConsole, &$firstRun, $globalMetrics, $periods) { + Console::loop(function () use ($interval, $register, $dbForProject, $globalMetrics, $periods) { $time = date('d-m-Y H:i:s', time()); Console::info("[{$time}] Aggregating usage data every {$interval} seconds"); + $loopStart = microtime(true); + $client = $register->get('influxdb'); if ($client) { $database = $client->selectDB('telegraf'); @@ -225,7 +192,6 @@ $cli $dbForProject->updateDocument('stats', $document->getId(), $document->setAttribute('value', $value)); } - $latestData[$projectId][$metric][$period['key']] = $time; } catch (\Exception$e) { Console::warning("Failed to save data for project {$projectId} and metric {$metric}"); } @@ -234,6 +200,9 @@ $cli } } } - $firstRun = false; + + $loopTook = microtime(true) - $loopStart; + $time = date('d-m-Y H:i:s', time()); + Console::info("[{$time}] Aggregation took {$loopTook} seconds"); }, $interval); }); diff --git a/src/Appwrite/Stats/Stats.php b/src/Appwrite/Stats/Stats.php index 5c24e1ae9..f56f6a4e7 100644 --- a/src/Appwrite/Stats/Stats.php +++ b/src/Appwrite/Stats/Stats.php @@ -126,8 +126,8 @@ class Stats foreach ($dbMetrics as $metric) { $value = $this->params[$metric] ?? 0; if ($value >= 1) { - $dbTags = ",projectId={$projectId},collectionId=" . ($this->params['collectionId'] ?? ''); - $this->statsd->increment($metric . $dbTags); + $tags = ",projectId={$projectId},collectionId=" . ($this->params['collectionId'] ?? ''); + $this->statsd->increment($metric . $tags); } } @@ -141,8 +141,36 @@ class Stats foreach ($storageMertics as $metric) { $value = $this->params[$metric] ?? 0; if ($value >= 1) { - $storageTags = ",projectId={$projectId},bucketId=" . ($this->params['bucketId'] ?? ''); - $this->statsd->increment($metric . $storageTags); + $tags = ",projectId={$projectId},bucketId=" . ($this->params['bucketId'] ?? ''); + $this->statsd->increment($metric . $tags); + } + } + + $usersMetrics = [ + 'users.create', + 'users.read', + 'users.update', + 'users.delete', + ]; + + foreach ($usersMetrics as $metric) { + $value = $this->params[$metric] ?? 0; + if ($value >= 1) { + $tags = ",projectId={$projectId}"; + $this->statsd->increment($metric . $tags); + } + } + + $sessionsMetrics = [ + 'users.sessions.create', + 'users.sessions.delete', + ]; + + foreach ($sessionsMetrics as $metric) { + $value = $this->params[$metric] ?? 0; + if ($value >= 1) { + $tags = ",projectId={$projectId},provider=". ($this->params['provider'] ?? ''); + $this->statsd->increment($metric . $tags); } }