«

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

时间:2024-7-25 09:07     作者:韩俊     分类: PHP


这篇“thinkphp6如何使用中间件记录行为日志”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“thinkphp6如何使用中间件记录行为日志”文章吧。

    一、定义中间件

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

    php think make:middleware Behavior

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

    内容如下:

    <?php
    declare (strict_types = 1);
    namespace appmiddleware;
    use thinkfacadeLog;
    
    class Behavior
    {
        /**
         * 处理请求
         *
         * @param    hinkRequest $request
         * @param Closure       $next
         * @return Response
         */
        public function handle($request, Closure $next)
        {
             //start 加入以下内容
             $admin  =  get_admin_info();                   //当前登录用户的信息,自己实现
             $method = strtolower($request->method());
             $is_ajax = $request->isAjax();
             $route = $request->pathinfo();
             $req = $_REQUEST;
             unset($req['s'],$req['_session']);  
             $req_data = $req ?  json_encode($req) : '';
             $data = [
                   'admin_id' => $admin['id'],              //操作人id
                   'admin_user' => $admin['user'],          //操作人用户名
                   'route' => $route,                       //操作的路由地址
                   'method' => $method,                     //get/post
                   'req_tp' => $is_ajax ? 'ajax' : 'normal',
                   'req_data' => $req_data,                   //get/post的数据
                   'ip' => getIp(),
                   'create_time' => time()
             ];
             //end
             return $next($request);
        }
    }

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

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

    1.修改log配置文件

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

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

    2.注册全局中间件

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

    <?php
    // 全局中间件定义文件
    return [
        // 全局请求缓存
        //     hinkmiddlewareCheckRequestCache::class,
        // 多语言加载
        //     hinkmiddlewareLoadLangPack::class,
        // Session初始化
        //     hinkmiddlewareSessionInit::class
        // 行为日志
        appmiddlewareBehavior::class,   
    ];

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

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

    打开文件,数据已写入

    {“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方法

    要求定时任务可以访问到

     /**
         * 定时任务服务器定时将用户行为日志插入到数据库
         * @return void
         */
        public function sync_behavior_log()
        {
            $path = runtime_path() . 'behavior/b.log';
            $b_file = file_get_contents($path);
            $b_arr = explode(PHP_EOL, $b_file);
            $d = [];
            foreach ($b_arr as $b) {
                $data = json_decode($b, true);
                if (!empty($data['msg'])) {
                    $d[] = json_decode($data['msg'], true);
                }
            }
            if ($d) {
                try {
                    Db::name('log_behavior')->insertAll($d);     //批量插入数据库
                    file_put_contents($path, '');       //清空文件日志
                    echo '采集用户行为日志成功' . count($d);
                } catch (DbException $e) {
                    echo ($e->getMessage());
                }
            }
        }

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

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

    3.新建定时任务

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

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

    标签: php php教程

    热门推荐