LogUtil.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Utils;
  4. //use Hyperf\Utils\Coroutine;
  5. use Hyperf\Coroutine\Coroutine;
  6. /**
  7. * Author:Panda
  8. * Email:joeyoung0314@qq.com
  9. * Class LogUtil
  10. * @package App\Utils
  11. *
  12. * ========================================================================
  13. * + 根据协程
  14. * +
  15. * +
  16. * +
  17. * ========================================================================
  18. */
  19. class LogUtil
  20. {
  21. /**==============日志系统==============**/
  22. private static int $size = 2;// (单位M) 避免单个日志文件太大 请设置单个文件最大存储
  23. private static array $logArr = [];
  24. private static array $logRootPath = [];//协程日志根目录
  25. private static array $logExtPath = [];//协程日志根目录02
  26. private static array $logExtType = [];//协程日志
  27. private static string $coroutineKey = 'logs';//协程标签组成
  28. /**
  29. * 协程单例模式处理
  30. * @param string $logExtTypePath
  31. */
  32. public static function getInstance(string $logExtTypePath = 'Api/')
  33. {
  34. //协程id
  35. $coroutine_id = Coroutine::id();
  36. if (!isset(self::$logExtType[$coroutine_id])) {
  37. self::$logExtType[$coroutine_id] = $logExtTypePath;
  38. Coroutine::defer(function () use ($coroutine_id) {
  39. unset(
  40. self::$logArr[$coroutine_id],
  41. self::$logRootPath[$coroutine_id],
  42. self::$logExtPath[$coroutine_id],
  43. self::$logExtType[$coroutine_id],
  44. );
  45. });
  46. }
  47. }
  48. /**
  49. * 日志级别:普通
  50. * @param string $logTitle 日志名称
  51. * @param string $logName 日志目录
  52. * @param string $logFile 日志文件名
  53. * @param mixed $content 日志参数
  54. */
  55. public static function info(string $logTitle = '', string $logName = 'Common', string $logFile = 'common', $content = [])
  56. {
  57. self::writeLog($content, $logName, $logFile, $logTitle, 'local.INFO');
  58. }
  59. /**
  60. * 日志级别:警告
  61. * @param string $logTitle 日志名称
  62. * @param string $logName 日志目录
  63. * @param string $logFile 日志文件名
  64. * @param mixed $content 日志参数
  65. */
  66. public static function warning(string $logTitle = '', string $logName = 'Common', string $logFile = 'common', $content = [])
  67. {
  68. self::writeLog($content, $logName, $logFile, $logTitle, 'local.WARNING');
  69. }
  70. /**
  71. * 日志级别:错误
  72. * @param string $logTitle 日志名称
  73. * @param string $logName 日志目录
  74. * @param string $logFile 日志文件名
  75. * @param mixed $content 日志参数
  76. */
  77. public static function error(string $logTitle = '', string $logName = 'Common', string $logFile = 'common', $content = [])
  78. {
  79. self::writeLog($content, $logName, $logFile, $logTitle, 'local.ERROR');
  80. }
  81. /**
  82. * 日志内容保存
  83. * @param mixed $content
  84. * @param string $logName 日志模块名称
  85. * @param string $logFile 日志内容
  86. * @param string $logTitle 日志内容头部
  87. * @param string $status
  88. *
  89. */
  90. private static function writeLog($content, string $logName = 'Common', string $logFile = 'common', string $logTitle = '', string $status = 'INFO')
  91. {
  92. $coroutine_id = Coroutine::id();
  93. $logPath = $logName . '_' . $logFile;
  94. $logWhite = self::whiteLog();
  95. if (in_array($logPath, $logWhite)) return;//验证日志黑名单
  96. //if(is_array($content) && isset($content['route']) && $content['route'] == 'Param_uploadFileImg') return;//黑名单
  97. //获取日志文件目录
  98. if (empty(self::$logRootPath[$coroutine_id])) {
  99. self::$logRootPath[$coroutine_id] = realpath('') . '/runtime/logs/Log/' . self::$logExtType[$coroutine_id];
  100. }
  101. if (empty(self::$logExtPath[$coroutine_id])) {
  102. self::$logExtPath[$coroutine_id] = realpath('') . '/runtime/logs/Log02/' . self::$logExtType[$coroutine_id];
  103. }
  104. if (empty(self::$logArr[$coroutine_id][$logName][$logFile])) {
  105. self::$logArr[$coroutine_id][$logName][$logFile] = '================ Start ================' . PHP_EOL;
  106. }
  107. $content = is_array($content) ? json_encode($content, JSON_UNESCAPED_UNICODE) : $content;
  108. if (!empty($logTitle)) $logTitle .= ':';
  109. self::$logArr[$coroutine_id][$logName][$logFile] .= '[' . (date('Y-m-d H:i:s') . "] {$status}: {$logTitle}{$content}" . PHP_EOL . PHP_EOL);
  110. }
  111. public static function close()
  112. {
  113. $coroutine_id = Coroutine::id();
  114. try {
  115. if (empty(self::$logArr[$coroutine_id])) return;
  116. //没有Log目录 创建Log02目录
  117. if (!file_exists(self::$logRootPath[$coroutine_id])) {
  118. $tem_path = self::$logExtPath[$coroutine_id];
  119. if (!file_exists($tem_path)) {
  120. mkdir($tem_path, 0777, true);
  121. }
  122. $logPath = $tem_path . date('Y_m_d');
  123. } else {
  124. $logPath = self::$logRootPath[$coroutine_id] . date('Y_m_d');
  125. }
  126. //创建日志文件目录
  127. if (!file_exists($logPath)) mkdir($logPath);
  128. //逐个日志文件写入
  129. foreach (self::$logArr[$coroutine_id] as $key => $value) {
  130. $logDir = $logPath . '/' . $key;
  131. if (!file_exists($logDir)) mkdir($logDir, 0777, true);
  132. self::logEnd($value, $logDir);
  133. }
  134. self::$logArr[$coroutine_id] = [];
  135. } catch (\Exception $e) {
  136. return;
  137. }
  138. }
  139. public static function logEnd($data, $logDir)
  140. {
  141. foreach ($data as $k => $v) {
  142. //获取日志文件名 避免单个日志文件太大
  143. $count = 1;
  144. while (true) {
  145. //生成日志文件名
  146. $logFile = "{$logDir}" . '/' . "{$k}_{$count}.log";
  147. //第一次写入日志
  148. if (!is_file($logFile)) break;
  149. //日志文件未大于1M
  150. $file = filesize($logFile) / 1024 / 1024;
  151. if ($file < self::$size) break;
  152. $count++;
  153. }
  154. $v = rtrim($v);
  155. $v .= PHP_EOL . '================ End ================' . PHP_EOL . PHP_EOL;
  156. error_log($v, 3, $logFile);
  157. // $ch = fopen($logFile, 'ab');
  158. // fwrite($ch, $v);
  159. // fclose($ch);
  160. }
  161. }
  162. /**
  163. * 日志黑名单
  164. * @return array
  165. */
  166. public static function whiteLog()
  167. {
  168. return [];
  169. }
  170. }