LogUtil.php 6.5 KB

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