CollectUserLogJob.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. namespace App\Module\Game\Jobs;
  3. use App\Module\Game\Logics\UserLogCollectorManager;
  4. use Illuminate\Bus\Queueable;
  5. use Illuminate\Contracts\Queue\ShouldQueue;
  6. use Illuminate\Foundation\Bus\Dispatchable;
  7. use Illuminate\Queue\InteractsWithQueue;
  8. use Illuminate\Queue\SerializesModels;
  9. use Illuminate\Support\Facades\Log;
  10. /**
  11. * 用户日志收集任务
  12. *
  13. * 通过计划任务定时收集各模块的原始日志,转换为用户友好的日志消息
  14. */
  15. class CollectUserLogJob implements ShouldQueue
  16. {
  17. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  18. /**
  19. * 任务最大尝试次数
  20. *
  21. * @var int
  22. */
  23. public $tries = 3;
  24. /**
  25. * 任务超时时间(秒)
  26. *
  27. * @var int
  28. */
  29. public $timeout = 60;
  30. /**
  31. * 指定收集器名称
  32. *
  33. * @var string|null
  34. */
  35. protected ?string $collectorName;
  36. /**
  37. * 创建新的任务实例
  38. *
  39. * @param string|null $collectorName 收集器名称,null表示执行所有收集器
  40. */
  41. public function __construct(?string $collectorName = null)
  42. {
  43. $this->collectorName = $collectorName;
  44. }
  45. /**
  46. * 执行任务
  47. *
  48. * @return void
  49. */
  50. public function handle(): void
  51. {
  52. try {
  53. $manager = new UserLogCollectorManager();
  54. if ($this->collectorName) {
  55. // 执行指定收集器
  56. $result = $manager->collectByName($this->collectorName);
  57. Log::info('用户日志收集任务执行完成', [
  58. 'collector' => $this->collectorName,
  59. 'processed_count' => $result['processed_count'],
  60. 'execution_time' => $result['execution_time'],
  61. 'status' => $result['status']
  62. ]);
  63. if ($result['status'] === 'error') {
  64. throw new \Exception("收集器 {$this->collectorName} 执行失败: {$result['error']}");
  65. }
  66. } else {
  67. // 执行所有收集器
  68. $results = $manager->collectAll();
  69. Log::info('用户日志收集任务执行完成', [
  70. 'total_processed' => $results['total_processed'],
  71. 'total_execution_time' => $results['total_execution_time'],
  72. 'collectors_count' => count($results['collectors'])
  73. ]);
  74. // 检查是否有失败的收集器
  75. $failedCollectors = [];
  76. foreach ($results['collectors'] as $name => $result) {
  77. if ($result['status'] === 'error') {
  78. $failedCollectors[] = $name;
  79. }
  80. }
  81. if (!empty($failedCollectors)) {
  82. throw new \Exception('部分收集器执行失败: ' . implode(', ', $failedCollectors));
  83. }
  84. }
  85. } catch (\Exception $e) {
  86. Log::error('用户日志收集任务异常', [
  87. 'collector' => $this->collectorName,
  88. 'error' => $e->getMessage(),
  89. 'attempt' => $this->attempts()
  90. ]);
  91. // 重新抛出异常以触发重试机制
  92. throw $e;
  93. }
  94. }
  95. /**
  96. * 任务失败时的处理
  97. *
  98. * @param \Throwable $exception
  99. * @return void
  100. */
  101. public function failed(\Throwable $exception): void
  102. {
  103. Log::error('用户日志收集任务最终失败', [
  104. 'collector' => $this->collectorName,
  105. 'error' => $exception->getMessage(),
  106. 'attempts' => $this->attempts()
  107. ]);
  108. // 可以在这里实现失败后的补偿机制
  109. // 比如发送告警通知或记录到特殊日志文件
  110. }
  111. /**
  112. * 静态方法:调度日志收集任务
  113. *
  114. * @param string|null $collectorName 收集器名称,null表示执行所有收集器
  115. * @return void
  116. */
  117. public static function dispatchCollection(?string $collectorName = null): void
  118. {
  119. try {
  120. self::dispatch($collectorName);
  121. Log::info('调度用户日志收集任务', [
  122. 'collector' => $collectorName ?? 'all'
  123. ]);
  124. } catch (\Exception $e) {
  125. Log::error('调度用户日志收集任务失败', [
  126. 'collector' => $collectorName,
  127. 'error' => $e->getMessage()
  128. ]);
  129. }
  130. }
  131. }