【fastadmin】脚本模式下,日志钩子函数执行出现死循环,导致内存溢出奔溃

问题出现原因是想对项目中error级别的日志,接入钉钉告警,方便查看

于是使用钩子方法,日志写入完成后,自动调用自定义的告警方法中

php 复制代码
1、在application/tags.php 中添加

'log_write_done' => [
	'app\\common\\behavior\\Common',
],

2、在 common/behavior/Common.php 中添加

/**
* 记录日志的钩子方法,发送告警信息
* @param $log
* @return void
*/
public function logWriteDone($log)
{
	$level = '';
	if (isset($log['notice'])) {
	    $level = 'notice';
	}
	if (isset($log['error'])) {
	    $level = 'error';
	}
	if (isset($log['alert'])) {
	    $level = 'alert';
	}
	
	//钉钉告警
	if (in_array($level, ['notice', 'error'])) {
	    $method = '';
	
	    if (isset($log['info'])) {
	        foreach ($log['info'] as $value) {
	            if (strpos($value, 'PARAM')) {
	                $method = $value;
	            }
	        }
	    }
	    $data = $log[$level];
	
	    $message = $method . "\r\n--------------------\r\n" . var_export($data, true);
	
	    Notice::DingRobot($message, $level);
	}
}

在 Notice::DingRobot(message, level); 中实现钉钉机器人推送消息代码,即可实现告警功能

但是在运行脚本的时候,发现程序会内存溢出直到崩溃,报错:

Allowed memory size of 536870912 bytes exhausted (tried to allocate 262144 bytes) in

正常调用是OK的,脚本调用会出现异常,百思不得其解,于是开启了漫长的debug过程。。。。。。

最后追框架源码,发现了问题原因

1、脚本运行时,因为会连接数据库,所以框架会打sql级别的日志

thinkphp/library/think/Log.php

2、打日志时先是执行到了这个魔术方法中,可以看到是调用了record方法

这一步很关键,注意看有个IS_CLI 这个是在命令行模式的时候为true

3、然后继续到save里面看

4、save记录完日志后,会执行钩子 log_write_done , 继续往Hook::listen 方法里面排查

可以看到这里是执行了exec方法

5、到exec里面看看

6、这一步很关键,可以看到调用完对应的钩子函数后,如果是debug模式,会继续打个record日志,于是流程就又回到了第一次,变成了死循环,这就是导致程序内存崩溃的原因

找到问题原因了,如何解决呢,可以确定是框架bug导致的,但是一般来说最好不要直接改框架源码,那么就从业务上面入手,通过上面的流程可以看出,首先是是 IS_CLI 执行大日志的操作,然后是debug模式为true时, 才会打record日志,那么可以在自定义的钩子函数中加上

php 复制代码
public function logWriteDone($log)
{
	if (IS_CLI && App::$debug) {
	    App::$debug = false;
	}
	
	//发送告警
}

如果是命令行模式下,把debug设置为false,那么就第六步判断的时候,debug为false,就不会进入死循环中了

问题是再命令行模式 + 本地debug模式打开的时候会出现,这个方法没有根本解决bug,是通过绕过的方式,解决了这个问题,如果有更好的解决方法,欢迎留言告知

相关推荐
闲云野鹤在人间4 小时前
docker 入门 | 第5章 网络详解
网络·docker·架构·华为云·php
PHP实战开发录6 小时前
MySQL连接数为什么会打满
系统架构·php·开发
VXbishe7 小时前
【课程设计】基于SpringBoot的乡村政务服务系统的设计与实现-计算机毕设77011
javascript·vue.js·spring boot·python·php·课程设计·政务
aixingpan7 小时前
aixingpan.cn API开发文档:api_docs_bichart_natalvssolar_return2接口指南
前端·php
曦夜日长8 小时前
Linux系统篇,进程概念(四):内核链表的深度理解、进程优先级的底层理解
linux·运维·服务器·php
4SAPI1 天前
企业大模型API服务商推荐:从多模型接入到AI API Gateway的技术选型分析
人工智能·php
子非鱼a1 天前
【WEB】[NewStarCTF 2023 公开赛道]include 0。0
php
DevUp1 天前
停更老站往哪搬:PHP 老站的五条出路(番外七)
php·cms
专业程序开发源1 天前
springboot旅游推荐系统82074-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·php·课程设计·旅游
sbjdhjd1 天前
从“删除后重生”到认证绕过:PHP 常驻内存实验与 Cacti remote_agent 命令执行链路复盘
安全·web安全·网络安全·数据挖掘·php·网络攻击模型·安全架构