|
|
@@ -0,0 +1,215 @@
|
|
|
+<?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("");
|
|
|
+ }
|
|
|
+}
|