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

    背景:当线上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 代码 s hutdown  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 . " \n ";
 
  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代码正常执行完成时






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值