如何更加优雅的0侵入式实现 操作日志 的记录?
最终想实现
时间 | 操作人 | 操作记录 | IP | host |
---|---|---|---|---|
YYYY-mm-dd | admin | 修改:[商品] 金额 10.00->22.00; unit 1->2 新增: [商品] 金额 11.00 删除:[user] [id:1] |
8.8.8.8 | 内网ip或主机名 |
YYYY-mm-dd | 系统(CLI) | 修改: [订单] 状态 WAITING->PAY_SUCCESS | 内网ip或主机名或job名称如/app/jobs/XXXJob |
0侵入式
不改动(一行都不能动)当前系统现有逻辑(控制器、业务逻辑部分)、队列的前提下实现
想法
注册个ServiceProvider或者全局中间件,在$next($request)
之前开启DB::listen
记录sql,根据表名、字段名找对应模型的注释比如模型这么定义:
class User extends Model {
public $_title = '用户';
public $_attrs = [ 'id'=>'ID', 'nickname'=>'用户昵称' ... ];
public $_ignoreAttrs = ['created_at','updated_at'];
}
然后根据$model->getDirty()
获取修改内容,根据$model->_title
获取当前模型叫什么名字(用户、商品、订单历史balabala) 根据 $_ignoreAttrs
忽略哪些字段的变更比如创建时间、最后修改时间,根据$_attrs
把对应字段改成中文。然后拼成一个完整字符串修改 [$model->_title] $model->_attrs[$...] $model->getOriginalAttribute($model->...) -> $model->getAttribute($model->...)
问题
如果是CLI模式下呢?怎么区分【一次】【请求】?
比如如果是一个异步任务,应该单个任务里的所有model新增、变动视为【一次[请求]】。不能视整个进程的生命周期为一次请求。
监听模型不好吗?
你可以看看这个:github.com/owen-it/laravel-auditin...
可能需要适度的调整,我之前也没有使用这个,而是照着他的思路自己实现了差不多的功能
你说的一次请求, 你可以创建一个类似于唯一请求 ID 这种
向异步任务里传递该 ID 就行
坐等方案 :grin:
为什么没试试这个呢?
点我快速remake
session_id
, 我是不建议你用listen
, 可以改为全局中间件DB::enableQueryLog
DB::DB::getQueryLog()
得到一个数组, 这一批 SQL 都是同一次请求的data_set($sqlList, *.session_id
, Str::random(32))`Model::insert($sqlList);
这不算0嵌入哦
楼主解决问题了吗
楼主解决问题了吗
CLI模式下的异步任务如果是队列的话,可以使用:任务中间件。
在中间件里处理任务内所有的模型的变更