diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 6d82c4f472..5a0cb03209 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -18,6 +18,7 @@ use Utopia\Database\Exception\Duplicate; use Utopia\Database\Validator\UID; use DeviceDetector\DeviceDetector; use Appwrite\Database\Validator\CustomId; +use Appwrite\Utopia\Response\Model; use Utopia\Database\Database; use Utopia\Database\Query; @@ -616,6 +617,9 @@ App::get('/v1/users/usage') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'users') ->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_USERS_USAGE) ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true) ->inject('response') ->inject('dbForInternal') @@ -624,11 +628,11 @@ App::get('/v1/users/usage') /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ - $stats = []; + $usage = []; if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') { $period = [ '24h' => [ - 'period' => '30m', + 'period' => '15m', 'limit' => 48, ], '7d' => [ @@ -646,8 +650,8 @@ App::get('/v1/users/usage') ]; Authorization::disable(); - $metrics = [ + "users.count", "users.create", "users.read", "users.update", @@ -656,6 +660,7 @@ App::get('/v1/users/usage') "users.sessions.delete" ]; + $stats = []; foreach ($metrics as $metric) { $requestDocs = $dbForInternal->find('stats', [ new Query('period', Query::TYPE_EQUAL, [$period[$range]['period']]), @@ -672,63 +677,21 @@ App::get('/v1/users/usage') $stats[$metric] = array_reverse($stats[$metric]); } - - $usersCount = $dbForInternal->findOne('stats', [new Query('metric', Query::TYPE_EQUAL, ['users.count'])], 0, ['time'], [Database::ORDER_DESC]); - $usersTotal = $usersCount ? $usersCount->getAttribute('value', 0) : 0; - + Authorization::reset(); - $create = $stats["users.create"] ?? []; - $read = $stats["users.read"] ?? []; - $update = $stats["users.update"] ?? []; - $delete = $stats["users.delete"] ?? []; - $sessionsCreate = $stats["users.sessions.create"] ?? []; - $sessionsDelete = $stats["users.sessions.delete"] ?? []; - - $response->json([ + $usage = new Document([ 'range' => $range, - 'users' => [ - 'data' => [], - 'total' => $usersTotal, - ], - 'create' => [ - 'data' => $create, - 'total' => \array_sum(\array_map(function ($item) { - return $item['value']; - }, $create)), - ], - 'read' => [ - 'data' => $read, - 'total' => \array_sum(\array_map(function ($item) { - return $item['value']; - }, $read)), - ], - 'update' => [ - 'data' => $update, - 'total' => \array_sum(\array_map(function ($item) { - return $item['value']; - }, $update)), - ], - 'delete' => [ - 'data' => $delete, - 'total' => \array_sum(\array_map(function ($item) { - return $item['value']; - }, $delete)), - ], - 'sessionsCreate' => [ - 'data' => $sessionsCreate, - 'total' => \array_sum(\array_map(function ($item) { - return $item['value']; - }, $sessionsCreate)), - ], - 'sessionsDelete' => [ - 'data' => $sessionsDelete, - 'total' => \array_sum(\array_map(function ($item) { - return $item['value']; - }, $sessionsDelete)), - ] + 'users.count' => $stats["users.count"], + 'users.create' => $stats["users.create"], + 'users.read' => $stats["users.read"], + 'users.update' => $stats["users.update"], + 'users.delete' => $stats["users.delete"], + 'sessions.create' => $stats["users.sessions.create"], + 'sessions.delete' => $stats["users.sessions.delete"] ]); - } else { - $response->json([]); + } + + $response->dynamic($usage, Response::MODEL_USERS_USAGE); }); \ No newline at end of file diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 811f07cb55..728e52b9e0 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -47,6 +47,7 @@ use Appwrite\Utopia\Response\Model\Webhook; use Appwrite\Utopia\Response\Model\Preferences; use Appwrite\Utopia\Response\Model\Mock; // Keep last use Appwrite\Utopia\Response\Model\StorageUsage; +use Appwrite\Utopia\Response\Model\UsersUsage; use stdClass; /** @@ -80,6 +81,7 @@ class Response extends SwooleResponse // Users const MODEL_USER = 'user'; const MODEL_USER_LIST = 'userList'; + const MODEL_USERS_USAGE = 'usersUsage'; const MODEL_SESSION = 'session'; const MODEL_SESSION_LIST = 'sessionList'; const MODEL_TOKEN = 'token'; @@ -196,6 +198,7 @@ class Response extends SwooleResponse ->setModel(new CollectionUsage()) ->setModel(new Log()) ->setModel(new User()) + ->setModel(new UsersUsage()) ->setModel(new Preferences()) ->setModel(new Session()) ->setModel(new Token()) diff --git a/src/Appwrite/Utopia/Response/Model/UsersUsage.php b/src/Appwrite/Utopia/Response/Model/UsersUsage.php new file mode 100644 index 0000000000..bb3db30b26 --- /dev/null +++ b/src/Appwrite/Utopia/Response/Model/UsersUsage.php @@ -0,0 +1,91 @@ +addRule('range', [ + 'type' => self::TYPE_STRING, + 'description' => 'The time range of the usage stats.', + 'default' => '', + 'example' => '30d', + ]) + ->addRule('users.count', [ + 'type' => Response::MODEL_METRIC_LIST, + 'description' => 'Aggregated stats for total number of users.', + 'default' => [], + 'example' => new stdClass, + 'array' => true + ]) + ->addRule('users.create', [ + 'type' => Response::MODEL_METRIC_LIST, + 'description' => 'Aggregated stats for users created.', + 'default' => [], + 'example' => new stdClass, + 'array' => true + ]) + ->addRule('users.read', [ + 'type' => Response::MODEL_METRIC_LIST, + 'description' => 'Aggregated stats for users read.', + 'default' => [], + 'example' => new stdClass, + 'array' => true + ]) + ->addRule('users.update', [ + 'type' => Response::MODEL_METRIC_LIST, + 'description' => 'Aggregated stats for users updated.', + 'default' => [], + 'example' => new stdClass, + 'array' => true + ]) + ->addRule('users.delete', [ + 'type' => Response::MODEL_METRIC_LIST, + 'description' => 'Aggregated stats for users deleted.', + 'default' => [], + 'example' => new stdClass, + 'array' => true + ]) + ->addRule('sessions.create', [ + 'type' => Response::MODEL_METRIC_LIST, + 'description' => 'Aggregated stats for sessions created.', + 'default' => [], + 'example' => new stdClass, + 'array' => true + ]) + ->addRule('sessions.delete', [ + 'type' => Response::MODEL_METRIC_LIST, + 'description' => 'Aggregated stats for sessions deleted.', + 'default' => [], + 'example' => new stdClass, + 'array' => true + ]) + ; + } + + /** + * Get Name + * + * @return string + */ + public function getName():string + { + return 'UsersUsage'; + } + + /** + * Get Type + * + * @return string + */ + public function getType():string + { + return Response::MODEL_USERS_USAGE; + } +} \ No newline at end of file