| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- <?php
- namespace App\Module\ThirdParty\Commands;
- use Illuminate\Console\Command;
- use App\Module\ThirdParty\Models\ThirdPartyLog;
- use App\Module\ThirdParty\Models\ThirdPartyMonitor;
- /**
- * 第三方服务日志清理命令
- */
- class CleanupLogsCommand extends Command
- {
- /**
- * 命令签名
- *
- * @var string
- */
- protected $signature = 'thirdparty:cleanup-logs
- {--days=30 : 保留天数}
- {--type=all : 清理类型 (logs|monitors|all)}
- {--service= : 指定服务ID}
- {--dry-run : 只显示将要删除的记录数,不实际执行}
- {--force : 强制执行,不询问确认}';
- /**
- * 命令描述
- *
- * @var string
- */
- protected $description = '清理第三方服务的旧日志和监控记录';
- /**
- * 执行命令
- *
- * @return int
- */
- public function handle(): int
- {
- $days = (int)$this->option('days');
- $type = $this->option('type');
- $serviceId = $this->option('service');
- $dryRun = $this->option('dry-run');
- $force = $this->option('force');
- if ($days < 1) {
- $this->error('保留天数必须大于0');
- return Command::FAILURE;
- }
- if (!in_array($type, ['logs', 'monitors', 'all'])) {
- $this->error('清理类型必须是 logs、monitors 或 all');
- return Command::FAILURE;
- }
- $this->info("开始清理 {$days} 天前的记录...");
- try {
- $cutoffDate = now()->subDays($days);
- $results = [];
- if ($type === 'logs' || $type === 'all') {
- $results['logs'] = $this->cleanupLogs($cutoffDate, $serviceId, $dryRun);
- }
- if ($type === 'monitors' || $type === 'all') {
- $results['monitors'] = $this->cleanupMonitors($cutoffDate, $serviceId, $dryRun);
- }
- $this->displayResults($results, $dryRun);
- if ($dryRun) {
- $this->info('这是预览模式,没有实际删除记录');
- return Command::SUCCESS;
- }
- if (!$force && !$this->confirmDeletion($results)) {
- $this->info('操作已取消');
- return Command::SUCCESS;
- }
- // 实际执行删除
- $actualResults = [];
- if ($type === 'logs' || $type === 'all') {
- $actualResults['logs'] = $this->cleanupLogs($cutoffDate, $serviceId, false);
- }
- if ($type === 'monitors' || $type === 'all') {
- $actualResults['monitors'] = $this->cleanupMonitors($cutoffDate, $serviceId, false);
- }
- $this->displayResults($actualResults, false);
- $this->info('清理完成');
- return Command::SUCCESS;
- } catch (\Exception $e) {
- $this->error("清理失败: {$e->getMessage()}");
- return Command::FAILURE;
- }
- }
- /**
- * 清理调用日志
- *
- * @param \Carbon\Carbon $cutoffDate
- * @param int|null $serviceId
- * @param bool $dryRun
- * @return array
- */
- protected function cleanupLogs($cutoffDate, $serviceId, bool $dryRun): array
- {
- $query = ThirdPartyLog::where('created_at', '<', $cutoffDate);
- if ($serviceId) {
- $query->where('service_id', $serviceId);
- }
- $count = $query->count();
- if (!$dryRun && $count > 0) {
- $deleted = $query->delete();
- return [
- 'type' => '调用日志',
- 'count' => $deleted,
- 'size' => $this->estimateLogSize($deleted),
- ];
- }
- return [
- 'type' => '调用日志',
- 'count' => $count,
- 'size' => $this->estimateLogSize($count),
- ];
- }
- /**
- * 清理监控记录
- *
- * @param \Carbon\Carbon $cutoffDate
- * @param int|null $serviceId
- * @param bool $dryRun
- * @return array
- */
- protected function cleanupMonitors($cutoffDate, $serviceId, bool $dryRun): array
- {
- $query = ThirdPartyMonitor::where('checked_at', '<', $cutoffDate);
- if ($serviceId) {
- $query->where('service_id', $serviceId);
- }
- $count = $query->count();
- if (!$dryRun && $count > 0) {
- $deleted = $query->delete();
- return [
- 'type' => '监控记录',
- 'count' => $deleted,
- 'size' => $this->estimateMonitorSize($deleted),
- ];
- }
- return [
- 'type' => '监控记录',
- 'count' => $count,
- 'size' => $this->estimateMonitorSize($count),
- ];
- }
- /**
- * 估算日志大小
- *
- * @param int $count
- * @return string
- */
- protected function estimateLogSize(int $count): string
- {
- // 估算每条日志记录约2KB
- $sizeInBytes = $count * 2048;
- return $this->formatBytes($sizeInBytes);
- }
- /**
- * 估算监控记录大小
- *
- * @param int $count
- * @return string
- */
- protected function estimateMonitorSize(int $count): string
- {
- // 估算每条监控记录约512字节
- $sizeInBytes = $count * 512;
- return $this->formatBytes($sizeInBytes);
- }
- /**
- * 格式化字节大小
- *
- * @param int $bytes
- * @return string
- */
- protected function formatBytes(int $bytes): string
- {
- $units = ['B', 'KB', 'MB', 'GB'];
- $unitIndex = 0;
- while ($bytes >= 1024 && $unitIndex < count($units) - 1) {
- $bytes /= 1024;
- $unitIndex++;
- }
- return round($bytes, 2) . ' ' . $units[$unitIndex];
- }
- /**
- * 显示清理结果
- *
- * @param array $results
- * @param bool $dryRun
- * @return void
- */
- protected function displayResults(array $results, bool $dryRun): void
- {
- if (empty($results)) {
- return;
- }
- $action = $dryRun ? '将要删除' : '已删除';
- $this->info("\n清理结果:");
- $this->line(str_repeat('-', 60));
- $totalCount = 0;
- $totalSize = 0;
- foreach ($results as $result) {
- $this->line("{$action} {$result['type']}: {$result['count']} 条记录 ({$result['size']})");
- $totalCount += $result['count'];
-
- // 简单累加字节数(这里简化处理)
- $sizeInBytes = $this->parseSizeToBytes($result['size']);
- $totalSize += $sizeInBytes;
- }
- $this->line(str_repeat('-', 60));
- $this->line("总计: {$totalCount} 条记录 ({$this->formatBytes($totalSize)})");
- if ($totalCount === 0) {
- $this->info('没有找到需要清理的记录');
- }
- }
- /**
- * 解析大小字符串为字节数
- *
- * @param string $size
- * @return int
- */
- protected function parseSizeToBytes(string $size): int
- {
- $units = ['B' => 1, 'KB' => 1024, 'MB' => 1024*1024, 'GB' => 1024*1024*1024];
-
- foreach ($units as $unit => $multiplier) {
- if (str_contains($size, $unit)) {
- $value = (float)str_replace(' ' . $unit, '', $size);
- return (int)($value * $multiplier);
- }
- }
-
- return 0;
- }
- /**
- * 确认删除操作
- *
- * @param array $results
- * @return bool
- */
- protected function confirmDeletion(array $results): bool
- {
- $totalCount = array_sum(array_column($results, 'count'));
-
- if ($totalCount === 0) {
- return false;
- }
- return $this->confirm("确认要删除 {$totalCount} 条记录吗?此操作不可恢复!");
- }
- /**
- * 显示清理统计信息
- *
- * @return void
- */
- protected function displayCleanupStats(): void
- {
- $logCount = ThirdPartyLog::count();
- $monitorCount = ThirdPartyMonitor::count();
-
- $oldLogCount = ThirdPartyLog::where('created_at', '<', now()->subDays(30))->count();
- $oldMonitorCount = ThirdPartyMonitor::where('checked_at', '<', now()->subDays(30))->count();
- $this->info("\n当前统计:");
- $this->line("调用日志总数: {$logCount} (30天前: {$oldLogCount})");
- $this->line("监控记录总数: {$monitorCount} (30天前: {$oldMonitorCount})");
- if ($oldLogCount > 0 || $oldMonitorCount > 0) {
- $this->warn("建议定期清理旧记录以节省存储空间");
- }
- }
- }
|