使用register_shutdown_function实现php项目脚本执行失败的实时报警
2017-06-15 19:10
676 查看
背景:当线上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."\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代码正常执行完成时
分析:当我们的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."\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代码正常执行完成时
相关文章推荐
- PHP - Manual手册 - XLVII. Function Handling Functions函数管理函数 - register_shutdown_function注册一个脚本结束时调用的函数
- windows下使用PHP实现定时执行脚本
- 如何使用register_shutdown_function()捕获PHP致命错误?
- windows下使用PHP实现定时执行脚本
- PHP register_shutdown_function()函数的使用示例
- PHP ignore_user_abort 与 connection_status 与 register_shutdown_function 使用方法
- windows下使用PHP实现定时执行脚本
- windows下使用PHP实现定时执行脚本
- php ignore_user_abort与register_shutdown_function 使用方法
- PHP 错误与异常 笔记与总结(11 )register_shutdown_function() 函数的使用
- PHP register_shutdown_function()函数的使用示例
- PHP错误处理函数register_shutdown_function使用示例
- 使用php结合rsync、inotify实现的实时备份脚本!
- asterisk 使用php脚本socket通过AMI端口实现自动打电话报警
- windows下使用PHP实现定时执行脚本
- php ignore_user_abort与register_shutdown_function 使用方法
- PHP register_shutdown_function()函数的使用示例
- php中__destruct与register_shutdown_function执行的先后顺序问题
- php中__destruct与register_shutdown_function执行的先后顺序问题
- windows下使用PHP实现定时执行脚本