当前位置:首页 > CMS教程 > Thinkphp > 列表

thinkphp6如何使用中间件记录行为日志

发布:smiling 来源: PHP粉丝网  添加日期:2023-07-03 19:02:28 浏览: 评论:0 

发现本站没有一个靠谱的tp6记录行为日志的教程,于是就整理了一下自己在项目中已经投入使用的行为日志中间件的详细配置步骤供大家参考。

提示:先阅读官方中间件教程 https://www.kancloud.cn/manual/thinkphp6_0/1037493

一、定义中间件

可以通过命令行指令快速生成中间件

php think make:middleware Behavior

thinkphp6如何使用中间件记录行为日志

这个指令会 app/middleware目录下面生成一个Behavior中间件。

内容如下:

  1. <?php 
  2. declare (strict_types = 1); 
  3. namespace app\middleware; 
  4. use think\facade\Log; 
  5.  
  6. class Behavior 
  7.     /** 
  8.      * 处理请求 
  9.      * 
  10.      * @param \think\Request $request 
  11.      * @param \Closure       $next 
  12.      * @return Response 
  13.      */ 
  14.     public function handle($request, \Closure $next
  15.     { 
  16.          //start 加入以下内容 
  17.          $admin  =  get_admin_info();                   //当前登录用户的信息,自己实现 
  18.          $method = strtolower($request->method()); 
  19.          $is_ajax = $request->isAjax(); 
  20.          $route = $request->pathinfo(); 
  21.          $req = $_REQUEST
  22.          unset($req['s'],$req['_session']);   
  23.          $req_data = $req ?  json_encode($req) : ''
  24.          $data = [ 
  25.                'admin_id' => $admin['id'],               //操作人id 
  26.                'admin_user' => $admin['user'],           //操作人用户名 
  27.                'route' => $route,                        //操作的路由地址 
  28.                'method' => $method,                      //get/post 
  29.                'req_tp' => $is_ajax ? 'ajax' : 'normal'
  30.                'req_data' => $req_data,                   //get/post的数据 
  31.                'ip' => getIp(), 
  32.                'create_time' => time() 
  33.          ]; 
  34.          //end 
  35.          return $next($request); 
  36.     } 

二、使用日志通道暂存行为日志

不建议将行为日志实时写入数据库给数据库造成不必要的压力. 我们先写入log文件缓存,定时存入数据库

提示:先阅读官方日志处理教程 https://www.kancloud.cn/manual/thinkphp6_0/1037616

1.修改log配置文件

打开config/log.php ,在’channels’ => [] 最后加入一个记录行为日志的单独通道:

  1. // 其它日志通道配置 
  2. //行为日志 
  3. 'behavior'    =>    [ 
  4.     'path'           => runtime_path().'behavior',  //日志存放目录 
  5.     'type'    =>    'File', 
  6.     'single' =>     'b',                //单一文件日志:文件名 
  7.     'file_size'    =>   1024*1024*10,   //日志文件大小限制(超出会生成多个文件 
  8.     'max_files' => 30,                  //文件最大数量 
  9.     'realtime_write'    =>    false,    // 关闭实时写入 
  10. ], 

2.注册全局中间件

打开app/middleware.php ,注册个行为日志全局中间件

  1. <?php 
  2. // 全局中间件定义文件 
  3. return [ 
  4.     // 全局请求缓存 
  5.     // \think\middleware\CheckRequestCache::class, 
  6.     // 多语言加载 
  7.     // \think\middleware\LoadLangPack::class, 
  8.     // Session初始化 
  9.     // \think\middleware\SessionInit::class 
  10.     // 行为日志 
  11.     \app\middleware\Behavior::class,    
  12. ]; 

3.测试能否成功生成日志

随便访问一个本项目页面,例如:http://www.tp6.com/index/index/test?a=1&b=2,看能否生成以下文件.

thinkphp6如何使用中间件记录行为日志

打开文件,数据已写入

  1. {“time”:“2022-04-16T21:38:48+08:00”,“type”:“info”,“msg”:"{“admin_id”:888,“admin_user”:“fanchen”,“route”:“index\/index\/test”,“method”:“get”,“req_tp”:“normal”,“req_data”:"{\“a\”:\“1\”,\“b\”:\“2\”}",“ip”:“127.0.0.1”,“create_time”:1650116328}"} 

三、使用定时任务将日志内容定时写入数据库

1.新建一个api方法

要求定时任务可以访问到

  1. /** 
  2.     * 定时任务服务器定时将用户行为日志插入到数据库 
  3.     * @return void 
  4.     */ 
  5.    public function sync_behavior_log() 
  6.    { 
  7.        $path = runtime_path() . 'behavior/b.log'
  8.        $b_file = file_get_contents($path); 
  9.        $b_arr = explode(PHP_EOL, $b_file); 
  10.        $d = []; 
  11.        foreach ($b_arr as $b) { 
  12.            $data = json_decode($b, true); 
  13.            if (!emptyempty($data['msg'])) { 
  14.                $d[] = json_decode($data['msg'], true); 
  15.            } 
  16.        } 
  17.        if ($d) { 
  18.            try { 
  19.                Db::name('log_behavior')->insertAll($d);     //批量插入数据库 
  20.                file_put_contents($path'');       //清空文件日志 
  21.                echo '采集用户行为日志成功' . count($d); 
  22.            } catch (DbException $e) { 
  23.                echo ($e->getMessage()); 
  24.            } 
  25.        } 
  26.    } 

2.新建行为日志数据表log_behavior

  1. SET NAMES utf8mb4; 
  2. SET FOREIGN_KEY_CHECKS = 0; 
  3.  
  4. -- ---------------------------- 
  5. -- Table structure for log_behavior 
  6. -- ---------------------------- 
  7. DROP TABLE IF EXISTS `log_behavior`; 
  8. CREATE TABLE `log_behavior`  ( 
  9.   `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID'
  10.   `admin_id` int(11) NOT NULL DEFAULT 0 COMMENT '用户id'
  11.   `admin_user` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户名'
  12.   `route` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '模块名称'
  13.   `method` enum('delete','put','post','get'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'get' COMMENT '请求方式 1get 2post 3put 4delete'
  14.   `req_data` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '请求数据'
  15.   `ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户ip'
  16.   `create_time` int(11) NOT NULL DEFAULT 0 COMMENT '创建时间'
  17.   PRIMARY KEY (`id`) USING BTREE, 
  18.   INDEX `uid`(`admin_id`) USING BTREE, 
  19.   INDEX `admin_user`(`admin_user`) USING BTREE, 
  20.   INDEX `route`(`route`) USING BTREE 
  21. ) ENGINE = InnoDB AUTO_INCREMENT = 3902195 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '行为日志' ROW_FORMAT = Compact; 
  22.  
  23. SET FOREIGN_KEY_CHECKS = 1; 

3.新建定时任务

新建定时任务,定时访问步骤1的sync_behavior_log地址就行了, 建议5分钟1次

至此, 有用户访问时,数据表就会每隔一段时间就批量插入行为日志数据了

总结

写得比较简单粗暴, 有些地方需要自己实现, 比如获取登录用户信息…

Tags: thinkphp6中间件 thinkphp6行为日志

分享到: