[ Index ]

PHP Cross Reference of Eventum

title

Body

[close]

/include/ -> class.error_handler.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 encoding=utf-8: */
   3  // +----------------------------------------------------------------------+
   4  // | Eventum - Issue Tracking System                                      |
   5  // +----------------------------------------------------------------------+
   6  // | Copyright (c) 2003, 2004, 2005, 2006, 2007 MySQL AB                  |
   7  // |                                                                      |
   8  // | This program is free software; you can redistribute it and/or modify |
   9  // | it under the terms of the GNU General Public License as published by |
  10  // | the Free Software Foundation; either version 2 of the License, or    |
  11  // | (at your option) any later version.                                  |
  12  // |                                                                      |
  13  // | This program is distributed in the hope that it will be useful,      |
  14  // | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
  15  // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
  16  // | GNU General Public License for more details.                         |
  17  // |                                                                      |
  18  // | You should have received a copy of the GNU General Public License    |
  19  // | along with this program; if not, write to:                           |
  20  // |                                                                      |
  21  // | Free Software Foundation, Inc.                                       |
  22  // | 59 Temple Place - Suite 330                                          |
  23  // | Boston, MA 02111-1307, USA.                                          |
  24  // +----------------------------------------------------------------------+
  25  // | Authors: João Prado Maia <jpm@mysql.com>                             |
  26  // +----------------------------------------------------------------------+
  27  //
  28  // @(#) $Id: class.error_handler.php 3488 2007-11-22 08:25:13Z glen $
  29  //
  30  
  31  require_once (APP_INC_PATH . "class.misc.php");
  32  require_once (APP_INC_PATH . "class.mail.php");
  33  require_once (APP_INC_PATH . "class.setup.php");
  34  
  35  /**
  36   * Class to manage all tasks related to error conditions of the site, such as
  37   * logging facilities or alert notifications to the site administrators.
  38   *
  39   * @version 1.0
  40   * @author João Prado Maia <jpm@mysql.com>
  41   */
  42  
  43  class Error_Handler
  44  {
  45      /**
  46       * Logs the error condition to a specific file and if asked and possible
  47       * queue error in mail queue for reporting.
  48       *
  49       * @access public
  50       * @param  mixed $error_msg The error message
  51       * @param  string $script The script name where the error happened
  52       * @param  integer $line The line number where the error happened
  53       * @param  boolean $notify_error Whether error should be notified by email.
  54       */
  55      function logError($error_msg = 'unknown', $script = 'unknown', $line = 'unknown', $notify_error = true)
  56      {
  57          $msg =& Error_Handler::_createErrorReport($error_msg, $script, $line);
  58          $fp = @fopen(APP_ERROR_LOG, 'a');
  59          fwrite($fp, '[' . date('D M d H:i:s Y') . '] ');
  60          fwrite($fp, $msg);
  61          fclose($fp);
  62  
  63          // if there's no db_api object, then we cannot
  64          // possibly queue up the error emails
  65          if ($notify_error === false || is_null(@$GLOBALS['db_api'])) {
  66              return;
  67          }
  68  
  69          $setup = Setup::load();
  70          if (@$setup['email_error']['status'] == 'enabled') {
  71              $notify_list = trim($setup['email_error']['addresses']);
  72              if (empty($notify_list)) {
  73                  return false;
  74              }
  75              Error_Handler::_notify($msg, $setup['smtp']['from'], $notify_list, $script, $line);
  76          }
  77      }
  78  
  79      /**
  80       * Notifies site administrators of the error condition
  81       *
  82       * @access private
  83       * @param  string $notify_msg The formatted error message
  84       * @param  string $notify_from Sender of the email
  85       * @param  string $notify_list Email addresses to whom send the error report.
  86       */
  87      function _notify(&$notify_msg, $notify_from, $notify_list, $script, $line)
  88      {
  89  
  90          $time = time();
  91          $date = date('m/d/Y H:i:s', $time);
  92          $msg = "Hello,\n\n";
  93          $msg .= $notify_msg;
  94  
  95          // this checks that we're not running from commandline (cron for example)
  96          if (isset($_SERVER['REMOTE_ADDR'])) {
  97              $msg .= "That happened on page '" . $_SERVER['SCRIPT_NAME'] . "' from IP Address '" . $_SERVER['REMOTE_ADDR'] . "' coming from the page (referrer) '" . $_SERVER['HTTP_REFERER'] . "'.\n\n";
  98              $msg .= "The user agent given was '" . $_SERVER['HTTP_USER_AGENT'] . "'.\n\n";
  99          }
 100          $msg .= "-- \nSincerely yours,\nAutomated Error_Handler Class";
 101  
 102          // query database for 'max_allowed_packet'
 103          $stmt = "show variables like 'max_allowed_packet'";
 104          $res =& $GLOBALS['db_api']->dbh->query($stmt);
 105          if (PEAR::isError($res)) {
 106              // we failed, assume 8M
 107              $max_allowed_packet = 8387584;
 108          } else {
 109              $arr = $res->fetchRow(DB_FETCHMODE_ORDERED);
 110              $max_allowed_packet = $arr[1];
 111              $res->free();
 112          }
 113  
 114          // skip error details of an email notification about a query that
 115          // was bigger than max_allowed_packet + 1024
 116          if (strlen($msg) > $max_allowed_packet + 1024) {
 117              return false;
 118          }
 119  
 120          $notify_list = str_replace(';', ',', $notify_list);
 121          $notify_list = explode(',', $notify_list);
 122          $subject = APP_SITE_NAME . ' - Error found! - ' . $date;
 123  
 124          foreach ($notify_list as $notify_email) {
 125              $mail = new Mail_API;
 126              $mail->setTextBody($msg);
 127              $mail->send($notify_from, $notify_email, $subject, 0, false, 'error');
 128          }
 129      }
 130  
 131      /**
 132       * Creates error report.
 133       *
 134       * @access private
 135       * @param  mixed $error_msg The error message
 136       * @param  string $script The script name where the error happened
 137       * @param  integer $line The line number where the error happened
 138       */
 139      function &_createErrorReport(&$error_msg, $script, $line)
 140      {
 141          $msg = "An error was found on line '" . $line . "' of script " . "'$script'.\n\n";
 142  
 143          $msg .= "The error message passed to us was:\n\n";
 144          if ((is_array($error_msg)) && (count($error_msg) > 1)) {
 145              $msg .= "'" . $error_msg[0] . "'\n\n";
 146              $msg .= "A more detailed error message follows:\n\n";
 147              $error_msg = $error_msg[1];
 148          }
 149  
 150          if (strlen($error_msg) > 1024) {
 151              $msg .= "'" . substr($error_msg, 0, 1024) . "' ...";
 152  
 153              // try to find native code from DB error
 154              // [nativecode=1153 ** Got a packet bigger than 'max_allowed_packet' bytes]'
 155              $nativecode = strstr($error_msg, '[nativecode=');
 156              if ($nativecode) {
 157                  $msg .= ' ' . $nativecode;
 158              }
 159              $msg .= "\n";
 160          } else {
 161              $msg .= "'" . $error_msg . "'\n";
 162          }
 163  
 164          // only try to include the backtrace if we are on PHP 4.3.0 or later
 165          if (function_exists('debug_backtrace')) {
 166              $msg .= "\nA backtrace is available:\n\n";
 167              $backtrace = debug_backtrace();
 168              // remove the two entries related to the error handling stuff itself
 169              array_splice($backtrace, 0, 2);
 170  
 171              // we process backtrace to truncate large blobs
 172              $cutoff = 1024;
 173              foreach ($backtrace as $e) {
 174                  // backtrace frame contains: [file] [line] [function] [class] [type] [args]
 175                  $f = $e['file'];
 176                  $f = str_replace(APP_INC_PATH, 'APP_INC_PATH/', $f);
 177                  $f = str_replace(APP_PATH, 'APP_PATH/', $f);
 178  
 179                  $fn = $e['function'];
 180                  if (isset($e['class'])) {
 181                      $fn = $e['class']. $e['type']. $fn;
 182                  }
 183                  $a = '';
 184                  if ($e['args']) {
 185                      $z = array();
 186                      foreach ($e['args'] as $x) {
 187                          if (is_string($x)) {
 188                              if (strlen($x) > $cutoff) {
 189                                  $z[] = sprintf("(string )'%.{$cutoff}s'...", $x);
 190                              } else {
 191                                  $z[] = sprintf("(string )'%s'", $x);
 192                              }
 193                          } elseif (is_object($x)) {
 194                              $z[] = 'Object '. get_class($x);
 195  
 196                          } elseif (is_bool($x)) {
 197                              $z[] = '(bool ) '.$x ? 'true' : 'false';
 198  
 199                          } else {
 200                              $z[] = '(' . gettype($x). ' )' . $x;
 201                          }
 202                      }
 203                      $a = join(', ', $z);
 204                  }
 205                  $msg .= sprintf("%s:%d\n  %s(%s)\n", $f, $e['line'], $fn, $a);
 206              }
 207  
 208              $msg .= "\n\n";
 209          }
 210          return $msg;
 211      }
 212  }
 213  
 214  // benchmarking the included file (aka setup time)
 215  if (APP_BENCHMARK) {
 216      $GLOBALS['bench']->setMarker('Included Error_Handler Class');
 217  }


Generated: Wed Dec 19 21:21:33 2007 Cross-referenced by PHPXref 0.7