新版流量池提交

This commit is contained in:
wong
2026-02-04 11:02:33 +08:00
parent a20794366a
commit 2855ab80fb
68 changed files with 8957 additions and 714 deletions

View 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];
}
}