فهرست منبع

【程序目录】修改了日志格式,增加了日志配置,增加了公共中间件,增加了业务成功和失败的日志,增加了http响应事件监听。

leekay0218 3 سال پیش
والد
کامیت
a919f029e2

+ 25 - 8
crmeb/app/adminapi/AdminApiExceptionHandle.php

@@ -19,6 +19,7 @@ use think\exception\DbException;
 use think\exception\Handle;
 use think\exception\ValidateException;
 use think\facade\Env;
+use think\facade\Log;
 use think\Response;
 use Throwable;
 
@@ -27,26 +28,42 @@ class AdminApiExceptionHandle extends Handle
 
     /**
      * 记录异常信息(包括日志或者其它方式记录)
-     *
      * @access public
      * @param Throwable $exception
      * @return void
      */
-    public function report(Throwable $exception): void
+    public function report(Throwable $exception):void
     {
-        // 使用内置的方式记录异常日志
-        parent::report($exception);
+        $data = [
+            'file' => $exception->getFile(),
+            'line' => $exception->getLine(),
+            'message' => $this->getMessage($exception),
+            'code' => $this->getCode($exception),
+        ];
+
+        //日志内容
+        $log = [
+            request()->adminId(),                                                                 //管理员ID
+            request()->ip(),                                                                      //客户ip
+            ceil(msectime() - (request()->time(true) * 1000)),                                    //耗时(毫秒)
+            request()->rule()->getMethod(),                                                       //请求类型
+            str_replace("/", "", request()->rootUrl()),                                           //应用
+            request()->baseUrl(),                                                                 //路由
+            json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),     //请求参数
+            json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),                  //报错数据
+
+        ];
+        Log::write(implode("|", $log), "error");
     }
 
     /**
      * Render an exception into an HTTP response.
-     *
      * @access public
      * @param \think\Request $request
-     * @param Throwable $e
+     * @param Throwable      $e
      * @return Response
      */
-    public function render($request, Throwable $e): Response
+    public function render($request, Throwable $e):Response
     {
         $massageData = Env::get('app_debug', false) ? [
             'file' => $e->getFile(),
@@ -58,7 +75,7 @@ class AdminApiExceptionHandle extends Handle
         if ($e instanceof DbException) {
             return app('json')->fail('数据获取失败', $massageData);
         } elseif ($e instanceof AuthException || $e instanceof ValidateException || $e instanceof ApiException) {
-            return app('json')->make($e->getCode() ?: 400, $e->getMessage());
+            return app('json')->make($e->getCode() ? : 400, $e->getMessage());
         } elseif ($e instanceof AdminException) {
             return app('json')->fail($e->getMessage(), $massageData);
         } else {

+ 25 - 8
crmeb/app/api/ApiExceptionHandle.php

@@ -17,6 +17,7 @@ use crmeb\exceptions\AuthException;
 use think\exception\DbException;
 use think\exception\Handle;
 use think\facade\Env;
+use think\facade\Log;
 use think\Response;
 use Throwable;
 use think\exception\ValidateException;
@@ -26,26 +27,42 @@ class ApiExceptionHandle extends Handle
 
     /**
      * 记录异常信息(包括日志或者其它方式记录)
-     *
      * @access public
      * @param Throwable $exception
      * @return void
      */
-    public function report(Throwable $exception): void
+    public function report(Throwable $exception):void
     {
-        // 使用内置的方式记录异常日志
-        parent::report($exception);
+        $data = [
+            'file' => $exception->getFile(),
+            'line' => $exception->getLine(),
+            'message' => $this->getMessage($exception),
+            'code' => $this->getCode($exception),
+        ];
+
+        //日志内容
+        $log = [
+            request()->uid(),                                                                     //用户ID
+            request()->ip(),                                                                      //客户ip
+            ceil(msectime() - (request()->time(true) * 1000)),                                    //耗时(毫秒)
+            request()->rule()->getMethod(),                                                       //请求类型
+            str_replace("/", "", request()->rootUrl()),                                           //应用
+            request()->baseUrl(),                                                                 //路由
+            json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),     //请求参数
+            json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),                  //报错数据
+
+        ];
+        Log::write(implode("|", $log), "error");
     }
 
     /**
      * Render an exception into an HTTP response.
-     *
      * @access public
      * @param \think\Request $request
-     * @param Throwable $e
+     * @param Throwable      $e
      * @return Response
      */
-    public function render($request, Throwable $e): Response
+    public function render($request, Throwable $e):Response
     {
         // 添加自定义异常处理机制
         if ($e instanceof DbException) {
@@ -54,7 +71,7 @@ class ApiExceptionHandle extends Handle
                 'message' => $e->getMessage(),
                 'line' => $e->getLine(),
             ]);
-        } else if ($e instanceof AuthException || $e instanceof ApiException || $e instanceof ValidateException) {
+        } elseif ($e instanceof AuthException || $e instanceof ApiException || $e instanceof ValidateException) {
             return app('json')->fail($e->getMessage());
         } else {
             return app('json')->fail('很抱歉!系统开小差了', Env::get('app_debug', false) ? [

+ 1 - 1
crmeb/app/event.php

@@ -19,7 +19,7 @@ return [
     'listen' => [
         'AppInit' => [],
         'HttpRun' => [],
-        'HttpEnd' => [],
+        'HttpEnd' => [\app\listener\http\HttpEnd::class],
         'LogLevel' => [],
         'LogWrite' => [],
         'StoreProductOrderDeliveryAfter' => [], // OrderSubscribe 送货 发送模板消息 admin模块 order.StoreOrder控制器/order.combinationOrder控制器

+ 38 - 0
crmeb/app/http/middleware/BaseMiddleware.php

@@ -0,0 +1,38 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\http\middleware;
+
+
+use app\Request;
+use crmeb\interfaces\MiddlewareInterface;
+
+/**
+ * Class BaseMiddleware
+ * @package app\api\middleware
+ */
+class BaseMiddleware implements MiddlewareInterface
+{
+    public function handle(Request $request, \Closure $next, bool $force = true)
+    {
+        if (!Request::hasMacro('uid')) {
+            Request::macro('uid', function(){ return 0; });
+        }
+        if (!Request::hasMacro('adminId')) {
+            Request::macro('adminId', function(){ return 0; });
+        }
+        if (!Request::hasMacro('kefuId')) {
+            Request::macro('kefuId', function(){ return 0; });
+        }
+
+        return $next($request);
+    }
+}

+ 25 - 8
crmeb/app/kefuapi/KefuApiExceptionHandle.php

@@ -16,6 +16,7 @@ use crmeb\exceptions\AuthException;
 use think\exception\Handle;
 use think\exception\ValidateException;
 use think\facade\Config;
+use think\facade\Log;
 use think\Response;
 use Throwable;
 
@@ -23,26 +24,42 @@ class KefuApiExceptionHandle extends Handle
 {
     /**
      * 记录异常信息(包括日志或者其它方式记录)
-     *
      * @access public
      * @param Throwable $exception
      * @return void
      */
-    public function report(Throwable $exception): void
+    public function report(Throwable $exception):void
     {
-        // 使用内置的方式记录异常日志
-        parent::report($exception);
+        $data = [
+            'file' => $exception->getFile(),
+            'line' => $exception->getLine(),
+            'message' => $this->getMessage($exception),
+            'code' => $this->getCode($exception),
+        ];
+
+        //日志内容
+        $log = [
+            request()->kefuId(),                                                                  //客服ID
+            request()->ip(),                                                                      //客户ip
+            ceil(msectime() - (request()->time(true) * 1000)),                                    //耗时(毫秒)
+            request()->rule()->getMethod(),                                                       //请求类型
+            str_replace("/", "", request()->rootUrl()),                                           //应用
+            request()->baseUrl(),                                                                 //路由
+            json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),     //请求参数
+            json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),                  //报错数据
+
+        ];
+        Log::write(implode("|", $log), "error");
     }
 
     /**
      * Render an exception into an HTTP response.
-     *
      * @access public
      * @param \think\Request $request
-     * @param Throwable $e
+     * @param Throwable      $e
      * @return Response
      */
-    public function render($request, Throwable $e): Response
+    public function render($request, Throwable $e):Response
     {
         $massageData = Config::get('app_debug', false) ? [
             'file' => $e->getFile(),
@@ -54,7 +71,7 @@ class KefuApiExceptionHandle extends Handle
         if ($e instanceof DbException) {
             return app('json')->fail('数据获取失败', $massageData);
         } elseif ($e instanceof ValidateException || $e instanceof AuthException) {
-            return app('json')->make($e->getCode() ?: 400, $e->getMessage());
+            return app('json')->make($e->getCode() ? : 400, $e->getMessage());
         } else {
             return app('json')->code(200)->make(400, $e->getMessage(), $massageData);
         }

+ 63 - 0
crmeb/app/listener/http/HttpEnd.php

@@ -0,0 +1,63 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\listener\http;
+
+use think\facade\Log;
+use think\Response;
+
+/**
+ * 订单创建事件
+ * Class Create
+ * @package app\listener\http
+ */
+class HttpEnd
+{
+    public function handle(Response $response):void
+    {
+        //业务成功和失败分开存储
+        $status = isset($response->getData()["status"]) ? $response->getData()["status"] : 0;
+        if ($status == 200) {
+            //业务成功日志开关
+            if (config("log.success_close")) return;
+            $type = "success";
+        } else {
+            //业务失败日志开关
+            if (config("log.fail_close")) return;
+            $type = "fail";
+        }
+
+        //当前用户身份标识
+        if (!empty(request()->uid())) {
+            $uid = request()->uid();
+        } elseif (!empty(request()->adminId())) {
+            $uid = request()->adminId();
+        } elseif (!empty(request()->kefuId())) {
+            $uid = request()->kefuId();
+        } else {
+            $uid = 0;
+        }
+
+        //日志内容
+        $log = [
+            $uid,                                                                                 //用户ID
+            request()->ip(),                                                                      //客户ip
+            ceil(msectime() - (request()->time(true) * 1000)),                                    //耗时(毫秒)
+            request()->rule()->getMethod(),                                                       //请求类型
+            str_replace("/", "", request()->rootUrl()),                                           //应用
+            request()->baseUrl(),                                                                 //路由
+            json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),     //请求参数
+            json_encode($response->getData(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),   //响应数据
+
+        ];
+        Log::write(implode("|", $log), $type);
+    }
+}

+ 4 - 2
crmeb/app/middleware.php

@@ -14,9 +14,11 @@ return [
     // 多语言加载
     // \think\middleware\LoadLangPack::class,
     // Session初始化
-     \think\middleware\SessionInit::class,
+    \think\middleware\SessionInit::class,
     //多语言初始化
-     \think\middleware\LoadLangPack::class,
+    \think\middleware\LoadLangPack::class,
     // 页面Trace调试
     // \think\middleware\TraceDebug::class,
+    //初始化基础中间件
+    \app\http\middleware\BaseMiddleware::class,
 ];

+ 15 - 10
crmeb/config/log.php

@@ -15,27 +15,32 @@ use think\facade\Env;
 // +----------------------------------------------------------------------
 return [
     // 默认日志记录通道
-    'default'      => Env::get('log.channel', 'file'),
+    'default' => Env::get('log.channel', 'file'),
     // 日志记录级别
-    'level'        => ['error','warning'],
+    'level' => ['error', 'warning', 'fail', 'success'],
     // 日志类型记录的通道 ['error'=>'email',...]
     'type_channel' => [],
     // 是否关闭日志写入
-    'close'        => false,
-
+    'close' => false,
+    //是否关闭业务成功日志
+    'success_close' => false,
+    //是否关闭业务失败日志
+    'fail_close' => false,
     // 日志通道列表
-    'channels'     => [
+    'channels' => [
         'file' => [
             // 日志记录方式
-            'type'        => 'File',
+            'type' => 'File',
             // 日志保存目录
-            'path'        => app()->getRuntimePath() . 'log' . DIRECTORY_SEPARATOR,
+            'path' => app()->getRuntimePath() . 'log' . DIRECTORY_SEPARATOR,
             // 单文件日志写入
-            'single'      => false,
+            'single' => false,
             // 独立日志级别
-            'apart_level' => [],
+            'apart_level' => ['error', 'fail', 'success'],
             // 最大日志文件数量
-            'max_files'   => 0,
+            'max_files' => 0,
+            'time_format' => 'Y-m-d H:i:s',
+            'format' => '%s|%s|%s'
         ],
         // 其它日志通道配置
     ],