新版流量池服务端提交
This commit is contained in:
188
Server/application/command/CleanLogsCommand.php
Normal file
188
Server/application/command/CleanLogsCommand.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use think\console\input\Option;
|
||||
use think\facade\App;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 清除过期日志文件命令
|
||||
*
|
||||
* 使用方法:
|
||||
* php think clean:logs # 使用默认保留10天
|
||||
* php think clean:logs --days=7 # 保留7天
|
||||
* php think clean:logs --days=30 # 保留30天
|
||||
* php think clean:logs --dry-run # 预览模式,不实际删除
|
||||
*/
|
||||
class CleanLogsCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('clean:logs')
|
||||
->setDescription('清除过期的日志文件')
|
||||
->addOption('days', 'd', Option::VALUE_OPTIONAL, '保留天数(默认:10天)', 10)
|
||||
->addOption('dry-run', null, Option::VALUE_NONE, '预览模式,不实际删除文件');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$days = (int)$input->getOption('days');
|
||||
$dryRun = $input->getOption('dry-run');
|
||||
|
||||
if ($days <= 0) {
|
||||
$output->writeln('<error>保留天数必须大于0</error>');
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($dryRun) {
|
||||
$output->writeln('<info>运行在预览模式,不会实际删除文件</info>');
|
||||
}
|
||||
|
||||
$output->writeln("<info>====================================</info>");
|
||||
$output->writeln("<info> 清除过期日志文件</info>");
|
||||
$output->writeln("<info>====================================</info>");
|
||||
$output->writeln("保留天数: {$days} 天");
|
||||
$output->writeln("");
|
||||
|
||||
// 获取日志目录
|
||||
$logPath = App::getRuntimePath() . 'log' . DIRECTORY_SEPARATOR;
|
||||
|
||||
if (!is_dir($logPath)) {
|
||||
$output->writeln("<comment>日志目录不存在: {$logPath}</comment>");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 计算截止时间(保留指定天数之前的日志)
|
||||
$cutoffTime = time() - ($days * 24 * 60 * 60);
|
||||
$cutoffDate = date('Y-m-d H:i:s', $cutoffTime);
|
||||
|
||||
$output->writeln("<comment>清除 {$cutoffDate} 之前的日志文件</comment>");
|
||||
$output->writeln("");
|
||||
|
||||
// 统计信息
|
||||
$totalFiles = 0;
|
||||
$deletedFiles = 0;
|
||||
$totalSize = 0;
|
||||
$freedSize = 0;
|
||||
|
||||
try {
|
||||
// 递归扫描日志目录
|
||||
$result = $this->cleanLogDirectory($logPath, $cutoffTime, $dryRun, $output);
|
||||
|
||||
$totalFiles = $result['total'];
|
||||
$deletedFiles = $result['deleted'];
|
||||
$totalSize = $result['totalSize'];
|
||||
$freedSize = $result['freedSize'];
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>清除日志时发生错误: ' . $e->getMessage() . '</error>');
|
||||
Log::error('清除日志失败: ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 输出统计信息
|
||||
$output->writeln("");
|
||||
$output->writeln("<info>====================================</info>");
|
||||
$output->writeln("<info> 清除完成</info>");
|
||||
$output->writeln("<info>====================================</info>");
|
||||
$output->writeln("扫描文件数: {$totalFiles}");
|
||||
$output->writeln("删除文件数: {$deletedFiles}");
|
||||
$output->writeln("释放空间: " . $this->formatBytes($freedSize));
|
||||
|
||||
if ($dryRun) {
|
||||
$output->writeln("");
|
||||
$output->writeln("<comment>预览模式:实际未删除任何文件</comment>");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归清理日志目录
|
||||
*/
|
||||
protected function cleanLogDirectory($dir, $cutoffTime, $dryRun, Output $output)
|
||||
{
|
||||
$total = 0;
|
||||
$deleted = 0;
|
||||
$totalSize = 0;
|
||||
$freedSize = 0;
|
||||
|
||||
if (!is_dir($dir)) {
|
||||
return ['total' => 0, 'deleted' => 0, 'totalSize' => 0, 'freedSize' => 0];
|
||||
}
|
||||
|
||||
$items = scandir($dir);
|
||||
|
||||
foreach ($items as $item) {
|
||||
if ($item === '.' || $item === '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = $dir . $item;
|
||||
|
||||
if (is_dir($path)) {
|
||||
// 递归处理子目录
|
||||
$result = $this->cleanLogDirectory($path . DIRECTORY_SEPARATOR, $cutoffTime, $dryRun, $output);
|
||||
$total += $result['total'];
|
||||
$deleted += $result['deleted'];
|
||||
$totalSize += $result['totalSize'];
|
||||
$freedSize += $result['freedSize'];
|
||||
} elseif (is_file($path)) {
|
||||
$total++;
|
||||
$fileSize = filesize($path);
|
||||
$totalSize += $fileSize;
|
||||
|
||||
// 获取文件修改时间
|
||||
$fileMTime = filemtime($path);
|
||||
|
||||
// 如果文件修改时间早于截止时间,则删除
|
||||
if ($fileMTime < $cutoffTime) {
|
||||
$freedSize += $fileSize;
|
||||
|
||||
if ($dryRun) {
|
||||
$output->writeln("<comment>[预览] 将删除: {$path} (" . date('Y-m-d H:i:s', $fileMTime) . ", " . $this->formatBytes($fileSize) . ")</comment>");
|
||||
} else {
|
||||
if (@unlink($path)) {
|
||||
$deleted++;
|
||||
$output->writeln("<info>已删除: {$path}</info>");
|
||||
} else {
|
||||
$output->writeln("<error>删除失败: {$path}</error>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'total' => $total,
|
||||
'deleted' => $deleted,
|
||||
'totalSize' => $totalSize,
|
||||
'freedSize' => $freedSize,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化字节数
|
||||
*/
|
||||
protected function formatBytes($bytes, $precision = 2)
|
||||
{
|
||||
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
|
||||
if ($bytes == 0) {
|
||||
return '0 B';
|
||||
}
|
||||
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
|
||||
$bytes /= pow(1024, $pow);
|
||||
|
||||
return round($bytes, $precision) . ' ' . $units[$pow];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user