diff --git a/README.md b/README.md index 6fc0c61..7892ac8 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,6 @@ │ │ ├── ExceptionTrigger 自定义异常处理器,将异常上报至redis或http │ │ ├── FdManager WebSocket连接符管理,共享内存(Swoole\Table)实现 │ │ ├── LamJwt jwt - │ │ ├── LamLog 自定义日志处理器 │ │ ├── LamOpenssl RSA数据加密和解密 │ │ ├── LamUnit 辅助工具类 │ │ ├── Mysqli 对MysqlClient的二次封装 @@ -37,6 +36,7 @@ │ │ ├── Dictionary 国际化字典,项目请`继承`它 │ │ └── Languages I18n助手类,主要用来注册、设置 │ │ + │ ├── Logs 自定义日志处理器 │ └── OrmCache 模型缓存组件,已实现 String、Hash、Set、SplArray │ ├── HttpController diff --git a/src/Common/Classes/LamLog.php b/src/Common/Classes/LamLog.php deleted file mode 100644 index 98732de..0000000 --- a/src/Common/Classes/LamLog.php +++ /dev/null @@ -1,136 +0,0 @@ -logDir = $logDir ?: ''; - } - - public function log($msg, int $logLevel = self::LOG_LEVEL_INFO, string $category = 'debug'): string - { - $str = $this->_preAct($msg, $logLevel, $category, 'log'); - - // 立即写入 - if ($category === self::CATE_IMMEDIATE || Coroutine::getCid() < 0) { - $this->save(); - } // 协程defer时写入 - else { - Coroutine::defer(function () { - $this->save(); - }); - } - - return $str; - } - - public function console($msg, int $logLevel = self::LOG_LEVEL_INFO, string $category = 'debug') - { - $str = $this->_preAct($msg, $logLevel, $category, 'console'); - $cid = Coroutine::getCid(); - fwrite(STDOUT, "[CID=$cid]$str\n"); - } - - // 保存日志 - public function save() - { - empty($this->logDir) && $this->logDir = config('LOG.dir'); - $dir = $this->logDir . '/' . date('ym'); - is_dir($dir) or @ mkdir($dir, 0777, true); - - // conArr[$cid][$key][] = $value - foreach ((array)$this->conArr[Coroutine::getUid()] as $key => $value) { - if (empty($value) || ! is_array($value)) { - continue; - } - - $fname = $key == $this->dfKey ? '' : "-$key"; - - file_put_contents("$dir/" . date('d') . $fname . ".log", "\n" . implode("\n", $value) . "\n", FILE_APPEND | LOCK_EX); - } - - unset($this->conArr[Coroutine::getUid()]); - - return true; - } - - private function _preAct($msg, int &$logLevel = self::LOG_LEVEL_INFO, string $category = 'console', string $func = 'log') - { - if ( ! is_scalar($msg)) { - $msg = json_encode($msg, JSON_UNESCAPED_UNICODE); - } - $msg = str_replace(["\n", "\r"], '', $msg); - - // 不在东8区则拼接上东8区的时间 - $tznInt = intval(substr((int)date('O'), 0, -2)); - $time = time(); - if ($tznInt !== 8) { - $date = "{$tznInt}区: " . date(DateUtils::FULL, $time); - $date .= ', +8区: ' . date(DateUtils::FULL, DateUtils::getTimeZoneStamp($time, 'PRC')); - } else { - $date = date(DateUtils::FULL, $time); - } - - $logLevel = $this->levelMap($logLevel); - - $str = "[$date][$category][$logLevel]$msg"; - - if ($func == 'log') { - if (in_array($logLevel, config('LOG.apart_level'))) { - $this->merge($logLevel, $str); - } elseif (in_array($category, config('LOG.apart_category'))) { - $this->merge($category, $str); - } else { - $this->merge($this->dfKey, $str); - } - } - - return $str; - } - - private function levelMap(int $level) - { - switch ($level) { - case self::LOG_LEVEL_INFO: - return 'info'; - case self::LOG_LEVEL_NOTICE: - return 'notice'; - case self::LOG_LEVEL_WARNING: - return 'warning'; - case self::LOG_LEVEL_ERROR: - return 'error'; - default: - return 'unknown'; - } - } - - /** - * 完整实例: conArr[$cid][$key][] = $value - * @param string $key - * @param string $value - */ - protected function merge($key = '', $value = '') - { - $this->conArr[Coroutine::getUid()][$key][] = $value; - } -} diff --git a/src/Common/Logs/Handler.php b/src/Common/Logs/Handler.php new file mode 100644 index 0000000..2d8cbea --- /dev/null +++ b/src/Common/Logs/Handler.php @@ -0,0 +1,79 @@ +levelMap($logLevel); + $Item = new Item([ + 'message' => $msg, + 'level' => $logLevel, + 'category' => $category + ]); + + $this->save($Item); + return $Item->getWriteStr(); + } + + public function console($msg, int $logLevel = self::LOG_LEVEL_INFO, string $category = 'debug') + { + $logLevel = $this->levelMap($logLevel); + $Item = new Item([ + 'message' => $msg, + 'level' => $logLevel, + 'category' => $category + ]); + $str = $Item->getWriteStr(); + fwrite(STDOUT, "$str\n"); + } + + public function save(Item $Item) + { + empty($this->logDir) && $this->logDir = config('LOG.dir'); + $dir = $this->logDir . '/' . date('ym'); + is_dir($dir) or @ mkdir($dir, 0777, true); + + $apartLevel = config('LOG.apart_level'); + $apartCategory = config('LOG.apart_category'); + + $name = ''; + if (in_array($Item->level, $apartLevel)) { + $name = '-' . $Item->level; + } elseif (in_array($Item->category, $apartCategory)) { + $name = '-' . $Item->category; + } + + $d = date('d'); + $str = $Item->getWriteStr(); + file_put_contents("$dir/{$d}{$name}.log", "$str\n", FILE_APPEND | LOCK_EX); + } + + private function levelMap(int $level) + { + switch ($level) { + case self::LOG_LEVEL_INFO: + return 'info'; + case self::LOG_LEVEL_NOTICE: + return 'notice'; + case self::LOG_LEVEL_WARNING: + return 'warning'; + case self::LOG_LEVEL_ERROR: + return 'error'; + default: + return 'unknown'; + } + } +} diff --git a/src/Common/Logs/Item.php b/src/Common/Logs/Item.php new file mode 100644 index 0000000..e33e1c0 --- /dev/null +++ b/src/Common/Logs/Item.php @@ -0,0 +1,55 @@ +cid = Coroutine::getCid(); + + if ( ! is_scalar($this->message)) { + $this->message = json_encode($this->message, JSON_UNESCAPED_UNICODE); + } + $this->message = str_replace(["\n", "\r"], '', $this->message); + + // 产生日志的时间 + $this->time = time(); + $this->date = date(DateUtils::FULL, $this->time); + // 不在东8区,则记录东8区时间 + $tznInt = intval(substr((int)date('O'), 0, -2)); + if ($tznInt !== 8) { + $this->date .= ', +8区: ' . date(DateUtils::FULL, DateUtils::getTimeZoneStamp($this->time, 'PRC')); + } + } + + public function getWriteStr() + { + return "[cid={$this->cid}][{$this->date}][{$this->category}][{$this->level}]{$this->message}"; + } + + public function __get($name) + { + if (property_exists($this, $name)) { + return $this->{$name}; + } + throw new \Exception(__CLASS__ . ' Not fount property : ' . $name); + } +} diff --git a/src/Consumer/BaseTrait.php b/src/Consumer/BaseTrait.php index da1cb52..da2df40 100644 --- a/src/Consumer/BaseTrait.php +++ b/src/Consumer/BaseTrait.php @@ -21,8 +21,8 @@ trait BaseTrait * 'queue' => 'queue_login', // 监听的redis队列名 * 'tick' => 1000, // 多久运行一次,单位毫秒, 默认1000毫秒 * 'limit' => 200, // 单次出队列的阈值, 默认200 - * 'coroutine' => false // 是否为每条数据开启协程 - * 'pool' => 'default' // redis连接池名称 + * 'pool' => 'default' // redis连接池名称 + * 'json' => false // 是否需要json_decode * ], * */ @@ -36,10 +36,11 @@ protected function onException(\Throwable $throwable, ...$args) /** * 消费单条数据,由子类继承实现 - * @param string $data 每一条队列数据 + * @param string|array $data 每一条队列数据 + * @param Redis|null $redis redis连接 * @return mixed */ - abstract protected function consume($data = ''); + abstract protected function consume($data = [], Redis $redis = null); /** * EasySwoole自定义进程入口 @@ -63,14 +64,10 @@ public function run() break; } try { - $openCoroutine = $this->args['coroutine'] ?? false; - if ($openCoroutine) { - go(function () use ($data) { - $this->consume($data); - }); - } else { - $this->consume($data); + if ( ! empty($this->args['json'])) { + $data = json_decode($data, true); } + $this->consume($data, $Redis); } catch (\Throwable $throwable) { \EasySwoole\EasySwoole\Trigger::getInstance()->throwable($throwable); } diff --git a/src/Consumer/HttpTrackerTrait.php b/src/Consumer/HttpTrackerTrait.php index 9595c93..b031027 100644 --- a/src/Consumer/HttpTrackerTrait.php +++ b/src/Consumer/HttpTrackerTrait.php @@ -2,9 +2,11 @@ namespace WonderGame\EsUtility\Consumer; +use EasySwoole\Redis\Redis; + trait HttpTrackerTrait { - protected function consume($data = '') + protected function consume($data = [], Redis $redis = null) { try { diff --git a/src/Consumer/ProcessInfoTrait.php b/src/Consumer/ProcessInfoTrait.php index 6488444..7930cab 100644 --- a/src/Consumer/ProcessInfoTrait.php +++ b/src/Consumer/ProcessInfoTrait.php @@ -3,10 +3,11 @@ namespace WonderGame\EsUtility\Consumer; use EasySwoole\ORM\AbstractModel; +use EasySwoole\Redis\Redis; trait ProcessInfoTrait { - protected function consume($data = '') + protected function consume($data = [], Redis $redis = null) { $data = json_decode($data, true); if ( ! $data) {