forked from learnable/php-airbrake-notifier
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove the dependency on Horde's YAML library.
Add ability to specify the environment the app is running in. Support v2 of the Hoptoad API.
- Loading branch information
Showing
3 changed files
with
179 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,123 +1,177 @@ | |||
<?php | <?php | ||
if (!class_exists('HTTP_Request')) require_once('HTTP/Request.php'); | if (!class_exists('HTTP_Request2')) require_once('HTTP/Request2.php'); | ||
if (!class_exists('Horde_Yaml')) require_once('Horde/Yaml.php'); | if (!class_exists('HTTP_Request2_Adapter_Socket')) require_once 'HTTP/Request2/Adapter/Socket.php'; | ||
if (!class_exists('Horde_Yaml_Dumper')) require_once('Horde/Yaml/Dumper.php'); | |||
|
|
||
class Hoptoad | class Hoptoad | ||
{ | { | ||
/** | const NOTIFIER_NAME = 'php-hoptoad-notifier'; | ||
* Install the error and exception handlers that connect to Hoptoad | const NOTIFIER_VERSION = '0.2.0'; | ||
* | const NOTIFIER_URL = 'http://github.com/rich/php-hoptoad-notifier'; | ||
* @return void | const NOTIFIER_API_VERSION = '2.0'; | ||
* @author Rich Cavanaugh |
|
||
*/ | /** | ||
public static function installHandlers($api_key=NULL) | * Install the error and exception handlers that connect to Hoptoad | ||
{ | * | ||
if (isset($api_key)) define('HOPTOAD_API_KEY', $api_key); | * @return void | ||
|
* @author Rich Cavanaugh | ||
set_error_handler(array("Hoptoad", "errorHandler")); | */ | ||
set_exception_handler(array("Hoptoad", "exceptionHandler")); | public static function installHandlers($api_key=NULL, $environment=NULL) | ||
} | { | ||
|
if (isset($api_key)) define('HOPTOAD_API_KEY', $api_key); | ||
/** | if (isset($environment)) define('HOPTOAD_APP_ENVIRONMENT', $environment); | ||
* Handle a php error |
|
||
* | set_error_handler(array("Hoptoad", "errorHandler")); | ||
* @param string $code | set_exception_handler(array("Hoptoad", "exceptionHandler")); | ||
* @param string $message | } | ||
* @param string $file |
|
||
* @param string $line | /** | ||
* @return void | * Handle a php error | ||
* @author Rich Cavanaugh | * | ||
*/ | * @param string $code | ||
public static function errorHandler($code, $message, $file, $line) | * @param string $message | ||
{ | * @param string $file | ||
if ($code == E_STRICT) return; | * @param string $line | ||
|
* @return void | ||
$trace = Hoptoad::tracer(); | * @author Rich Cavanaugh | ||
Hoptoad::notifyHoptoad(HOPTOAD_API_KEY, $message, $file, $line, $trace, null); | */ | ||
} | public static function errorHandler($code, $message, $file, $line) | ||
|
{ | ||
/** | if ($code == E_STRICT) return; | ||
* Handle a raised exception |
|
||
* | $trace = Hoptoad::tracer(); | ||
* @param string $exception | Hoptoad::notifyHoptoad(HOPTOAD_API_KEY, $message, $file, $line, $trace, null, HOPTOAD_APP_ENVIRONMENT); | ||
* @return void | } | ||
* @author Rich Cavanaugh |
|
||
*/ | /** | ||
public static function exceptionHandler($exception) | * Handle a raised exception | ||
{ | * | ||
$trace = Hoptoad::tracer($exception->getTrace()); | * @param string $exception | ||
|
* @return void | ||
Hoptoad::notifyHoptoad(HOPTOAD_API_KEY, $exception->getMessage(), $exception->getFile(), $exception->getLine(), $trace, null); | * @author Rich Cavanaugh | ||
} | */ | ||
|
public static function exceptionHandler($exception) | ||
/** | { | ||
* Pass the error and environment data on to Hoptoad | $trace = Hoptoad::tracer($exception->getTrace()); | ||
* |
|
||
* @package default | Hoptoad::notifyHoptoad(HOPTOAD_API_KEY, $exception->getMessage(), $exception->getFile(), $exception->getLine(), $trace, null, HOPTOAD_APP_ENVIRONMENT); | ||
* @author Rich Cavanaugh | } | ||
*/ |
|
||
public static function notifyHoptoad($api_key, $message, $file, $line, $trace, $error_class=null) | /** | ||
{ | * Pass the error and environment data on to Hoptoad | ||
$req =& new HTTP_Request("http://hoptoadapp.com/notices/", array("method" => "POST", "timeout" => 2)); | * | ||
$req->addHeader('Accept', 'text/xml, application/xml'); | * @package default | ||
$req->addHeader('Content-type', 'application/x-yaml'); | * @author Rich Cavanaugh | ||
|
*/ | ||
array_unshift($trace, "$file:$line"); | public static function notifyHoptoad($api_key, $message, $file, $line, $trace, $error_class=null, $environment='production') | ||
|
{ | ||
if (isset($_SESSION)) { | array_unshift($trace, "$file:$line"); | ||
$session = array('key' => session_id(), 'data' => $_SESSION); |
|
||
} else { | $adapter = new HTTP_Request2_Adapter_Socket; | ||
$session = array(); | $req = new HTTP_Request2("http://hoptoadapp.com/notifier_api/v2/notices", HTTP_Request2::METHOD_POST); | ||
} | $req->setAdapter($adapter); | ||
|
$req->setHeader(array( | ||
$url = "http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"; | 'Accept' => 'text/xml, application/xml', | ||
$body = array( | 'Content-Type' => 'text/xml' | ||
'api_key' => $api_key, | )); | ||
'error_class' => $error_class, | $req->setBody(self::buildXmlNotice($api_key, $message, $trace, $error_class, $environment)); | ||
'error_message' => $message, | echo $req->send()->getBody(); | ||
'backtrace' => $trace, | } | ||
'request' => array("params" => $_REQUEST, "url" => $url), |
|
||
'session' => $session, | /** | ||
'environment' => $_SERVER | * Build up the XML to post according to the documentation at: | ||
); | * http://help.hoptoadapp.com/faqs/api-2/notifier-api-v2 | ||
|
* @return string | ||
$req->setBody(Horde_Yaml::dump(array("notice" => $body))); | * @author Rich Cavanaugh | ||
$req->sendRequest(); | **/ | ||
} | public static function buildXmlNotice($api_key, $message, $trace, $error_class, $environment, $component='') | ||
|
{ | ||
/** | $doc = new SimpleXMLElement('<notice />'); | ||
* Build a trace that is formatted in the way Hoptoad expects | $doc->addAttribute('version', self::NOTIFIER_API_VERSION); | ||
* | $doc->addChild('api-key', $api_key); | ||
* @param string $trace |
|
||
* @return void | $notifier = $doc->addChild('notifier'); | ||
* @author Rich Cavanaugh | $notifier->addChild('name', self::NOTIFIER_NAME); | ||
*/ | $notifier->addChild('version', self::NOTIFIER_VERSION); | ||
public static function tracer($trace = NULL) | $notifier->addChild('url', self::NOTIFIER_URL); | ||
{ |
|
||
$lines = Array(); | $error = $doc->addChild('error'); | ||
|
$error->addChild('class', $error_class); | ||
$trace = $trace ? $trace : debug_backtrace(); | $error->addChild('message', $message); | ||
|
|
||
$indent = ''; | $backtrace = $error->addChild('backtrace'); | ||
$func = ''; | foreach ($trace as $line) { | ||
|
$line_node = $backtrace->addChild('line'); | ||
foreach($trace as $val) { | list($file, $number) = explode(':', $line); | ||
if (isset($val['class']) && $val['class'] == 'Hoptoad') continue; | $line_node->addAttribute('file', $file); | ||
|
$line_node->addAttribute('number', $number); | ||
$file = isset($val['file']) ? $val['file'] : 'Unknown file'; | $line_node->addAttribute('method', ''); | ||
$line_number = isset($val['line']) ? $val['line'] : ''; | } | ||
$func = isset($val['function']) ? $val['function'] : ''; |
|
||
$class = isset($val['class']) ? $val['class'] : ''; | $request = $doc->addChild('request'); | ||
|
$request->addChild('url', "http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"); | ||
$line = $file; | $request->addChild('component', $component); | ||
if ($line_number) $line .= ':' . $line_number; |
|
||
if ($func) $line .= ' in function ' . $func; | if (isset($_REQUEST) && !empty($_REQUEST)) { | ||
if ($class) $line .= ' in class ' . $class; | $params = $request->addChild('params'); | ||
|
foreach ($_REQUEST as $key => $val) { | ||
$lines[] = $line; | $var_node = $params->addChild('var', $val); | ||
} | $var_node->addAttribute('key', $key); | ||
|
} | ||
return $lines; | } | ||
} |
|
||
} | if (isset($_SESSION) && !empty($_SESSION)) { | ||
$session = $request->addChild('session'); | |||
foreach ($_SESSION as $key => $val) { | |||
$var_node = $session->addChild('var', $val); | |||
$var_node->addAttribute('key', $key); | |||
} | |||
} | |||
|
|||
$cgi_data = $request->addChild('cgi-data'); | |||
foreach ($_SERVER as $key => $val) { | |||
$var_node = $cgi_data->addChild('var', $val); | |||
$var_node->addAttribute('key', $key); | |||
} | |||
|
|||
$env = $doc->addChild('server-environment'); | |||
$env->addChild('project-root', $_SERVER['DOCUMENT_ROOT']); | |||
$env->addChild('environment-name', $environment); | |||
|
|||
return $doc->asXML(); | |||
} | |||
|
|||
/** | |||
* Build a trace that is formatted in the way Hoptoad expects | |||
* | |||
* @param string $trace | |||
* @return void | |||
* @author Rich Cavanaugh | |||
*/ | |||
public static function tracer($trace = NULL) | |||
{ | |||
$lines = Array(); | |||
|
|||
$trace = $trace ? $trace : debug_backtrace(); | |||
|
|||
$indent = ''; | |||
$func = ''; | |||
|
|||
foreach($trace as $val) { | |||
if (isset($val['class']) && $val['class'] == 'Hoptoad') continue; | |||
|
|||
$file = isset($val['file']) ? $val['file'] : 'Unknown file'; | |||
$line_number = isset($val['line']) ? $val['line'] : ''; | |||
$func = isset($val['function']) ? $val['function'] : ''; | |||
$class = isset($val['class']) ? $val['class'] : ''; | |||
|
|||
$line = $file; | |||
if ($line_number) $line .= ':' . $line_number; | |||
if ($func) $line .= ' in function ' . $func; | |||
if ($class) $line .= ' in class ' . $class; | |||
|
|||
$lines[] = $line; | |||
} | |||
|
|||
return $lines; | |||
} | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,4 +1,4 @@ | |||
<?php | <?php | ||
require_once('Hoptoad.php'); | require_once('Hoptoad.php'); | ||
|
|
||
Hoptoad::installHandlers("YOUR_HOPTOAD_API_KEY"); | Hoptoad::installHandlers("YOUR_HOPTOAD_API_KEY", 'production'); |