Merge pull request #10953 from appwrite/feat-audits-upgrade

Feat: Audits  upgrade
This commit is contained in:
Damodar Lohani
2025-12-31 06:55:34 +05:45
committed by GitHub
18 changed files with 212 additions and 134 deletions
@@ -72,10 +72,11 @@ class XList extends Action
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('audit')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
@@ -98,12 +99,16 @@ class XList extends Action
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$audit = new Audit($dbForProject);
$type = $this->getCollectionsEventsContext();
$context = $this->getContext();
$resource = "database/$databaseId/$type/$collectionId/$context/{$document->getId()}";
$logs = $audit->getLogsByResource($resource, $queries);
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? 25;
$offset = $grouped['offset'] ?? 0;
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
$output = [];
@@ -152,7 +157,7 @@ class XList extends Action
$response->dynamic(new Document([
'logs' => $output,
'total' => $audit->countLogsByResource($resource, $queries),
'total' => $audit->countLogsByResource($resource),
]), $this->getResponseModel());
}
}
@@ -71,10 +71,11 @@ class XList extends Action
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('audit')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
@@ -95,10 +96,13 @@ class XList extends Action
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$audit = new Audit($dbForProject);
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? 25;
$offset = $grouped['offset'] ?? 0;
$context = $this->getContext();
$resource = "database/$databaseId/$context/$collectionId";
$logs = $audit->getLogsByResource($resource, $queries);
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
$output = [];
@@ -147,7 +151,7 @@ class XList extends Action
$response->dynamic(new Document([
'logs' => $output,
'total' => $audit->countLogsByResource($resource, $queries),
'total' => $audit->countLogsByResource($resource),
]), $this->getResponseModel());
}
}
@@ -67,10 +67,11 @@ class XList extends Action
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('audit')
->callback($this->action(...));
}
public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
{
$database = $dbForProject->getDocument('databases', $databaseId);
@@ -84,9 +85,13 @@ class XList extends Action
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$audit = new Audit($dbForProject);
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? 25;
$offset = $grouped['offset'] ?? 0;
$resource = 'database/' . $databaseId;
$logs = $audit->getLogsByResource($resource, $queries);
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
$output = [];
@@ -133,7 +138,7 @@ class XList extends Action
}
$response->dynamic(new Document([
'total' => $audit->countLogsByResource($resource, $queries),
'total' => $audit->countLogsByResource($resource),
'logs' => $output,
]), UtopiaResponse::MODEL_LOG_LIST);
}
@@ -62,10 +62,11 @@ class XList extends Action
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('audit')
->callback($this->action(...));
}
public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
{
$database = $dbForProject->getDocument('databases', $databaseId);
@@ -79,9 +80,12 @@ class XList extends Action
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$audit = new Audit($dbForProject);
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? 25;
$offset = $grouped['offset'] ?? 0;
$resource = 'database/' . $databaseId;
$logs = $audit->getLogsByResource($resource, $queries);
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
$output = [];
@@ -128,7 +132,7 @@ class XList extends Action
}
$response->dynamic(new Document([
'total' => $audit->countLogsByResource($resource, $queries),
'total' => $audit->countLogsByResource($resource),
'logs' => $output,
]), UtopiaResponse::MODEL_LOG_LIST);
}
@@ -50,6 +50,7 @@ class XList extends CollectionLogXList
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('audit')
->callback($this->action(...));
}
}
@@ -51,6 +51,7 @@ class XList extends DocumentLogXList
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('audit')
->callback($this->action(...));
}
}
+5 -6
View File
@@ -4,7 +4,6 @@ namespace Appwrite\Platform\Workers;
use Exception;
use Throwable;
use Utopia\Audit\Audit;
use Utopia\CLI\Console;
use Utopia\Database\Document;
use Utopia\Database\Exception\Authorization;
@@ -42,8 +41,8 @@ class Audits extends Action
$this
->desc('Audits worker')
->inject('message')
->inject('getProjectDB')
->inject('project')
->inject('getAudit')
->callback($this->action(...));
$this->lastTriggeredTime = time();
@@ -54,13 +53,14 @@ class Audits extends Action
* @param Message $message
* @param callable $getProjectDB
* @param Document $project
* @param callable $getAudit
* @return Commit|NoCommit
* @throws Throwable
* @throws \Utopia\Database\Exception
* @throws Authorization
* @throws Structure
*/
public function action(Message $message, callable $getProjectDB, Document $project): Commit|NoCommit
public function action(Message $message, Document $project, callable $getAudit): Commit|NoCommit
{
$payload = $message->getPayload() ?? [];
@@ -102,7 +102,7 @@ class Audits extends Action
'mode' => $mode,
'data' => $auditPayload,
],
'timestamp' => date("Y-m-d H:i:s", $message->getTimestamp()),
'time' => date("Y-m-d H:i:s", $message->getTimestamp()),
];
if (isset($this->logs[$project->getSequence()])) {
@@ -135,8 +135,7 @@ class Audits extends Action
Console::log('Processing Project "' . $sequence . '" batch with ' . count($projectLogs['logs']) . ' events');
$projectDocument = $projectLogs['project'];
$dbForProject = $getProjectDB($projectDocument);
$audit = new Audit($dbForProject);
$audit = $getAudit($projectDocument);
$audit->logBatch($projectLogs['logs']);
Console::success('Audit logs processed successfully');
+13 -13
View File
@@ -9,6 +9,7 @@ use Appwrite\Extend\Exception;
use Executor\Executor;
use Throwable;
use Utopia\Abuse\Adapters\TimeLimit\Database as AbuseDatabase;
use Utopia\Audit\Adapter\SQL;
use Utopia\Audit\Audit;
use Utopia\Cache\Adapter\Filesystem;
use Utopia\Cache\Cache;
@@ -62,6 +63,7 @@ class Deletes extends Action
->inject('executionRetention')
->inject('auditRetention')
->inject('log')
->inject('getAudit')
->callback($this->action(...));
}
@@ -84,7 +86,8 @@ class Deletes extends Action
Executor $executor,
string $executionRetention,
string $auditRetention,
Log $log
Log $log,
callable $getAudit,
): void {
$payload = $message->getPayload() ?? [];
@@ -145,7 +148,7 @@ class Deletes extends Action
break;
case DELETE_TYPE_AUDIT:
if (!$project->isEmpty()) {
$this->deleteAuditLogs($project, $getProjectDB, $auditRetention);
$this->deleteAuditLogs($project, $auditRetention, $getAudit);
}
break;
case DELETE_TYPE_REALTIME:
@@ -517,7 +520,7 @@ class Deletes extends Action
$projectCollectionIds = [
...\array_keys(Config::getParam('collections', [])['projects']),
Audit::COLLECTION,
SQL::COLLECTION,
AbuseDatabase::COLLECTION,
];
@@ -783,23 +786,20 @@ class Deletes extends Action
* @param Database $dbForPlatform
* @param callable $getProjectDB
* @param string $auditRetention
* @param callable $getAudit
* @return void
* @throws Exception
*/
private function deleteAuditLogs(Document $project, callable $getProjectDB, string $auditRetention): void
private function deleteAuditLogs(Document $project, string $auditRetention, callable $getAudit): void
{
$projectId = $project->getId();
$dbForProject = $getProjectDB($project);
/** @var Audit $audit */
$audit = $getAudit($project);
try {
$this->deleteByGroup(Audit::COLLECTION, [
Query::select([...$this->selects, 'time']),
Query::lessThan('time', $auditRetention),
Query::orderDesc('time'),
Query::orderAsc(),
], $dbForProject);
} catch (DatabaseException $e) {
Console::error('Failed to delete audit logs for project ' . $projectId . ': ' . $e->getMessage());
$audit->cleanup(new \DateTime($auditRetention));
} catch (Throwable $th) {
Console::error('Failed to delete audit logs for project ' . $projectId . ': ' . $th->getMessage());
}
}