option('days'); $cutoffDate = Carbon::now()->subDays($daysToKeep); $this->info("Trimming log files older than {$daysToKeep} days ({$cutoffDate->format('Y-m-d H:i:s')})..."); $totalSizeBefore = 0; $totalSizeAfter = 0; $filesProcessed = 0; foreach ($this->logFiles as $logFileName) { $logPath = storage_path('logs/' . $logFileName); if (!File::exists($logPath)) { $this->warn("Log file not found: {$logFileName}"); continue; } $sizeBefore = File::size($logPath); $totalSizeBefore += $sizeBefore; $trimmed = $this->trimLogFile($logPath, $cutoffDate); $sizeAfter = File::size($logPath); $totalSizeAfter += $sizeAfter; $filesProcessed++; if ($trimmed) { $savedBytes = $sizeBefore - $sizeAfter; $savedKB = round($savedBytes / 1024, 2); $this->info("✓ {$logFileName}: Trimmed from " . $this->formatFileSize($sizeBefore) . " to " . $this->formatFileSize($sizeAfter) . " (saved {$savedKB} KB)"); } else { $this->info("✓ {$logFileName}: No entries older than {$daysToKeep} days (size: " . $this->formatFileSize($sizeBefore) . ")"); } } if ($filesProcessed > 0) { $totalSaved = $totalSizeBefore - $totalSizeAfter; $this->info("\nTotal: Processed {$filesProcessed} files, saved " . $this->formatFileSize($totalSaved)); } return 0; } /** * Trim log file to keep only entries newer than cutoff date. * * @param string $logPath * @param Carbon $cutoffDate * @return bool Whether any entries were removed */ protected function trimLogFile($logPath, $cutoffDate) { $content = File::get($logPath); $lines = explode("\n", $content); $keptLines = []; $removedCount = 0; foreach ($lines as $line) { // Skip empty lines if (trim($line) === '') { continue; } // Extract timestamp from log line format: [YYYY-MM-DD HH:MM:SS] message if (preg_match('/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]/', $line, $matches)) { $logDate = Carbon::parse($matches[1]); if ($logDate->greaterThanOrEqualTo($cutoffDate)) { $keptLines[] = $line; } else { $removedCount++; } } else { // Keep lines without timestamps (shouldn't happen, but be safe) $keptLines[] = $line; } } if ($removedCount > 0) { // Rewrite the log file with only kept lines File::put($logPath, implode("\n", $keptLines) . "\n"); return true; } return false; } /** * Format file size in human-readable format. * * @param int $bytes * @return string */ protected function formatFileSize($bytes) { if ($bytes >= 1048576) { return round($bytes / 1048576, 2) . ' MB'; } elseif ($bytes >= 1024) { return round($bytes / 1024, 2) . ' KB'; } else { return $bytes . ' bytes'; } } }