您的位置: 翼速应用 > 业内知识 > PHP框架 > 正文

教你在thinkphp中用中间件记录行为日志

本文将教会你在thinkphp中用中间件记录行为日志,还包括了使用日志通道暂存行为日志、使用定时任务将日志内容定时写入数据库等等知识,希望能对大家有所帮助。


教你在thinkphp中用中间件记录行为日志


一、定义中间件


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


php think make:middleware Behavior


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


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


<?phpdeclare (strict_types = 1);namespace app\middleware;use think\facade\Log;class Behavior{
    /**
     * 处理请求
     *
     * @param \think\Request $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 ,在’channels’ => [] 最后加入一个记录行为日志的单独通道:


// 其它日志通道配置
//行为日志
'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 [
    // 全局请求缓存
    // \think\middleware\CheckRequestCache::class,
    // 多语言加载
    // \think\middleware\LoadLangPack::class,
    // Session初始化
    // \think\middleware\SessionInit::class
    // 行为日志
    \app\middleware\Behavior::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次


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



我来说两句

0 条评论

推荐阅读

  • 响应式布局CSS媒体查询设备像素比介绍

    构建响应式网站布局最常见的是流体网格,灵活调整大小的站点布局技术,确保用户在使用的幕上获得完整的体验。响应式设计如何展示富媒体图像,可以通过以下几种方法。

    admin
  • 提升网站的性能快速加载的实用技巧

    网站速度很重要,快速加载的网站会带来更好的用户体验、更高的转化率、更多的参与度,而且在搜索引擎排名中也扮演重要角色,做SEO,网站硬件是起跑线,如果输在了起跑线,又怎么跟同行竞争。有许多方法可提升网站的性能,有一些技巧可以避免踩坑。

    admin
  • 织梦CMS TAG页找不到标签和实现彩色标签解决方法

    织梦cms是我们常见的网站程序系统的一款,在TAG标签中常常遇到的问题也很多。当我们点击 tags.php 页的某个标签的时候,有时会提示:“系统无此标签,可 能已经移除!” 但是我们检查程序后台,以及前台显示页面。这个标签确实存在,如果解决这个问题那?

    admin
  • HTML关于fieldset标签主要的作用

    在前端开发html页面中常用的标签很多,今天为大家带来的是关于HTML中fieldset标签主要的作用说明,根据技术分析HTML

    admin

精选专题