feat(logging): implement log pruning functionality
- Add LogPruneService to handle the deletion of old logs based on retention settings. - Create PruneLogsCommand to provide a console command for log pruning. - Introduce PruneLogsMessage and PruneLogsHandler for message handling related to log pruning. - Update the AST cache with new classes and their relationships.
This commit is contained in:
@@ -1989,4 +1989,12 @@ class AdminApiController extends BaseController
|
||||
'created_at' => (int) $l['createdAt'],
|
||||
], $rows), (int) $total, $page, $limit);
|
||||
}
|
||||
|
||||
#[Route('/api/v1/admin/logs', methods: ['DELETE'])]
|
||||
public function clearLogs(): JsonResponse
|
||||
{
|
||||
$deleted = $this->em->getRepository(AppLog::class)->deleteAll();
|
||||
|
||||
return $this->success(['deleted' => $deleted]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ class SiteConfigController extends BaseController
|
||||
'support_phone',
|
||||
'max_cancel_hours_before',
|
||||
'appointment_reminder_hours',
|
||||
'log_retention_days',
|
||||
// payment gateways
|
||||
'payment_test_mode',
|
||||
'payment_allowed_frontend_hosts',
|
||||
|
||||
@@ -22,6 +22,8 @@ class SiteConfigRepository extends ServiceEntityRepository
|
||||
'support_phone' => '',
|
||||
'max_cancel_hours_before' => '24',
|
||||
'appointment_reminder_hours' => '2',
|
||||
// logging (0 = نگهداری نامحدود)
|
||||
'log_retention_days' => '90',
|
||||
// payment gateways
|
||||
'payment_test_mode' => '0',
|
||||
'mellat_terminal_id' => '',
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App;
|
||||
|
||||
use App\Appointment\Message\ExpireAppointmentsMessage;
|
||||
use App\Shared\Logging\Message\PruneLogsMessage;
|
||||
use Symfony\Component\Scheduler\Attribute\AsSchedule;
|
||||
use Symfony\Component\Scheduler\RecurringMessage;
|
||||
use Symfony\Component\Scheduler\Schedule as SymfonySchedule;
|
||||
@@ -24,6 +25,9 @@ class Schedule implements ScheduleProviderInterface
|
||||
->processOnlyLastMissedRun(true) // ensure only last missed task is run
|
||||
->add(
|
||||
RecurringMessage::every('1 minute', new ExpireAppointmentsMessage())
|
||||
)
|
||||
->add(
|
||||
RecurringMessage::every('1 day', new PruneLogsMessage())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,24 @@ use Doctrine\Persistence\ManagerRegistry;
|
||||
class AppLogRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry) { parent::__construct($registry, AppLog::class); }
|
||||
|
||||
/** حذف همهی لاگها؛ تعداد ردیفهای حذفشده را برمیگرداند. */
|
||||
public function deleteAll(): int
|
||||
{
|
||||
return (int) $this->createQueryBuilder('l')
|
||||
->delete()
|
||||
->getQuery()
|
||||
->execute();
|
||||
}
|
||||
|
||||
/** حذف لاگهای قدیمیتر از timestamp دادهشده؛ تعداد حذفشده را برمیگرداند. */
|
||||
public function deleteOlderThan(int $timestamp): int
|
||||
{
|
||||
return (int) $this->createQueryBuilder('l')
|
||||
->delete()
|
||||
->where('l.createdAt < :ts')
|
||||
->setParameter('ts', $timestamp)
|
||||
->getQuery()
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Shared\Logging\Command;
|
||||
|
||||
use App\Shared\Logging\LogPruneService;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand(name: 'app:prune-logs', description: 'حذف لاگهای قدیمیتر از مدت نگهداری تنظیمشده')]
|
||||
final class PruneLogsCommand extends Command
|
||||
{
|
||||
public function __construct(private readonly LogPruneService $pruneService)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$deleted = $this->pruneService->pruneByRetention();
|
||||
$output->writeln(sprintf('%d لاگ حذف شد.', $deleted));
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Shared\Logging;
|
||||
|
||||
use App\Config\Repository\SiteConfigRepository;
|
||||
|
||||
/**
|
||||
* حذف لاگهای قدیمیتر از مدت نگهداری تنظیمشده (`log_retention_days`).
|
||||
* مقدار ۰ یا نامعتبر یعنی نگهداری نامحدود — چیزی حذف نمیشود.
|
||||
*/
|
||||
class LogPruneService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AppLogRepository $logRepo,
|
||||
private readonly SiteConfigRepository $configRepo,
|
||||
) {}
|
||||
|
||||
/** تعداد لاگهای حذفشده را برمیگرداند. */
|
||||
public function pruneByRetention(): int
|
||||
{
|
||||
$days = (int) ($this->configRepo->get('log_retention_days') ?? 0);
|
||||
if ($days <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$cutoff = time() - ($days * 86400);
|
||||
|
||||
return $this->logRepo->deleteOlderThan($cutoff);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace App\Shared\Logging\Message;
|
||||
|
||||
class PruneLogsMessage
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Shared\Logging\MessageHandler;
|
||||
|
||||
use App\Shared\Logging\LogPruneService;
|
||||
use App\Shared\Logging\Message\PruneLogsMessage;
|
||||
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
|
||||
|
||||
#[AsMessageHandler]
|
||||
final class PruneLogsHandler
|
||||
{
|
||||
public function __construct(private readonly LogPruneService $pruneService) {}
|
||||
|
||||
public function __invoke(PruneLogsMessage $message): void
|
||||
{
|
||||
$this->pruneService->pruneByRetention();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user