QueueLogger.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. namespace app\common\utils;
  3. use think\facade\Log;
  4. use think\console\Output;
  5. /**
  6. * 队列日志工具类
  7. * 提供统一的队列任务日志记录功能
  8. */
  9. class QueueLogger
  10. {
  11. /**
  12. * 记录队列任务开始日志
  13. *
  14. * @param string $jobName 任务名称
  15. * @param mixed $job 任务对象
  16. * @param array $data 任务数据
  17. */
  18. public static function start($jobName, $job, $data)
  19. {
  20. $logData = [
  21. 'job_id' => method_exists($job, 'getJobId') ? $job->getJobId() : 'unknown',
  22. 'data' => $data,
  23. 'attempts' => method_exists($job, 'attempts') ? $job->attempts() : 0,
  24. 'start_time' => date('Y-m-d H:i:s')
  25. ];
  26. Log::channel('queue')->info("{$jobName}任务开始执行", $logData);
  27. self::outputToCli("{$jobName}任务开始执行", $logData);
  28. }
  29. /**
  30. * 记录队列任务成功日志
  31. *
  32. * @param string $jobName 任务名称
  33. * @param mixed $job 任务对象
  34. * @param array $data 任务数据
  35. * @param mixed $result 执行结果
  36. */
  37. public static function success($jobName, $job, $data, $result = null)
  38. {
  39. $logData = [
  40. 'job_id' => method_exists($job, 'getJobId') ? $job->getJobId() : 'unknown',
  41. 'data' => $data,
  42. 'result' => $result,
  43. 'end_time' => date('Y-m-d H:i:s')
  44. ];
  45. Log::channel('queue')->info("{$jobName}任务执行成功", $logData);
  46. self::outputToCli("{$jobName}任务执行成功", $logData);
  47. }
  48. /**
  49. * 记录队列任务警告日志
  50. *
  51. * @param string $jobName 任务名称
  52. * @param mixed $job 任务对象
  53. * @param array $data 任务数据
  54. * @param string $message 警告信息
  55. */
  56. public static function warning($jobName, $job, $data, $message)
  57. {
  58. $logData = [
  59. 'job_id' => method_exists($job, 'getJobId') ? $job->getJobId() : 'unknown',
  60. 'data' => $data,
  61. 'attempts' => method_exists($job, 'attempts') ? $job->attempts() : 0
  62. ];
  63. Log::channel('queue')->warning("{$jobName}任务警告: {$message}", $logData);
  64. self::outputToCli("{$jobName}任务警告: {$message}", $logData, 'warning');
  65. }
  66. /**
  67. * 记录队列任务异常日志
  68. *
  69. * @param string $jobName 任务名称
  70. * @param mixed $job 任务对象
  71. * @param array $data 任务数据
  72. * @param \Exception $e 异常对象
  73. */
  74. public static function error($jobName, $job, $data, \Exception $e)
  75. {
  76. $logData = [
  77. 'data' => $data,
  78. 'error_message' => $e->getMessage(),
  79. 'error_file' => $e->getFile(),
  80. 'error_line' => $e->getLine(),
  81. 'error_trace' => $e->getTraceAsString()
  82. ];
  83. // 安全地获取job信息,避免方法不存在导致的错误
  84. if (is_object($job)) {
  85. if (method_exists($job, 'getJobId')) {
  86. $logData['job_id'] = $job->getJobId();
  87. }
  88. if (method_exists($job, 'attempts')) {
  89. $logData['attempts'] = $job->attempts();
  90. }
  91. }
  92. Log::channel('queue')->error("{$jobName}任务执行异常", $logData);
  93. self::outputToCli("{$jobName}任务执行异常: " . $e->getMessage(), $logData, 'error');
  94. }
  95. /**
  96. * 记录队列任务失败日志
  97. *
  98. * @param string $jobName 任务名称
  99. * @param array $data 任务数据
  100. * @param string $message 失败信息
  101. */
  102. public static function failed($jobName, $data, $message = '任务进入失败状态,需要手动处理')
  103. {
  104. $logData = [
  105. 'data' => $data,
  106. 'failed_time' => date('Y-m-d H:i:s'),
  107. 'message' => $message
  108. ];
  109. Log::channel('queue')->error("{$jobName}任务失败", $logData);
  110. self::outputToCli("{$jobName}任务失败: {$message}", $logData, 'error');
  111. }
  112. /**
  113. * 记录队列任务结束日志
  114. *
  115. * @param string $jobName 任务名称
  116. * @param mixed $job 任务对象
  117. * @param array $data 任务数据
  118. */
  119. public static function end($jobName, $job, $data)
  120. {
  121. $logData = [
  122. 'job_id' => method_exists($job, 'getJobId') ? $job->getJobId() : 'unknown',
  123. 'data' => $data,
  124. 'end_time' => date('Y-m-d H:i:s')
  125. ];
  126. Log::channel('queue')->info("{$jobName}任务执行结束", $logData);
  127. self::outputToCli("{$jobName}任务执行结束", $logData);
  128. }
  129. /**
  130. * 记录业务执行开始日志
  131. *
  132. * @param string $businessName 业务名称
  133. * @param array $data 业务数据
  134. */
  135. public static function businessStart($businessName, $data)
  136. {
  137. $logData = [
  138. 'data' => $data,
  139. 'start_time' => date('Y-m-d H:i:s')
  140. ];
  141. Log::channel('queue')->info("开始执行{$businessName}业务", $logData);
  142. self::outputToCli("开始执行{$businessName}业务", $logData);
  143. }
  144. /**
  145. * 记录队列任务信息日志
  146. *
  147. * @param string $message 日志信息
  148. * @param array $context 上下文数据
  149. */
  150. public static function info($message, array $context = [])
  151. {
  152. Log::channel('queue')->info($message, $context);
  153. self::outputToCli($message, $context);
  154. }
  155. /**
  156. * 输出到CLI命令行
  157. *
  158. * @param string $message 消息内容
  159. * @param array $context 上下文数据
  160. * @param string $level 日志级别
  161. */
  162. private static function outputToCli($message, $context = [], $level = 'info')
  163. {
  164. if (PHP_SAPI === 'cli') {
  165. $output = new Output();
  166. $timestamp = date('Y-m-d H:i:s');
  167. switch ($level) {
  168. case 'error':
  169. $prefix = 'ERROR';
  170. $output->error("[{$timestamp}] [{$prefix}] {$message}");
  171. break;
  172. case 'warning':
  173. $prefix = 'WARN';
  174. $output->warning("[{$timestamp}] [{$prefix}] {$message}");
  175. break;
  176. default:
  177. $prefix = 'INFO';
  178. $output->info("[{$timestamp}] [{$prefix}] {$message}");
  179. }
  180. }
  181. }
  182. }