__destruct
里抛出异常已经不会产生致命错误了
场景是用户操作日志,laravel 框架,所有模型事件都实现了一个接口类ChangesLoggerInterface
,然后当任意一个模型触发任意事件都会进到一个 ChangesLoggerListener
的监听器中。
然后想实现:
当 saved\updated\deleted 的时候记录下哪些字段从 xx 改成了 bb 。
然后一次请求中肯定不止一个对象发生变动可能是多个比如电商下单接口可能会是order:saved,user:updated(last_order_dateline)
。
所以最终是实现在一次请求中记录一行数据(在 logs 表中)。
所以在 ChangesLoggerListener
中 想调用一个 Logger
的日志记录类,调用Logger::push
,这样在当 Logger 触发__destruct
的时候获取 $this->data(array)
拼成一行数据入库。
问题是:
__destruct
必须是在refcount
为 0 的时候才触发。所以如果业务逻辑里有 try...catch..
的时候,实际上__destruct
里的异常是不会被 catch 到的。
造成 refcount
不为 0 的原因是因为用了 Laravel 的 Facade 实现的接管的单例。
还有什么其他方案嘛?
1
Rache1 2021-06-15 14:26:52 +08:00 1
弄个类,然后存静态变量,在中间件后置获取这这个变量的内容,然后入库不就好了嘛
|
2
rockyliang 2021-06-15 14:45:10 +08:00
这个问题我没看太懂,我的理解是,你是想将数据表的增删改操作记录到日志里,但这个和在__destruct 里抛出异常有什么关系?
|
3
dzdh OP @rockyliang
因为现在的方案是在一个 recorder 的__destruct 里做的,insert into log..... 但是如果这个处理失败会抛出异常(比如还有可能会创建异步任务,http rest 的 queue http 超时啥的会抛出异常) |
6
wangxin13g 2021-06-15 16:02:22 +08:00
不推荐用__destruct 来做任何事情,不熟悉 laravel,看你的说法应该得用类似 Hook 的机制而不是用__destruct
|
7
dzdh OP |
8
dzdh OP @wangxin13g 的确是 hook,目前除了__destruct 想不到其他方案。比如 Laravel 的 dispatch()返回的 PendingDispatch 就是在 __destruct 的时候执行`queue::push`方法。
|
10
wangxin13g 2021-06-15 17:45:24 +08:00
@dzdh 那考虑一下加个消息队列解耦,消息体放更新前后数据,消费者消费消息生成日志。把日志放数据库的行为非常不好
|