牛骨文教育服务平台(让学习变的简单)
博文笔记

使用register_shutdown_function实现php项目脚本执行失败的实时报警

创建时间:2017-06-15 投稿人: 浏览次数:690
    背景:当线上php脚本执行失败时,希望能够实时地自动发送报警邮件,而不是等收到用户的反馈才知道有bug存在。     分析:当我们的php脚本正常执行完成或意外死掉导致PHP执行即将结束时,register_shutdown_function指定的函数将会被调用。     实现思路:在脚本开始处设置一个变量,值为false,然后在脚本末尾将之设置为true,让PHP关闭回调函数(即我们指定的函数)检查脚本是否已经完成【如果我们的变量仍旧是false,我们就知道脚本的最后一行没有执行,因此它肯定在程序执行到某处死掉了】      以下是一个演示例子: 1、主入口index.php文件: <?php // start function shutdown_func() { //定义关闭回调函数     // shutdown     global $completeFlag;
    global $completeFlagKey;
    if (!$completeFlag) {
        $monitorVal = "URL地址:".$_SERVER["REQUEST_URI"]."<br>";
        $monitorVal .= "GET参数:".json_encode($_GET)."<br>";         $monitorVal .= "POST参数:".json_encode($_POST)."<br>";         $monitorVal .= "当前用户:".$_SESSION["currUserName"]."<br>";
        $monitorVal .= "时间:".date("Y-m-d H:i:s")."<br>";
        $monitorVal .= "错误信息:".json_encode(error_get_last());
        $redis = new Redis();
        $redis->connect("127.0.0.1", 6379);
        $redis->set($completeFlagKey, $monitorVal);
    }
    return false; }
register_shutdown_function("shutdown_func"); $completeFlag = false; $completeFlagKey = uniqid("scriptShutdownMonitor_");
/*...这里是其他功能代码...*/
$completeFlag = true; // end ?> 2、各控制器都集成CommonController,CommonController文件的析构函数: function __destruct() {           // destruct     global $g_curr_run_env;
    global $completeFlagKey;
    if ($g_curr_run_env == "online") {
        $redis = new Redis();
        $redis->connect("127.0.0.1", 6379);
        $redis->delete($completeFlagKey);
    }
}

注意:__destruct里面如果要操作文件,也要写绝对路径 (1)如果是正常运行完,执行流程为:start 代码 destruct end shutdown (2)如果是脚本发生error,执行流程为:start 代码 shutdown (3)如果是代码里面主动exit()或die(),执行流程为:start 代码 shutdown destruct
3、监控报警邮件。通过crontab定时调用 set_time_limit(0);
date_default_timezone_set("Asia/shanghai");
$redis = new Redis();
$redis->connect("127.0.0.1", 6379);
$keys = $redis->keys("scriptShutdownMonitor_*");
$msg = "";
foreach ($keys as $key) {
  $val = $redis->get($key);
  if ($val) {
     $msg .= $val."<br><hr><br>";
  }
  $redis->del($key);
}
if ($msg != "") {
  $logCon = "当前时间:".date("Y-m-d H:i:s").";msg:".$msg." ";
  file_put_contents("send_email.log", $logCon, FILE_APPEND);
  require_once("send_email.php");   send_email(      "xx@qq.com",      "线上脚本执行失败报警",      $msg   ); }
附上博主的个人网站:w3cstudy学习网,上面的有很多供学习文章,有兴趣可以去逛逛
几点说明: 1、 register_shutdown_function("shutdown_func");     对应回调函数的定义以及这句话要放在有可能引发错误的代码前面,否则在错误代码处崩溃后,这行代码也不会执行         参数:可以是一个字符串,即指定的关闭回调函数的名称,无需带括号,用引号包住即可; 也可以是一个数组,如array(‘error’,’shutdown_errow’)表示指定error类中的shutdown_error函数为关闭回调函数。 2、exit();//即使使用了exit();也会在exit()执行完后调用register_shutdown_function函数! 3、register_shutdown_function执行机制是:php把要调用的函数调入内存。当页面所有php语句都执行完成时,再调用此函数。注意,在这个时候从内存中调用,不是从php页面中调用,所以上面的例子中回调函数内如果要操作文件不能使用相对路径,因为php已经当原来的页面不存在了。就没有什么相对路 径可言。 4、可以这样理解调用条件:       (1)当页面被用户代码如exit()强制停止时       (2)当程序代码运行超时或者出现错误时       (3)当php代码正常执行完成时





声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。