Merge pull request #29 from chillu/pulls/log-check-failures

Log check failures
This commit is contained in:
Sam Minnée 2015-11-20 13:49:11 +13:00
commit 1ef045d1b7
5 changed files with 191 additions and 11 deletions

View File

@ -173,6 +173,13 @@ class EnvironmentCheckSuite extends Object {
if(!is_array($names)) $names = array($names);
foreach($names as $name) self::inst($name)->push($check, $title);
}
/**
* Unregisters all checks.
*/
static function reset() {
self::$instances = array();
}
}
/**
@ -203,6 +210,7 @@ class EnvironmentCheckSuiteResult extends ViewableData {
$this->details->push(new ArrayData(array(
'Check' => $checkIdentifier,
'Status' => $this->statusText($status),
'StatusCode' => $status,
'Message' => $message,
)));

View File

@ -29,17 +29,37 @@ class EnvironmentChecker extends RequestHandler {
/**
* @var null|string
*/
public static $to_email_address = null;
private static $to_email_address = null;
/**
* @var null|string
*/
public static $from_email_address = null;
private static $from_email_address = null;
/**
* @var bool
*/
public static $email_results = false;
private static $email_results = false;
/**
* @var bool Log results via {@link SS_Log}
*/
private static $log_results_warning = false;
/**
* @var int Maps to {@link Zend_Log} levels. Defaults to Zend_Log::WARN
*/
private static $log_results_warning_level = 4;
/**
* @var bool Log results via {@link SS_Log}
*/
private static $log_results_error = false;
/**
* @var int Maps to {@link Zend_Log} levels. Defaults to Zend_Log::ALERT
*/
private static $log_results_error_level = 1;
/**
* @param string $checkSuiteName
@ -146,11 +166,26 @@ class EnvironmentChecker extends RequestHandler {
"ErrorCode" => $this->errorCode,
))->renderWith("EnvironmentChecker");
if (self::$email_results && !$result->ShouldPass()) {
$email = new Email(self::$from_email_address, self::$to_email_address, $this->title, $resultText);
if ($this->config()->email_results && !$result->ShouldPass()) {
$email = new Email($this->config()->from_email_address, $this->config()->to_email_address, $this->title, $resultText);
$email->send();
}
// Optionally log errors and warnings individually
foreach($result->Details() as $detail) {
if($this->config()->log_results_warning && $detail->StatusCode == EnvironmentCheck::WARNING) {
$this->log(
sprintf('EnvironmentChecker warning at "%s" check. Message: %s', $detail->Check, $detail->Message),
$this->config()->log_results_warning_level
);
} elseif($this->config()->log_results_error && $detail->StatusCode == EnvironmentCheck::ERROR) {
$this->log(
sprintf('EnvironmentChecker error at "%s" check. Message: %s', $detail->Check, $detail->Message),
$this->config()->log_results_error_level
);
}
}
// output the result as JSON if requested
if(
$this->getRequest()->getExtension() == 'json'
@ -166,6 +201,14 @@ class EnvironmentChecker extends RequestHandler {
return $response;
}
/**
* @param string $message
* @param int $level
*/
public function log($message, $level) {
SS_Log::log($message, $level);
}
/**
* Set the HTTP status code that should be returned when there's an error.
*
@ -176,44 +219,56 @@ class EnvironmentChecker extends RequestHandler {
}
/**
* @deprecated
* @param string $from
*/
public static function set_from_email_address($from) {
self::$from_email_address = $from;
Deprecation::notice('2.0', 'Use config API instead');
Config::inst()->update('EnvironmentChecker', 'from_email_address', $from);
}
/**
* @deprecated
* @return null|string
*/
public static function get_from_email_address() {
return self::$from_email_address;
Deprecation::notice('2.0', 'Use config API instead');
return Config::inst()->get('EnvironmentChecker', 'from_email_address');
}
/**
* @deprecated
* @param string $to
*/
public static function set_to_email_address($to) {
self::$to_email_address = $to;
Deprecation::notice('2.0', 'Use config API instead');
Config::inst()->update('EnvironmentChecker', 'to_email_address', $to);
}
/**
* @deprecated
* @return null|string
*/
public static function get_to_email_address() {
return self::$to_email_address;
Deprecation::notice('2.0', 'Use config API instead');
return Config::inst()->get('EnvironmentChecker', 'to_email_address');
}
/**
* @deprecated
* @param bool $results
*/
public static function set_email_results($results) {
self::$email_results = $results;
Deprecation::notice('2.0', 'Use config API instead');
Config::inst()->update('EnvironmentChecker', 'email_results', $results);
}
/**
* @deprecated
* @return bool
*/
public static function get_email_results() {
return self::$email_results;
Deprecation::notice('2.0', 'Use config API instead');
return Config::inst()->get('EnvironmentChecker', 'email_results');
}
}

View File

@ -17,6 +17,10 @@
{
"silverstripe/framework": "~3.1"
},
"require-dev":
{
"hafriedlander/phockito": "dev-master"
},
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"

View File

@ -83,6 +83,30 @@ EnvironmentCheckSuite:
* `SMTPConnectCheck`: Checks if the SMTP connection configured through PHP.ini works as expected.
* `SolrIndexCheck`: Checks if the Solr cores of given class are available.
## Monitoring Checks
Checks will return an appropriate HTTP status code, so are easy to hook into common uptime montoring
solutions like pingdom.com.
You can also have the environment checker email results with the following configuration:
```yml
EnvironmentChecker:
email_results: true
to_email_address: support@test.com
from_email_address: admin@test.com
```
Errors can be logged via the standard SilverStripe logging. Each check will cause an individual log entry.
You can choose to enable logging separately for warnings and errors,
identified through the result of `EnvironmentCheck->check()`.
```yml
EnvironmentChecker:
log_results_warning: true
log_results_error: true
```
## Authentication
By default, accessing the `dev/check` URL will not require authentication on CLI and dev environments, but if you're

View File

@ -0,0 +1,89 @@
<?php
class EnvironmentCheckerTest extends SapphireTest {
public function setUpOnce() {
parent::setUpOnce();
Phockito::include_hamcrest();
}
public function setUp() {
parent::setUp();
Config::nest();
}
public function tearDown() {
Config::unnest();
parent::tearDown();
}
public function testOnlyLogsWithErrors() {
Config::inst()->update('EnvironmentChecker', 'log_results_warning', true);
Config::inst()->update('EnvironmentChecker', 'log_results_error', true);
EnvironmentCheckSuite::register('test suite', new EnvironmentCheckerTest_CheckNoErrors());
$checker = Phockito::spy(
'EnvironmentChecker',
'test suite',
'test'
);
$response = $checker->index();
Phockito::verify($checker, 0)->log(anything(), anything());
EnvironmentCheckSuite::reset();
}
public function testLogsWithWarnings() {
Config::inst()->update('EnvironmentChecker', 'log_results_warning', true);
Config::inst()->update('EnvironmentChecker', 'log_results_error', false);
EnvironmentCheckSuite::register('test suite', new EnvironmentCheckerTest_CheckWarnings());
EnvironmentCheckSuite::register('test suite', new EnvironmentCheckerTest_CheckErrors());
$checker = Phockito::spy(
'EnvironmentChecker',
'test suite',
'test'
);
$response = $checker->index();
Phockito::verify($checker, 1)->log(containsString('warning'), anything());
Phockito::verify($checker, 0)->log(containsString('error'), anything());
EnvironmentCheckSuite::reset();
}
public function testLogsWithErrors() {
Config::inst()->update('EnvironmentChecker', 'log_results_error', false);
Config::inst()->update('EnvironmentChecker', 'log_results_error', true);
EnvironmentCheckSuite::register('test suite', new EnvironmentCheckerTest_CheckWarnings());
EnvironmentCheckSuite::register('test suite', new EnvironmentCheckerTest_CheckErrors());
$checker = Phockito::spy(
'EnvironmentChecker',
'test suite',
'test'
);
$response = $checker->index();
Phockito::verify($checker, 0)->log(containsString('warning'), anything());
Phockito::verify($checker, 1)->log(containsString('error'), anything());
EnvironmentCheckSuite::reset();
}
}
class EnvironmentCheckerTest_CheckNoErrors implements EnvironmentCheck, TestOnly{
public function check() {
return array(EnvironmentCheck::OK, '');
}
}
class EnvironmentCheckerTest_CheckWarnings implements EnvironmentCheck, TestOnly{
public function check() {
return array(EnvironmentCheck::WARNING, "test warning");
}
}
class EnvironmentCheckerTest_CheckErrors implements EnvironmentCheck, TestOnly{
public function check() {
return array(EnvironmentCheck::ERROR, "test error");
}
}