thinkphp6如何使用中间件记录行为日志(thinkphp6如何做到伪静态)这样也行?

随心笔谈2年前发布 编辑
159 0
🌐 经济型:买域名、轻量云服务器、用途:游戏 网站等 《腾讯云》特点:特价机便宜 适合初学者用 点我优惠购买
🚀 拓展型:买域名、轻量云服务器、用途:游戏 网站等 《阿里云》特点:中档服务器便宜 域名备案事多 点我优惠购买
🛡️ 稳定型:买域名、轻量云服务器、用途:游戏 网站等 《西部数码》 特点:比上两家略贵但是稳定性超好事也少 点我优惠购买



目录前言一、定义中间件二、使用日志通道暂存行为日志1.修改log配置文件2.注册全局中间件3.测试能否成功生成日志三、使用定时任务将日志内容定时写入数据库1.新建一个api方法2.新建行为日志数据表log_behavior3.新建定时任务总结

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

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

中间件

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

php think make:middleware Behavior

在这里插入图片描述

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

内容如下:

<?php
declare (strict_types=1);
namespace app\middleware;
use think\facade\Log;

class Behavior
{

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文件缓存,定时存入数据库

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

日志处理

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

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

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

<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class
// 行为日志
\app\middleware\Behavior::class,
];

随便访问一个本项目页面,例如: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}”}

要求定时任务可以访问到

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());
}
}
}
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;

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

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

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:Thinkphp6.0中间件的具体使用THINKPHP项目开发中的日志记录实例分析PHP Pipeline 实现中间件的示例代码

© 版权声明

相关文章