From 645729a5180286d2a4e0f2a5e8eef84e50159000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Mon, 22 Dec 2025 11:07:33 +0100 Subject: [PATCH] feat: remove outdated log entries scheduled --- config/packages/zenstruck_schedule.yaml | 4 ++ src/Command/CleanupLogEntriesCommand.php | 70 ++++++++++++++++++++++++ src/Entity/LogEntry.php | 5 +- src/Repository/LogEntryRepository.php | 30 ++++++++++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/Command/CleanupLogEntriesCommand.php create mode 100644 src/Repository/LogEntryRepository.php diff --git a/config/packages/zenstruck_schedule.yaml b/config/packages/zenstruck_schedule.yaml index 3cbde21..3807d05 100644 --- a/config/packages/zenstruck_schedule.yaml +++ b/config/packages/zenstruck_schedule.yaml @@ -20,3 +20,7 @@ zenstruck_schedule: - task: app:bpn:xml-sync frequency: '0 20-23,0-7 * * *' description: 'Sync BusPro XML data hourly outside peak hours' + + - task: app:cleanup:log-entries + frequency: "30 1 * * *" + description: "Removes outdated log entries with a retention period of 6 months" diff --git a/src/Command/CleanupLogEntriesCommand.php b/src/Command/CleanupLogEntriesCommand.php new file mode 100644 index 0000000..e94ec21 --- /dev/null +++ b/src/Command/CleanupLogEntriesCommand.php @@ -0,0 +1,70 @@ +addOption( + 'retention', + 'r', + InputOption::VALUE_REQUIRED, + 'Retention period in months', + (string) self::DEFAULT_RETENTION_MONTHS + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + + $retentionMonths = (int) $input->getOption('retention'); + if ($retentionMonths < 1) { + $io->error('Retention period must be at least 1 month.'); + + return Command::FAILURE; + } + + $threshold = (new \DateTimeImmutable())->modify(sprintf('-%d months', $retentionMonths)); + + $deletedCount = $this->logEntryRepository->deleteOlderThan($threshold); + + $message = sprintf( + 'Removed %d log entries older than %d month%s (before %s)', + $deletedCount, + $retentionMonths, + 1 === $retentionMonths ? '' : 's', + $threshold->format('Y-m-d H:i:s') + ); + + $this->logger->info($message); + $io->success($message); + + return Command::SUCCESS; + } +} diff --git a/src/Entity/LogEntry.php b/src/Entity/LogEntry.php index 74f8037..c9abbc2 100644 --- a/src/Entity/LogEntry.php +++ b/src/Entity/LogEntry.php @@ -1,10 +1,13 @@ + */ +class LogEntryRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, LogEntry::class); + } + + public function deleteOlderThan(\DateTimeImmutable $threshold): int + { + return $this->createQueryBuilder('l') + ->delete() + ->where('l.createdAt < :threshold') + ->setParameter('threshold', $threshold) + ->getQuery() + ->execute(); + } +}