发布于2026-07-10 阅读(0)
扫一扫,手机访问
先抛个问题:现在跑着的项目,如果业务方要求你查「上周三这个用户到底删了哪条订单记录」,你能在两分钟内精准定位吗?如果答案没那么笃定,多半是日志系统这块还有优化的空间。

Log 类记日志?用户根本对不上人直接用 Log::info() 记录日志,确实方便,但说句实话,这里头有个不小的坑——它只记下了日志内容和时间,关于上下文几乎一片空白:没有用户ID、没有请求详情,操作目标(比如到底改了哪条记录)更是无从谈起。真要追查问题,基本只能靠猜。
怎么解决?核心思路就一条:把所有日志的入口收拢到一个统一的服务类里来,比如 UserActivityLogger。
auth()->id()request()->ip()、request()->fullUrl()$post,就传 $post->id'password' => '***' 即可,干净又安全。这样一来,「谁在什么时间、对什么资源、干了什么」这条链路才算真正打通。
DB::table('activity_logs') 手动插,性能拉胯,事务里还容易丢用原生SQL插入日志,看似可控,但有个很隐蔽的陷阱:一旦包裹在数据库事务里,事务回滚,日志也跟着一块儿消失了。要是用户刚删了一条订单,日志却因为回滚没留下,审计直接断档,排查起来就费劲了。
实操建议:
DB::commit() 之后再来写。或者更稳的做法是使用 DB::unprepared() 绕过当前事务。database 队列还是 redis 队列都行。主流程只管处理业务,日志让后台进程慢慢消化,丝毫不影响响应速度。user_id、action(比如存个字符串 'updated_post' 就挺直观)、subject_type 和 subject_id 指向操作对象、再加上 ip、user_agent。很多人习惯监听 eloquent.updated 这类事件来抓模型变更,这确实能覆盖大部分CRUD操作。但真实场景下,有大量行为是不经过模型的:登录、登出、菜单点击、Excel文件导出、API token刷新……这些操作 Eloquent 事件完全收不到,日志记录就会出现大片盲区。
最佳实践是多元方案并行:
AuthController@login 方法里,显式调用 UserActivityLogger::log('logged_in')。LogUserActivity,在 handle() 里判断请求方法(POST/PUT/DELETE)以及当前用户是否已登录,自动进行日志记录。上线两周后,突然发现查某个用户的操作记录居然要等8秒,EXPLAIN 一跑,全表扫描——这就是忘了给 user_id 和 created_at 加联合索引的后果。
解决方法很简单,但从一开始就得想好:
$table->index(['user_id', 'created_at']) 。如果业务里经常按操作类型查(比如查「最近登出过多少次」),再加个 index(['action', 'created_at'])。activity_logs_202404),再用视图或查询路由来聚合,性能会明显改善。JOIN users 表来拿用户名。写日志的时候顺手存一个 user_name 快照字段进去,查询时直接取,省掉一次关联,速度自然就上去了。但别忘了,最容易被忽略的其实是「日志写入的时机」。同步写入磁盘最稳,但慢;异步写入快,可要是进程突然崩溃,最后几条日志可能就丢了。这个取舍没有银弹,完全取决于业务容忍度:金融类操作必须同步落盘,后台管理类操作则可以接受秒级延迟。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8