Merge pull request #9403 from appwrite/batch-per-project

Log batches per project
This commit is contained in:
Jake Barnby 2025-02-25 21:46:33 +13:00 committed by GitHub
commit 66dc3adb98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 222 additions and 527 deletions

View file

@ -2715,13 +2715,15 @@ App::get('/v1/account/logs')
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new EventAudit($dbForProject);
$logs = $audit->getLogsByUser($user->getInternalId(), $limit, $offset);
$logs = $audit->getLogsByUser($user->getInternalId(), $queries);
$output = [];
@ -2750,10 +2752,8 @@ App::get('/v1/account/logs')
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByUser($user->getInternalId()),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByUser($user->getInternalId(), $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});

View file

@ -23,6 +23,7 @@ use Utopia\App;
use Utopia\Audit\Audit;
use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Exception\Authorization as AuthorizationException;
use Utopia\Database\Exception\Conflict as ConflictException;
@ -669,13 +670,15 @@ App::get('/v1/databases/:databaseId/logs')
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new Audit($dbForProject);
$resource = 'database/' . $databaseId;
$logs = $audit->getLogsByResource($resource, $limit, $offset);
$logs = $audit->getLogsByResource($resource, $queries);
$output = [];
@ -723,10 +726,8 @@ App::get('/v1/databases/:databaseId/logs')
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByResource($resource),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByResource($resource, $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -1059,14 +1060,21 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs')
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$queries = Query::parseQueries($queries);
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new Audit($dbForProject);
$resource = 'database/' . $databaseId . '/collection/' . $collectionId;
$logs = $audit->getLogsByResource($resource, $limit, $offset);
$logs = $audit->getLogsByResource($resource, $queries);
$output = [];
@ -1114,10 +1122,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs')
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByResource($resource),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByResource($resource, $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -3713,13 +3719,15 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new Audit($dbForProject);
$resource = 'database/' . $databaseId . '/collection/' . $collectionId . '/document/' . $document->getId();
$logs = $audit->getLogsByResource($resource, $limit, $offset);
$logs = $audit->getLogsByResource($resource, $queries);
$output = [];
@ -3767,10 +3775,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByResource($resource),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByResource($resource, $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});

View file

@ -994,13 +994,15 @@ App::get('/v1/messaging/providers/:providerId/logs')
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new Audit($dbForProject);
$resource = 'provider/' . $providerId;
$logs = $audit->getLogsByResource($resource, $limit, $offset);
$logs = $audit->getLogsByResource($resource, $queries);
$output = [];
foreach ($logs as $i => &$log) {
@ -1047,10 +1049,8 @@ App::get('/v1/messaging/providers/:providerId/logs')
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByResource($resource),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByResource($resource, $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -2224,13 +2224,15 @@ App::get('/v1/messaging/topics/:topicId/logs')
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new Audit($dbForProject);
$resource = 'topic/' . $topicId;
$logs = $audit->getLogsByResource($resource, $limit, $offset);
$logs = $audit->getLogsByResource($resource, $queries);
$output = [];
@ -2278,10 +2280,8 @@ App::get('/v1/messaging/topics/:topicId/logs')
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByResource($resource),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByResource($resource, $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -2636,13 +2636,15 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs')
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new Audit($dbForProject);
$resource = 'subscriber/' . $subscriberId;
$logs = $audit->getLogsByResource($resource, $limit, $offset);
$logs = $audit->getLogsByResource($resource, $queries);
$output = [];
@ -2690,10 +2692,8 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs')
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByResource($resource),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByResource($resource, $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@ -3403,13 +3403,15 @@ App::get('/v1/messaging/messages/:messageId/logs')
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new Audit($dbForProject);
$resource = 'message/' . $messageId;
$logs = $audit->getLogsByResource($resource, $limit, $offset);
$logs = $audit->getLogsByResource($resource, $queries);
$output = [];
@ -3457,10 +3459,8 @@ App::get('/v1/messaging/messages/:messageId/logs')
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByResource($resource),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByResource($resource, $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});

View file

@ -1362,13 +1362,15 @@ App::get('/v1/teams/:teamId/logs')
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new Audit($dbForProject);
$resource = 'team/' . $team->getId();
$logs = $audit->getLogsByResource($resource, $limit, $offset);
$logs = $audit->getLogsByResource($resource, $queries);
$output = [];
@ -1415,9 +1417,7 @@ App::get('/v1/teams/:teamId/logs')
}
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByResource($resource),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByResource($resource, $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});

View file

@ -862,13 +862,15 @@ App::get('/v1/users/:userId/logs')
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
// Temp fix for logs
$queries[] = Query::or([
Query::greaterThan('$createdAt', DateTime::format(new \DateTime('2025-02-25T09:00+00:00'))),
Query::lessThan('$createdAt', DateTime::format(new \DateTime('2025-02-13T00:00+00:00'))),
]);
$audit = new Audit($dbForProject);
$logs = $audit->getLogsByUser($user->getInternalId(), $limit, $offset);
$logs = $audit->getLogsByUser($user->getInternalId(), $queries);
$output = [];
@ -915,10 +917,8 @@ App::get('/v1/users/:userId/logs')
}
$response->dynamic(new Document([
//'total' => $audit->countLogsByUser($user->getInternalId()),
//'logs' => $output,
'total' => 0,
'logs' => [],
'total' => $audit->countLogsByUser($user->getInternalId(), $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});

View file

@ -45,13 +45,13 @@
"ext-sockets": "*",
"appwrite/php-runtimes": "0.16.*",
"appwrite/php-clamav": "2.0.*",
"utopia-php/abuse": "0.50.*",
"utopia-php/abuse": "0.51.*",
"utopia-php/analytics": "0.10.*",
"utopia-php/audit": "0.51.*",
"utopia-php/audit": "0.54.0",
"utopia-php/cache": "0.11.*",
"utopia-php/cli": "0.15.*",
"utopia-php/config": "0.2.*",
"utopia-php/database": "0.59.0",
"utopia-php/database": "0.60.*",
"utopia-php/domains": "0.5.*",
"utopia-php/dsn": "0.2.1",
"utopia-php/framework": "0.33.*",
@ -85,11 +85,11 @@
"require-dev": {
"ext-fileinfo": "*",
"appwrite/sdk-generator": "0.40.*",
"phpunit/phpunit": "9.5.20",
"phpunit/phpunit": "9.*",
"swoole/ide-helper": "5.1.2",
"textalk/websocket": "1.5.7",
"laravel/pint": "^1.14",
"phpbench/phpbench": "^1.2"
"textalk/websocket": "1.5.*",
"laravel/pint": "1.*",
"phpbench/phpbench": "1.*"
},
"provide": {
"ext-phpiredis": "*"

507
composer.lock generated
View file

@ -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": "b1d26d441fe1fb6a26978d99ef01985f",
"content-hash": "87a12bb6f58c5dad7488229590e9a3f5",
"packages": [
{
"name": "adhocore/jwt",
@ -3377,16 +3377,16 @@
},
{
"name": "utopia-php/abuse",
"version": "0.50.0",
"version": "0.51.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/abuse.git",
"reference": "3ff67819e9de61506c5ca070a70552f7ebe99f80"
"reference": "661687b03277f1d202a0e8cf9da6e58c97da2b5e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/3ff67819e9de61506c5ca070a70552f7ebe99f80",
"reference": "3ff67819e9de61506c5ca070a70552f7ebe99f80",
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/661687b03277f1d202a0e8cf9da6e58c97da2b5e",
"reference": "661687b03277f1d202a0e8cf9da6e58c97da2b5e",
"shasum": ""
},
"require": {
@ -3394,7 +3394,7 @@
"ext-pdo": "*",
"ext-redis": "*",
"php": ">=8.0",
"utopia-php/database": "0.59.*"
"utopia-php/database": "0.60.*"
},
"require-dev": {
"laravel/pint": "1.*",
@ -3422,9 +3422,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/abuse/issues",
"source": "https://github.com/utopia-php/abuse/tree/0.50.0"
"source": "https://github.com/utopia-php/abuse/tree/0.51.0"
},
"time": "2025-02-12T09:13:59+00:00"
"time": "2025-02-17T11:10:18+00:00"
},
{
"name": "utopia-php/analytics",
@ -3474,21 +3474,21 @@
},
{
"name": "utopia-php/audit",
"version": "0.51.0",
"version": "0.54.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/audit.git",
"reference": "a5a4b73a57e27a0fac8025b1d6038e145a1ca04e"
"reference": "1b0cb8ac6bfbd7703e3f9a753c6ba59ff1c39975"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/a5a4b73a57e27a0fac8025b1d6038e145a1ca04e",
"reference": "a5a4b73a57e27a0fac8025b1d6038e145a1ca04e",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/1b0cb8ac6bfbd7703e3f9a753c6ba59ff1c39975",
"reference": "1b0cb8ac6bfbd7703e3f9a753c6ba59ff1c39975",
"shasum": ""
},
"require": {
"php": ">=8.0",
"utopia-php/database": "0.59.*"
"utopia-php/database": "0.60.*"
},
"require-dev": {
"laravel/pint": "1.*",
@ -3515,9 +3515,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/audit/issues",
"source": "https://github.com/utopia-php/audit/tree/0.51.0"
"source": "https://github.com/utopia-php/audit/tree/0.54.0"
},
"time": "2025-02-12T09:12:44+00:00"
"time": "2025-02-25T07:21:07+00:00"
},
{
"name": "utopia-php/cache",
@ -3717,16 +3717,16 @@
},
{
"name": "utopia-php/database",
"version": "0.59.0",
"version": "0.60.3",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "0eed7f1ad3eb66ff4a7d73b68dd9d3e05089eb18"
"reference": "c4bc4af3f09a91aea76aac75b4b78fa06598c61d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/0eed7f1ad3eb66ff4a7d73b68dd9d3e05089eb18",
"reference": "0eed7f1ad3eb66ff4a7d73b68dd9d3e05089eb18",
"url": "https://api.github.com/repos/utopia-php/database/zipball/c4bc4af3f09a91aea76aac75b4b78fa06598c61d",
"reference": "c4bc4af3f09a91aea76aac75b4b78fa06598c61d",
"shasum": ""
},
"require": {
@ -3767,9 +3767,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.59.0"
"source": "https://github.com/utopia-php/database/tree/0.60.3"
},
"time": "2025-02-12T08:08:29+00:00"
"time": "2025-02-17T12:46:59+00:00"
},
{
"name": "utopia-php/domains",
@ -3919,16 +3919,16 @@
},
{
"name": "utopia-php/framework",
"version": "0.33.16",
"version": "0.33.17",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/http.git",
"reference": "e91d4c560d1b809e25faa63d564fef034363b50f"
"reference": "73fac6fbce9f56282dba4e52a58cf836ec434644"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/http/zipball/e91d4c560d1b809e25faa63d564fef034363b50f",
"reference": "e91d4c560d1b809e25faa63d564fef034363b50f",
"url": "https://api.github.com/repos/utopia-php/http/zipball/73fac6fbce9f56282dba4e52a58cf836ec434644",
"reference": "73fac6fbce9f56282dba4e52a58cf836ec434644",
"shasum": ""
},
"require": {
@ -3960,9 +3960,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/http/issues",
"source": "https://github.com/utopia-php/http/tree/0.33.16"
"source": "https://github.com/utopia-php/http/tree/0.33.17"
},
"time": "2025-01-16T15:58:50+00:00"
"time": "2025-02-24T17:35:48+00:00"
},
{
"name": "utopia-php/image",
@ -4171,16 +4171,16 @@
},
{
"name": "utopia-php/migration",
"version": "0.6.19",
"version": "0.6.20",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/migration.git",
"reference": "3c9497f7a54ef88b1077c48d8326893133ad78eb"
"reference": "8c9ba52196f50aaef4aa1903f0d8fe0c8d9997ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/3c9497f7a54ef88b1077c48d8326893133ad78eb",
"reference": "3c9497f7a54ef88b1077c48d8326893133ad78eb",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/8c9ba52196f50aaef4aa1903f0d8fe0c8d9997ba",
"reference": "8c9ba52196f50aaef4aa1903f0d8fe0c8d9997ba",
"shasum": ""
},
"require": {
@ -4188,7 +4188,7 @@
"ext-curl": "*",
"ext-openssl": "*",
"php": ">=8.1",
"utopia-php/database": "0.59.*",
"utopia-php/database": "0.60.*",
"utopia-php/dsn": "0.2.*",
"utopia-php/framework": "0.33.*",
"utopia-php/storage": "0.18.*"
@ -4221,9 +4221,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/migration/issues",
"source": "https://github.com/utopia-php/migration/tree/0.6.19"
"source": "https://github.com/utopia-php/migration/tree/0.6.20"
},
"time": "2025-02-13T07:50:21+00:00"
"time": "2025-02-17T11:02:15+00:00"
},
{
"name": "utopia-php/mongo",
@ -5177,77 +5177,32 @@
},
"time": "2024-09-05T10:17:24+00:00"
},
{
"name": "doctrine/deprecations",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/doctrine/deprecations.git",
"reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9",
"reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^9 || ^12",
"phpstan/phpstan": "1.4.10 || 2.0.3",
"phpstan/phpstan-phpunit": "^1.0 || ^2",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"psr/log": "^1 || ^2 || ^3"
},
"suggest": {
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Deprecations\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
"homepage": "https://www.doctrine-project.org/",
"support": {
"issues": "https://github.com/doctrine/deprecations/issues",
"source": "https://github.com/doctrine/deprecations/tree/1.1.4"
},
"time": "2024-12-07T21:18:45+00:00"
},
{
"name": "doctrine/instantiator",
"version": "1.5.0",
"version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "0a0fa9780f5d4e507415a065172d26a98d02047b"
"reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b",
"reference": "0a0fa9780f5d4e507415a065172d26a98d02047b",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
"reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
"php": "^8.1"
},
"require-dev": {
"doctrine/coding-standard": "^9 || ^11",
"doctrine/coding-standard": "^11",
"ext-pdo": "*",
"ext-phar": "*",
"phpbench/phpbench": "^0.16 || ^1",
"phpstan/phpstan": "^1.4",
"phpstan/phpstan-phpunit": "^1",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"vimeo/psalm": "^4.30 || ^5.4"
"phpbench/phpbench": "^1.2",
"phpstan/phpstan": "^1.9.4",
"phpstan/phpstan-phpunit": "^1.3",
"phpunit/phpunit": "^9.5.27",
"vimeo/psalm": "^5.4"
},
"type": "library",
"autoload": {
@ -5274,7 +5229,7 @@
],
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
"source": "https://github.com/doctrine/instantiator/tree/1.5.0"
"source": "https://github.com/doctrine/instantiator/tree/2.0.0"
},
"funding": [
{
@ -5290,7 +5245,7 @@
"type": "tidelift"
}
],
"time": "2022-12-30T00:15:36+00:00"
"time": "2022-12-30T00:23:10+00:00"
},
{
"name": "doctrine/lexer",
@ -5944,298 +5899,6 @@
],
"time": "2025-01-26T19:54:45+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-2.x": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jaap van Otterdijk",
"email": "opensource@ijaap.nl"
}
],
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
"homepage": "http://www.phpdoc.org",
"keywords": [
"FQSEN",
"phpDocumentor",
"phpdoc",
"reflection",
"static analysis"
],
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
},
"time": "2020-06-27T09:03:43+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "5.6.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8",
"reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8",
"shasum": ""
},
"require": {
"doctrine/deprecations": "^1.1",
"ext-filter": "*",
"php": "^7.4 || ^8.0",
"phpdocumentor/reflection-common": "^2.2",
"phpdocumentor/type-resolver": "^1.7",
"phpstan/phpdoc-parser": "^1.7|^2.0",
"webmozart/assert": "^1.9.1"
},
"require-dev": {
"mockery/mockery": "~1.3.5 || ~1.6.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.8",
"phpstan/phpstan-mockery": "^1.1",
"phpstan/phpstan-webmozart-assert": "^1.2",
"phpunit/phpunit": "^9.5",
"psalm/phar": "^5.26"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
},
{
"name": "Jaap van Otterdijk",
"email": "opensource@ijaap.nl"
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.1"
},
"time": "2024-12-07T09:39:29+00:00"
},
{
"name": "phpdocumentor/type-resolver",
"version": "1.10.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
"reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a",
"reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a",
"shasum": ""
},
"require": {
"doctrine/deprecations": "^1.0",
"php": "^7.3 || ^8.0",
"phpdocumentor/reflection-common": "^2.0",
"phpstan/phpdoc-parser": "^1.18|^2.0"
},
"require-dev": {
"ext-tokenizer": "*",
"phpbench/phpbench": "^1.2",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.8",
"phpstan/phpstan-phpunit": "^1.1",
"phpunit/phpunit": "^9.5",
"rector/rector": "^0.13.9",
"vimeo/psalm": "^4.25"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-1.x": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
}
],
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0"
},
"time": "2024-11-09T15:12:26+00:00"
},
{
"name": "phpspec/prophecy",
"version": "v1.20.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "a0165c648cab6a80311c74ffc708a07bb53ecc93"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/a0165c648cab6a80311c74ffc708a07bb53ecc93",
"reference": "a0165c648cab6a80311c74ffc708a07bb53ecc93",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.2 || ^2.0",
"php": "^7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.* || 8.4.*",
"phpdocumentor/reflection-docblock": "^5.2",
"sebastian/comparator": "^3.0 || ^4.0 || ^5.0 || ^6.0",
"sebastian/recursion-context": "^3.0 || ^4.0 || ^5.0 || ^6.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.40",
"phpspec/phpspec": "^6.0 || ^7.0",
"phpstan/phpstan": "^1.9",
"phpunit/phpunit": "^8.0 || ^9.0 || ^10.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Prophecy\\": "src/Prophecy"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
},
{
"name": "Marcello Duarte",
"email": "marcello.duarte@gmail.com"
}
],
"description": "Highly opinionated mocking framework for PHP 5.3+",
"homepage": "https://github.com/phpspec/prophecy",
"keywords": [
"Double",
"Dummy",
"dev",
"fake",
"mock",
"spy",
"stub"
],
"support": {
"issues": "https://github.com/phpspec/prophecy/issues",
"source": "https://github.com/phpspec/prophecy/tree/v1.20.0"
},
"time": "2024-11-19T13:12:41+00:00"
},
{
"name": "phpstan/phpdoc-parser",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
"reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/9b30d6fd026b2c132b3985ce6b23bec09ab3aa68",
"reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0"
},
"require-dev": {
"doctrine/annotations": "^2.0",
"nikic/php-parser": "^5.3.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^9.6",
"symfony/process": "^5.2"
},
"type": "library",
"autoload": {
"psr-4": {
"PHPStan\\PhpDocParser\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.1.0"
},
"time": "2025-02-19T13:28:12+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "9.2.32",
@ -6557,55 +6220,50 @@
},
{
"name": "phpunit/phpunit",
"version": "9.5.20",
"version": "9.6.22",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba"
"reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba",
"reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f80235cb4d3caa59ae09be3adf1ded27521d1a9c",
"reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.3.1",
"doctrine/instantiator": "^1.5.0 || ^2",
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
"myclabs/deep-copy": "^1.10.1",
"phar-io/manifest": "^2.0.3",
"phar-io/version": "^3.0.2",
"myclabs/deep-copy": "^1.12.1",
"phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1",
"php": ">=7.3",
"phpspec/prophecy": "^1.12.1",
"phpunit/php-code-coverage": "^9.2.13",
"phpunit/php-file-iterator": "^3.0.5",
"phpunit/php-code-coverage": "^9.2.32",
"phpunit/php-file-iterator": "^3.0.6",
"phpunit/php-invoker": "^3.1.1",
"phpunit/php-text-template": "^2.0.3",
"phpunit/php-timer": "^5.0.2",
"sebastian/cli-parser": "^1.0.1",
"sebastian/code-unit": "^1.0.6",
"sebastian/comparator": "^4.0.5",
"sebastian/diff": "^4.0.3",
"sebastian/environment": "^5.1.3",
"sebastian/exporter": "^4.0.3",
"sebastian/global-state": "^5.0.1",
"sebastian/object-enumerator": "^4.0.3",
"sebastian/resource-operations": "^3.0.3",
"sebastian/type": "^3.0",
"phpunit/php-text-template": "^2.0.4",
"phpunit/php-timer": "^5.0.3",
"sebastian/cli-parser": "^1.0.2",
"sebastian/code-unit": "^1.0.8",
"sebastian/comparator": "^4.0.8",
"sebastian/diff": "^4.0.6",
"sebastian/environment": "^5.1.5",
"sebastian/exporter": "^4.0.6",
"sebastian/global-state": "^5.0.7",
"sebastian/object-enumerator": "^4.0.4",
"sebastian/resource-operations": "^3.0.4",
"sebastian/type": "^3.2.1",
"sebastian/version": "^3.0.2"
},
"require-dev": {
"ext-pdo": "*",
"phpspec/prophecy-phpunit": "^2.0.1"
},
"suggest": {
"ext-soap": "*",
"ext-xdebug": "*"
"ext-soap": "To be able to generate mocks based on WSDL files",
"ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
},
"bin": [
"phpunit"
@ -6613,7 +6271,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "9.5-dev"
"dev-master": "9.6-dev"
}
},
"autoload": {
@ -6644,7 +6302,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20"
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.22"
},
"funding": [
{
@ -6654,9 +6313,13 @@
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
"type": "tidelift"
}
],
"time": "2022-04-01T12:37:26+00:00"
"time": "2024-12-05T13:48:26+00:00"
},
{
"name": "psr/cache",
@ -8520,16 +8183,16 @@
},
{
"name": "textalk/websocket",
"version": "1.5.7",
"version": "1.5.8",
"source": {
"type": "git",
"url": "https://github.com/Textalk/websocket-php.git",
"reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46"
"reference": "d05dbaa97500176447ffb1f1800573f23085ab13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46",
"reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46",
"url": "https://api.github.com/repos/Textalk/websocket-php/zipball/d05dbaa97500176447ffb1f1800573f23085ab13",
"reference": "d05dbaa97500176447ffb1f1800573f23085ab13",
"shasum": ""
},
"require": {
@ -8563,9 +8226,9 @@
"description": "WebSocket client and server",
"support": {
"issues": "https://github.com/Textalk/websocket-php/issues",
"source": "https://github.com/Textalk/websocket-php/tree/1.5.7"
"source": "https://github.com/Textalk/websocket-php/tree/1.5.8"
},
"time": "2022-03-29T09:46:59+00:00"
"time": "2022-04-26T06:28:24+00:00"
},
{
"name": "theseer/tokenizer",

View file

@ -7,7 +7,6 @@ use Exception;
use Throwable;
use Utopia\Audit\Audit;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Exception\Authorization;
@ -46,8 +45,9 @@ class Audits extends Action
$this
->desc('Audits worker')
->inject('message')
->inject('dbForProject')
->callback(fn ($message, $dbForProject) => $this->action($message, $dbForProject));
->inject('getProjectDB')
->inject('project')
->callback([$this, 'action']);
$this->lastTriggeredTime = time();
}
@ -55,14 +55,15 @@ class Audits extends Action
/**
* @param Message $message
* @param Database $dbForProject
* @param callable $getProjectDB
* @param Document $project
* @return void
* @throws Throwable
* @throws \Utopia\Database\Exception
* @throws Authorization
* @throws Structure
*/
public function action(Message $message, Database $dbForProject): void
public function action(Message $message, callable $getProjectDB, Document $project): void
{
$payload = $message->getPayload() ?? [];
@ -103,27 +104,42 @@ class Audits extends Action
'timestamp' => DateTime::formatTz(DateTime::now())
];
$this->logs[] = $eventData;
if (isset($this->logs[$project->getInternalId()])) {
$this->logs[$project->getInternalId()]['logs'][] = $eventData;
} else {
$this->logs[$project->getInternalId()] = [
'project' => new Document([
'$id' => $project->getId(),
'$internalId' => $project->getInternalId(),
'database' => $project->getAttribute('database'),
]),
'logs' => [$eventData]
];
}
// Check if we should process the batch by checking both for the batch size and the elapsed time
$batchSize = $this->getBatchSize();
$shouldProcessBatch = count($this->logs) >= $batchSize;
if (!$shouldProcessBatch && count($this->logs) > 0) {
$shouldProcessBatch = (time() - $this->lastTriggeredTime) >= self::BATCH_AGGREGATION_INTERVAL;
$shouldProcessBatch = \count($this->logs) >= $batchSize;
if (!$shouldProcessBatch && \count($this->logs) > 0) {
$shouldProcessBatch = (\time() - $this->lastTriggeredTime) >= self::BATCH_AGGREGATION_INTERVAL;
}
if ($shouldProcessBatch) {
Console::log('Processing batch with ' . count($this->logs) . ' events');
$audit = new Audit($dbForProject);
try {
$audit->logBatch($this->logs);
Console::success('Audit logs processed successfully');
foreach ($this->logs as $internalId => $projectLogs) {
$dbForProject = $getProjectDB($projectLogs['project']);
Console::log('Processing batch with ' . count($projectLogs['logs']) . ' events');
$audit = new Audit($dbForProject);
$audit->logBatch($projectLogs['logs']);
Console::success('Audit logs processed successfully');
unset($this->logs[$internalId]);
}
} catch (Throwable $e) {
Console::error('Error processing audit logs: ' . $e->getMessage());
} finally {
// Clear the pending events after successful batch processing
$this->logs = [];
$this->lastTriggeredTime = time();
}
}

View file

@ -24,7 +24,15 @@ class Base extends Queries
public function __construct(string $collection, array $allowedAttributes)
{
$config = Config::getParam('collections', []);
$collections = array_merge($config['projects'], $config['buckets'], $config['databases'], $config['console']);
$collections = array_merge(
$config['projects'],
$config['buckets'],
$config['databases'],
$config['console'],
$config['logs']
);
$collection = $collections[$collection];
// array for constant lookup time
$allowedAttributesLookup = [];
@ -35,6 +43,7 @@ class Base extends Queries
$attributes = [];
foreach ($collection['attributes'] as $attribute) {
$key = $attribute['$id'];
if (!isset($allowedAttributesLookup[$key])) {
continue;
}

View file

@ -277,6 +277,7 @@ class AccountCustomClientTest extends Scope
{
sleep(5);
$session = $data['session'] ?? '';
/**
* Test for SUCCESS
*/