Bladeren bron

feat(log): 添加飞书日志驱动并增加测试用例

- 新增 FeiShu 日志驱动类实现 LogHandlerInterface 接口
- 实现飞书机器人 webhook 消息推送功能
- 添加 curl 句柄复用机制提高性能
- 配置支持消息格式化和应用名称设置
- 增加发送失败时的错误日志记录
- 在 LogTest 中添加飞书日志测试方法
runphp 1 maand geleden
bovenliggende
commit
1755b146a3
2 gewijzigde bestanden met toevoegingen van 103 en 0 verwijderingen
  1. 96 0
      src/Log/Driver/FeiShu.php
  2. 7 0
      tests/LogTest.php

+ 96 - 0
src/Log/Driver/FeiShu.php

@@ -0,0 +1,96 @@
+<?php
+declare(strict_types=1);
+namespace SixShop\System\Log\Driver;
+
+use think\contract\LogHandlerInterface;
+
+class FeiShu implements LogHandlerInterface
+{
+    private $curlHandle = null;
+    
+    public function __construct(private array $config = [])
+    {
+    }
+    
+    public function __destruct()
+    {
+        if ($this->curlHandle) {
+            curl_close($this->curlHandle);
+        }
+    }
+
+    #[\Override]
+    public function save(array $log): bool
+    {
+        foreach ($log as $record) {
+            $type = $record->type;
+            $msg  = $record->message;
+            $time = $record->time->format($this->config['time_format']);
+            if (!is_string($msg)) {
+                $msg = var_export($msg, true);
+            }
+            $message = sprintf($this->config['format'], $time, $type, $msg);
+            $this->write($message);
+        }
+
+        return true;
+    }
+
+    private function write(string $message): void
+    {
+        if (empty($this->config['webhook_url'])) {
+            return;
+        }
+
+        $data = [
+            'msg_type' => 'text',
+            'content' => [
+                'app_name' => $this->config['app_name'] ?? 'sixshop',
+                'msg' => $message
+            ]
+        ];
+
+        $this->sendWebhook($this->config['webhook_url'], $data);
+    }
+
+    private function sendWebhook(string $url, array $data): void
+    {
+        // 复用 curl 句柄
+        if (!$this->curlHandle) {
+            $this->curlHandle = curl_init();
+            curl_setopt_array($this->curlHandle, [
+                CURLOPT_POST => true,
+                CURLOPT_HTTPHEADER => [
+                    'Content-Type: application/json',
+                    'Accept: application/json'
+                ],
+                CURLOPT_RETURNTRANSFER => true,
+                CURLOPT_TIMEOUT => 10,
+                CURLOPT_CONNECTTIMEOUT => 5,
+                CURLOPT_SSL_VERIFYPEER => false,
+                CURLOPT_SSL_VERIFYHOST => false
+            ]);
+        }
+        
+        // 每次请求设置特定的 URL 和数据
+        curl_setopt_array($this->curlHandle, [
+            CURLOPT_URL => $url,
+            CURLOPT_POSTFIELDS => json_encode($data, JSON_UNESCAPED_UNICODE)
+        ]);
+
+        $response = curl_exec($this->curlHandle);
+        $httpCode = curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE);
+        $error = curl_error($this->curlHandle);
+
+        // 可以在这里记录发送结果到系统日志
+        if ($error || $httpCode !== 200) {
+            // 发送失败,可以选择记录到文件或其他方式
+            error_log(sprintf(
+                'FeiShu webhook send failed: %s, HTTP Code: %d, Response: %s', 
+                $error ?: 'Unknown error', 
+                $httpCode, 
+                $response
+            ));
+        }
+    }
+}

+ 7 - 0
tests/LogTest.php

@@ -21,4 +21,11 @@ class LogTest extends TestCase
         $this->log->debug('test1');
         \think\facade\Log::debug('test2');
     }
+
+    #[Test]
+    public function feishu()
+    {
+        $this->log->error('test1');
+        $this->log->error('test2');
+    }
 }