| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- <?php
- namespace App\Module\Game\Commands;
- use App\Module\Game\Logics\UserLogCollectorManager;
- use UCore\Command\Command;
- /**
- * 用户日志持续收集命令
- *
- * 持续运行的日志收集命令,循环100次后退出,间隔1秒
- * 复用CollectUserLogsCommand的核心逻辑
- */
- class CollectUserLogsContinuousCommand extends Command
- {
- /**
- * 命令名称和参数
- *
- * @var string
- */
- protected $signature = 'game:collect-user-logs-continuous {--detail : 显示详细的处理过程} {--limit=1000 : 单次处理最大记录数} {--cycles=100 : 循环次数} {--interval=1 : 间隔秒数}';
- /**
- * 命令描述
- *
- * @var string
- */
- protected $description = '持续收集用户日志,循环指定次数后退出
- 选项说明:
- --detail 显示详细的处理过程
- --limit 单次处理最大记录数(默认1000)
- --cycles 循环次数(默认100)
- --interval 间隔秒数(默认1秒)
- 注意:此命令会持续运行指定的循环次数,每次循环间隔指定时间,适用于需要持续监控日志收集的场景';
- /**
- * 执行命令
- */
- public function handleRun()
- {
- $detail = $this->option('detail');
- $limit = (int)$this->option('limit');
- $cycles = (int)$this->option('cycles');
- $interval = (int)$this->option('interval');
- // 参数验证
- if ($cycles <= 0) {
- $this->error("❌ 循环次数必须大于0");
- return 1;
- }
- if ($interval < 0) {
- $this->error("❌ 间隔时间不能小于0");
- return 1;
- }
- $this->info("🚀 开始持续收集用户日志...");
- $this->line("📊 配置信息:");
- $this->line(" 🔄 循环次数: <info>{$cycles}</info>");
- $this->line(" ⏱️ 间隔时间: <info>{$interval}秒</info>");
- $this->line(" 📝 单次限制: <info>{$limit}条</info>");
- $this->line("");
- $manager = new UserLogCollectorManager();
- $totalProcessed = 0;
- $totalExecutionTime = 0;
- $successfulCycles = 0;
- $failedCycles = 0;
- $startTime = microtime(true);
- for ($i = 1; $i <= $cycles; $i++) {
- $cycleStartTime = microtime(true);
-
- try {
- if ($detail) {
- $this->line("🔄 第 {$i}/{$cycles} 次循环开始...");
- }
- // 复用原有的收集逻辑
- $result = $this->executeTimelineCollection($manager, $limit, $detail);
-
- $cycleEndTime = microtime(true);
- $cycleExecutionTime = round(($cycleEndTime - $cycleStartTime) * 1000, 2);
-
- $totalProcessed += $result['processed_count'];
- $totalExecutionTime += $cycleExecutionTime;
- $successfulCycles++;
- if ($detail) {
- $this->line("✅ 第 {$i} 次循环完成: 处理 {$result['processed_count']} 条记录,耗时 {$cycleExecutionTime}ms");
- } else {
- // 简化输出,只显示有处理记录的循环
- if ($result['processed_count'] > 0) {
- $this->line("✅ 第 {$i} 次: 处理 {$result['processed_count']} 条记录");
- }
- }
- } catch (\Exception $e) {
- $failedCycles++;
- $this->error("❌ 第 {$i} 次循环失败: {$e->getMessage()}");
-
- if ($detail) {
- $this->line("🚨 错误详情: " . $e->getTraceAsString());
- }
- }
- // 如果不是最后一次循环,则等待间隔时间
- if ($i < $cycles && $interval > 0) {
- if ($detail) {
- $this->line("⏳ 等待 {$interval} 秒...");
- }
- sleep($interval);
- }
- }
- $endTime = microtime(true);
- $totalRealTime = round(($endTime - $startTime) * 1000, 2);
- // 显示最终统计
- $this->displayFinalStatistics($cycles, $successfulCycles, $failedCycles, $totalProcessed, $totalExecutionTime, $totalRealTime);
- return $failedCycles > 0 ? 1 : 0;
- }
- /**
- * 执行时间线收集(复用原有逻辑)
- *
- * @param UserLogCollectorManager $manager
- * @param int $limit
- * @param bool $detail
- * @return array
- */
- private function executeTimelineCollection(UserLogCollectorManager $manager, int $limit, bool $detail): array
- {
- $startTime = microtime(true);
- // 直接执行所有收集器,传递限制参数
- $results = $manager->collectAll($limit);
- if ($results['total_processed'] == 0) {
- return [
- 'processed_count' => 0,
- 'execution_time' => round((microtime(true) - $startTime) * 1000, 2),
- 'status' => 'success',
- 'message' => '没有新记录需要处理',
- 'timestamp' => now()->toDateTimeString()
- ];
- }
- if ($detail) {
- foreach ($results['collectors'] as $collectorName => $result) {
- if ($result['processed_count'] > 0) {
- $this->line(" {$collectorName}: 处理了 {$result['processed_count']} 条记录");
- }
- }
- }
- $endTime = microtime(true);
- return [
- 'processed_count' => $results['total_processed'],
- 'execution_time' => round(($endTime - $startTime) * 1000, 2),
- 'status' => 'success',
- 'timestamp' => now()->toDateTimeString(),
- 'details' => $results['collectors']
- ];
- }
- /**
- * 显示最终统计信息
- *
- * @param int $totalCycles
- * @param int $successfulCycles
- * @param int $failedCycles
- * @param int $totalProcessed
- * @param float $totalExecutionTime
- * @param float $totalRealTime
- * @return void
- */
- private function displayFinalStatistics(int $totalCycles, int $successfulCycles, int $failedCycles, int $totalProcessed, float $totalExecutionTime, float $totalRealTime): void
- {
- $this->line("");
- $this->info("🎉 持续收集完成!");
- $this->line("");
-
- $this->line("📊 <comment>执行统计</comment>:");
- $this->line(" 🔄 总循环次数: <info>{$totalCycles}</info>");
- $this->line(" ✅ 成功次数: <info>{$successfulCycles}</info>");
-
- if ($failedCycles > 0) {
- $this->line(" ❌ 失败次数: <error>{$failedCycles}</error>");
- }
-
- $this->line(" 📝 总处理记录: <info>{$totalProcessed}</info>");
- $this->line(" ⏱️ 总执行时间: <info>{$totalExecutionTime}ms</info>");
- $this->line(" 🕐 总运行时间: <info>{$totalRealTime}ms</info>");
-
- if ($totalProcessed > 0) {
- $avgTimePerRecord = round($totalExecutionTime / $totalProcessed, 2);
- $this->line(" 📈 平均处理时间: <info>{$avgTimePerRecord}ms/条</info>");
- }
-
- if ($successfulCycles > 0) {
- $avgRecordsPerCycle = round($totalProcessed / $successfulCycles, 2);
- $this->line(" 📊 平均每次处理: <info>{$avgRecordsPerCycle}条</info>");
- }
-
- $successRate = round(($successfulCycles / $totalCycles) * 100, 2);
- $this->line(" 🎯 成功率: <info>{$successRate}%</info>");
-
- $this->line("");
- }
- }
|