BaseLogCollector.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. namespace App\Module\Game\Logics\UserLogCollectors;
  3. use App\Module\Game\Services\UserLogService;
  4. use Illuminate\Support\Facades\Cache;
  5. use Illuminate\Support\Facades\Log;
  6. /**
  7. * 用户日志收集器基类
  8. *
  9. * 为各个模块的日志收集器提供基础功能
  10. */
  11. abstract class BaseLogCollector
  12. {
  13. /**
  14. * 收集器名称
  15. *
  16. * @var string
  17. */
  18. protected string $collectorName;
  19. /**
  20. * 源表名
  21. *
  22. * @var string
  23. */
  24. protected string $sourceTable;
  25. /**
  26. * 源类型
  27. *
  28. * @var string
  29. */
  30. protected string $sourceType;
  31. /**
  32. * 最大处理记录数
  33. *
  34. * @var int
  35. */
  36. protected int $maxRecords = 1000;
  37. /**
  38. * 构造函数
  39. */
  40. public function __construct()
  41. {
  42. $this->collectorName = static::class;
  43. }
  44. /**
  45. * 收集日志
  46. *
  47. * @return int 处理的记录数
  48. */
  49. public function collect(): int
  50. {
  51. try {
  52. // 获取上次处理的最大ID
  53. $lastProcessedId = $this->getLastProcessedId();
  54. // 获取新的记录
  55. $records = $this->getNewRecords($lastProcessedId);
  56. if ($records->isEmpty()) {
  57. return 0;
  58. }
  59. $processedCount = 0;
  60. $userLogs = [];
  61. foreach ($records as $record) {
  62. try {
  63. // 转换记录为用户日志
  64. $userLogData = $this->convertToUserLog($record);
  65. if ($userLogData) {
  66. $userLogs[] = $userLogData;
  67. $processedCount++;
  68. }
  69. // 更新最后处理的ID
  70. $this->updateLastProcessedId($record->id);
  71. } catch (\Exception $e) {
  72. Log::error("转换日志记录失败", [
  73. 'collector' => $this->collectorName,
  74. 'record_id' => $record->id ?? null,
  75. 'error' => $e->getMessage()
  76. ]);
  77. }
  78. }
  79. // 批量保存用户日志
  80. if (!empty($userLogs)) {
  81. UserLogService::batchLog($userLogs);
  82. }
  83. Log::info("日志收集完成", [
  84. 'collector' => $this->collectorName,
  85. 'processed_count' => $processedCount,
  86. 'total_records' => $records->count()
  87. ]);
  88. return $processedCount;
  89. } catch (\Exception $e) {
  90. Log::error("日志收集失败", [
  91. 'collector' => $this->collectorName,
  92. 'error' => $e->getMessage(),
  93. 'trace' => $e->getTraceAsString()
  94. ]);
  95. return 0;
  96. }
  97. }
  98. /**
  99. * 获取新的记录(子类实现)
  100. *
  101. * @param int $lastProcessedId 上次处理的最大ID
  102. * @return \Illuminate\Database\Eloquent\Collection
  103. */
  104. abstract protected function getNewRecords(int $lastProcessedId);
  105. /**
  106. * 转换记录为用户日志数据(子类实现)
  107. *
  108. * @param mixed $record 原始记录
  109. * @return array|null 用户日志数据,null表示跳过
  110. */
  111. abstract protected function convertToUserLog($record): ?array;
  112. /**
  113. * 获取上次处理的最大ID
  114. *
  115. * @return int
  116. */
  117. protected function getLastProcessedId(): int
  118. {
  119. $cacheKey = $this->getLastProcessedIdCacheKey();
  120. return Cache::get($cacheKey, 0);
  121. }
  122. /**
  123. * 更新最后处理的ID
  124. *
  125. * @param int $id
  126. * @return void
  127. */
  128. protected function updateLastProcessedId(int $id): void
  129. {
  130. $cacheKey = $this->getLastProcessedIdCacheKey();
  131. Cache::put($cacheKey, $id, 86400); // 缓存24小时
  132. }
  133. /**
  134. * 获取最后处理ID的缓存键
  135. *
  136. * @return string
  137. */
  138. protected function getLastProcessedIdCacheKey(): string
  139. {
  140. return "user_log_collector:last_processed_id:" . $this->sourceTable;
  141. }
  142. /**
  143. * 创建用户日志数据数组
  144. *
  145. * @param int $userId 用户ID
  146. * @param string $message 日志消息
  147. * @param int $sourceId 来源记录ID
  148. * @return array
  149. */
  150. protected function createUserLogData(int $userId, string $message, int $sourceId): array
  151. {
  152. return [
  153. 'user_id' => $userId,
  154. 'message' => $message,
  155. 'source_type' => $this->sourceType,
  156. 'source_id' => $sourceId,
  157. 'source_table' => $this->sourceTable,
  158. 'created_at' => now()->toDateTimeString(),
  159. ];
  160. }
  161. /**
  162. * 获取收集器名称
  163. *
  164. * @return string
  165. */
  166. public function getCollectorName(): string
  167. {
  168. return $this->collectorName;
  169. }
  170. /**
  171. * 获取源表名
  172. *
  173. * @return string
  174. */
  175. public function getSourceTable(): string
  176. {
  177. return $this->sourceTable;
  178. }
  179. /**
  180. * 获取源类型
  181. *
  182. * @return string
  183. */
  184. public function getSourceType(): string
  185. {
  186. return $this->sourceType;
  187. }
  188. /**
  189. * 重置最后处理的ID(用于重新处理)
  190. *
  191. * @return void
  192. */
  193. public function resetLastProcessedId(): void
  194. {
  195. $cacheKey = $this->getLastProcessedIdCacheKey();
  196. Cache::forget($cacheKey);
  197. }
  198. }