Merge pull request #4302 from Infisical/fix-timeout-for-audit-prune

Add timeout to audit log
This commit is contained in:
x032205
2025-08-04 12:28:48 -04:00
committed by GitHub
@@ -152,42 +152,54 @@ export const auditLogDALFactory = (db: TDbClient) => {
// delete all audit log that have expired // delete all audit log that have expired
const pruneAuditLog: TAuditLogDALFactory["pruneAuditLog"] = async (tx) => { const pruneAuditLog: TAuditLogDALFactory["pruneAuditLog"] = async (tx) => {
const AUDIT_LOG_PRUNE_BATCH_SIZE = 10000; const runPrune = async (dbClient: knex.Knex) => {
const MAX_RETRY_ON_FAILURE = 3; const AUDIT_LOG_PRUNE_BATCH_SIZE = 10000;
const MAX_RETRY_ON_FAILURE = 3;
const today = new Date(); const today = new Date();
let deletedAuditLogIds: { id: string }[] = []; let deletedAuditLogIds: { id: string }[] = [];
let numberOfRetryOnFailure = 0; let numberOfRetryOnFailure = 0;
let isRetrying = false; let isRetrying = false;
logger.info(`${QueueName.DailyResourceCleanUp}: audit log started`); logger.info(`${QueueName.DailyResourceCleanUp}: audit log started`);
do { do {
try { try {
const findExpiredLogSubQuery = (tx || db)(TableName.AuditLog) const findExpiredLogSubQuery = dbClient(TableName.AuditLog)
.where("expiresAt", "<", today) .where("expiresAt", "<", today)
.where("createdAt", "<", today) // to use audit log partition .where("createdAt", "<", today) // to use audit log partition
.orderBy(`${TableName.AuditLog}.createdAt`, "desc") .orderBy(`${TableName.AuditLog}.createdAt`, "desc")
.select("id") .select("id")
.limit(AUDIT_LOG_PRUNE_BATCH_SIZE); .limit(AUDIT_LOG_PRUNE_BATCH_SIZE);
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
deletedAuditLogIds = await (tx || db)(TableName.AuditLog) deletedAuditLogIds = await dbClient(TableName.AuditLog)
.whereIn("id", findExpiredLogSubQuery) .whereIn("id", findExpiredLogSubQuery)
.del() .del()
.returning("id"); .returning("id");
numberOfRetryOnFailure = 0; // reset numberOfRetryOnFailure = 0; // reset
} catch (error) { } catch (error) {
numberOfRetryOnFailure += 1; numberOfRetryOnFailure += 1;
logger.error(error, "Failed to delete audit log on pruning"); logger.error(error, "Failed to delete audit log on pruning");
} finally { } finally {
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
await new Promise((resolve) => { await new Promise((resolve) => {
setTimeout(resolve, 10); // time to breathe for db setTimeout(resolve, 10); // time to breathe for db
}); });
} }
isRetrying = numberOfRetryOnFailure > 0; isRetrying = numberOfRetryOnFailure > 0;
} while (deletedAuditLogIds.length > 0 || (isRetrying && numberOfRetryOnFailure < MAX_RETRY_ON_FAILURE)); } while (deletedAuditLogIds.length > 0 || (isRetrying && numberOfRetryOnFailure < MAX_RETRY_ON_FAILURE));
logger.info(`${QueueName.DailyResourceCleanUp}: audit log completed`); logger.info(`${QueueName.DailyResourceCleanUp}: audit log completed`);
};
if (tx) {
await runPrune(tx);
} else {
const QUERY_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
await db.transaction(async (trx) => {
await trx.raw(`SET statement_timeout = ${QUERY_TIMEOUT_MS}`);
await runPrune(trx);
});
}
}; };
const create: TAuditLogDALFactory["create"] = async (tx) => { const create: TAuditLogDALFactory["create"] = async (tx) => {