- 论坛徽章:
- 0
|
检测系统的运行及错误日志记录.
以下内容参考资料地址如下:
http://bbs.phpchina.com/thread-212378-1-1.html
http://bbs.phpchina.com/viewthread.php?tid=205481
php跟c语言有很大的区别, C语言软件在拥有持久层的模式下可以利用try 来将错误转化来表达给用户. 但php 在web上无需这样去做, 即时报错在服务器上是被dba所禁止的, 即使开启了报错信息的输出, 但你得知道信息仅仅是给用户看到了, 而管理员未必会知道, 类似腾讯网的应用上千上万, 管理员不可能天天去点击检查. 为此, 可以理解php更需要做的不是异常处理, 而是异常记录. 发现问题比解决问题更加重要, 也是所有操作的前一步. 一个网站程序的运行, 明眼上也许是正常, 这仅仅是所限条件下的结果, 千万人访问网站, 要确保每个人使用功能上没有问题, 站点就需要增加错误日志功能, 对mysql, php, 文件系统进行监控.
这里所指的监控并不复杂, 简单到利用php就可以实现. 相信绝大多数的网站程序的结构流程都差不多, 都有公共文件, 都有mysql库类. 日志将记录php的运行错误, 除了不可拯救错误无法抓取外, 其它的错误已经涵盖其中, 这点上李惟的思考上给我提供了很大的灵感. 根据php错误日志流程, 我已经增加了对mysql错误的追踪, 在查询条件, sql语句执行产生错误时, 将会被监控日志所记录, 以便实时解决. 更多的功能将体现在数据分析, 程序优化上, 特别是在公司级应用中, 在与C++与桌面软件做交互应用时, 正常的流程下你根本很难知道执行结果如何, 因为它并不像一般的web一样显示在浏览器上, 它更像一层链接桥, 或者多层链接桥, 你需要思考另一种方式去显示它的运行情况.
同时,mysql承接了绝大多数站点的压力点, 优化mysql变得迫在眉睫, 那作为php技术员, 怎么才能为dba提供一些更加准确的分析数据呢? 这些要求mysql执行日志可以起到作用, 它将记录sql语句在一天内执行的次数, sql语句执行消耗的时间, 更加能够分析出常错的语句及执行页. 这些信息对于信息安全是非常的重要. 也是高级php技术需要理解的. 我把mysql的重要性远远放在于php之上, 目前工作上的瓶颈也是在mysql上, mysql记录上千万, 分表结构无法同步, 每次更新功能都影响全局, 速度过慢, 区域服务器等等.... mysql更多的问题摆在了眼前. 就discuz来看, 当mysql出错时, 是会处理为中止 ( Halt ) 错误, 这点来说对于不同行业, 不同应用是有商议的, 比如api之类的, 返回值仅有 a , b两种, 当有错误信息时, 将影响到所有的流程判断, 所以, 即使mysql执行出错, 我们需要它仍然可以继续运行, 程序只做记录.
php部分.
- 01. register_shutdown_function('error_handler'); // 注册一个结束时触发的函数.
复制代码- 01.# php异常函数,
- 02.function error_handler() {
- 03. // 访问进入两次.
- 04. if($run_count === 1)
- 05. return false;
- 06. static $run_count = 1;
- 07.
- 08. // 获取错误信息
- 09. $error_array = error_get_last();
- 10.
- 11. // 对notice级的错误进行清除
- 12. if($error_array['type'] == 8) {
- 13. $error_array = array();
- 14. }
- 15. // 错误数组不为空时将进入.
- 16. if(empty($error_array) === false) {
- 17. $url = htmlspecialchars($_SERVER['REQUEST_URI']); // 当前请求访问url地址,
- 18. $path = strtr(dirname(__file__),array('include' => '')); // 由于此函数运行时是环境信息已经关闭,所以无法取得相对的路径, 这儿只要计算log_error与error_handler函数文件的位置关系即可, 利用__file__常量来计算.
- 19. $date = date('Y-m-d H:i:s',time()); // 当前时间
- 20. $error = implode(' | ',$error_array); // 将错误代码全部转化为数据.
- 21. file_put_contents($path.'systemdata/log_error.txt',"$date|$url,$error; \n",FILE_APPEND); // 写入日志文件中. 保护一行一条, 并且循环增加开启.
- 22. }
- 23.}
- 复制代码mysql 部分: 这是类当中的query方法, 基本上所有的mysql都会经过这一步, 所以日志就在这方法中处理, 此方法无论你怎么使用, 都不会报中止错误, 程序可以继续往下运行.
- 01.public static function query($query_sql,$mysql_type = false) {
- 02. self::connect();
- 03. if(is_resource(self::$link) === false)
- 04. return false;
- 05.
- 06. if(empty($mysql_type) === true)
- 07. self::$query = mysql_query($query_sql,self::$link);
- 08.
- 09. if(empty($mysql_type) === false)
- 10. self::$query = mysql_unbuffered_query($query_sql,self::$link);
- 11. self::$querynum[] = $query_sql;
- 12.
- 13. $error_state = mysql_error(self::$link);
- 14.
- 15. // mysql 错误日志记录.
- 16. if(empty($error_state) === false){ // 基本上跟php的错误日志相同, 一行一条错误日志.
- 17. $path = strtr(dirname(__FILE__),array('include'=>''));
- 18. $url = htmlspecialchars($_SERVER['REQUEST_URI']);
- 19. $date = date('Y-m-d H:i:s',GET_TIME);
- 20. $query_sql = addslashes($query_sql);
- 21. file_put_contents($path.'systemdata/log_error.txt',"$date||$url||$error_state||$query_sql; \n\n",FILE_APPEND);
- 22. }
- 23.
- 24. # sql 执行时间分析
- 25. // ........
- 26.
- 27. # sql 执行次数分析
- 28. // .........
- 29.
- 30. return self::$query;
- 31.}
复制代码 复制代码完毕. |
|