mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API CHANGE Added SSLogFileWriter to replace Debug::log_errors_to() and Debug::log_error_if_necessary() - the existing formatting for the Debug deprecation functions is now wrapped into SSLogErrorFileFormatter
MINOR Moved SSErrorLogTest to SSLogTest MINOR Documentation updates for SSLog and other bits and pieces git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@84828 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
c4dcf4f2d3
commit
2cca0b0a7b
@ -224,7 +224,9 @@ class Debug {
|
||||
*/
|
||||
static function warningHandler($errno, $errstr, $errfile, $errline, $errcontext) {
|
||||
if(error_reporting() == 0) return;
|
||||
if(self::$send_warnings_to) self::emailError(self::$send_warnings_to, $errno, $errstr, $errfile, $errline, $errcontext, "Warning");
|
||||
if(self::$send_warnings_to) {
|
||||
self::emailError(self::$send_warnings_to, $errno, $errstr, $errfile, $errline, $errcontext, "Warning");
|
||||
}
|
||||
|
||||
// Send out the error details to the logger for writing
|
||||
SSLog::log(
|
||||
@ -238,7 +240,9 @@ class Debug {
|
||||
SSLog::WARN
|
||||
);
|
||||
|
||||
self::log_error_if_necessary( $errno, $errstr, $errfile, $errline, $errcontext, "Warning");
|
||||
if(self::$log_errors_to) {
|
||||
self::log_error_if_necessary( $errno, $errstr, $errfile, $errline, $errcontext, "Warning");
|
||||
}
|
||||
|
||||
if(Director::isDev()) {
|
||||
self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Warning");
|
||||
@ -257,7 +261,9 @@ class Debug {
|
||||
* @param unknown_type $errcontext
|
||||
*/
|
||||
static function fatalHandler($errno, $errstr, $errfile, $errline, $errcontext) {
|
||||
if(self::$send_errors_to) self::emailError(self::$send_errors_to, $errno, $errstr, $errfile, $errline, $errcontext, "Error");
|
||||
if(self::$send_errors_to) {
|
||||
self::emailError(self::$send_errors_to, $errno, $errstr, $errfile, $errline, $errcontext, "Error");
|
||||
}
|
||||
|
||||
// Send out the error details to the logger for writing
|
||||
SSLog::log(
|
||||
@ -271,7 +277,9 @@ class Debug {
|
||||
SSLog::ERR
|
||||
);
|
||||
|
||||
self::log_error_if_necessary( $errno, $errstr, $errfile, $errline, $errcontext, "Error");
|
||||
if(self::$log_errors_to) {
|
||||
self::log_error_if_necessary( $errno, $errstr, $errfile, $errline, $errcontext, "Error");
|
||||
}
|
||||
|
||||
if(Director::isDev() || Director::is_cli()) {
|
||||
self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Error");
|
||||
@ -422,7 +430,7 @@ class Debug {
|
||||
*/
|
||||
static function emailError($emailAddress, $errno, $errstr, $errfile, $errline, $errcontext, $errorType = "Error") {
|
||||
user_error('Debug::send_errors_to() and Debug::emailError() is deprecated. Please use SSLog instead.
|
||||
See the class documentation for SSLog for more information.', E_USER_NOTICE);
|
||||
See the class documentation in SSLog.php for more information.', E_USER_NOTICE);
|
||||
$priority = ($errorType == 'Error') ? SSLog::ERR : SSLog::WARN;
|
||||
$writer = new SSLogEmailWriter($emailAddress);
|
||||
SSLog::add_writer($writer, $priority);
|
||||
@ -447,22 +455,25 @@ class Debug {
|
||||
*
|
||||
* @todo Detect script path for CLI errors
|
||||
* @todo Log detailed errors to full file
|
||||
* @deprecated 2.5 See SSLog on setting up error file logging
|
||||
*/
|
||||
protected static function log_error_if_necessary($errno, $errstr, $errfile, $errline, $errcontext, $errtype) {
|
||||
if(self::$log_errors_to) {
|
||||
$shortFile = "../" . self::$log_errors_to;
|
||||
$fullFile = $shortFile . '.full';
|
||||
|
||||
$relfile = Director::makeRelative($errfile);
|
||||
if($relfile[0] == '/') $relfile = substr($relfile,1);
|
||||
|
||||
$urlSuffix = "";
|
||||
if(isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] && isset($_SERVER['REQUEST_URI'])) {
|
||||
$urlSuffix = " (http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI])";
|
||||
}
|
||||
|
||||
error_log('[' . date('d-M-Y h:i:s') . "] $errtype at $relfile line $errline: $errstr$urlSuffix\n", 3, $shortFile);
|
||||
}
|
||||
user_error('Debug::log_error_if_necessary() and Debug::log_errors_to() are deprecated. Please use SSLog instead.
|
||||
See the class documentation in SSLog.php for more information.', E_USER_NOTICE);
|
||||
$priority = ($errtype == 'Error') ? SSLog::ERR : SSLog::WARN;
|
||||
$writer = new SSLogFileWriter('../' . self::$log_errors_to);
|
||||
SSLog::add_writer($writer, $priority);
|
||||
SSLog::log(
|
||||
array(
|
||||
'errno' => $errno,
|
||||
'errstr' => $errstr,
|
||||
'errfile' => $errfile,
|
||||
'errline' => $errline,
|
||||
'errcontext' => $errcontext
|
||||
),
|
||||
$priority
|
||||
);
|
||||
SSLog::remove_writer($writer);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -522,6 +533,7 @@ class Debug {
|
||||
|
||||
/**
|
||||
* Call this to enable logging of errors.
|
||||
* @deprecated 2.5 See SSLog on setting up error file logging
|
||||
*/
|
||||
static function log_errors_to($logFile = ".sserrors") {
|
||||
self::$log_errors_to = $logFile;
|
||||
|
@ -12,11 +12,28 @@
|
||||
*
|
||||
* You can add an error writer by calling {@link SSLog::add_writer()}
|
||||
*
|
||||
* Example usage (called from mysite/_config.php) which adds a writer
|
||||
* that will write all errors:
|
||||
* Example usage of logging errors by email notification:
|
||||
* <code>
|
||||
* $emailWriter = new SSErrorEmailWriter('my@email.com');
|
||||
* SSLog::add_writer($emailWriter, SSLog::ERR);
|
||||
* $logEmailWriter = new SSErrorEmailWriter('my@email.com');
|
||||
* SSLog::add_writer($logEmailWriter, SSLog::ERR);
|
||||
* </code>
|
||||
*
|
||||
* Example usage of logging errors by file:
|
||||
* <code>
|
||||
* $logFileWriter = new SSLogFileWriter('/var/log/silverstripe/errors.log');
|
||||
* SSLog::add_writer($logFileWriter, SSLog::ERR);
|
||||
* </code>
|
||||
*
|
||||
* Each writer object can be assigned a formatter. The formatter is
|
||||
* responsible for formatting the message before giving it to the writer.
|
||||
* {@link SSLogErrorEmailFormatter} is such an example that formats errors
|
||||
* into HTML for human readability in an email client.
|
||||
*
|
||||
* Formatters are added to writers like this:
|
||||
* <code>
|
||||
* $logEmailWriter = new SSErrorEmailWriter('my@email.com');
|
||||
* $myEmailFormatter = new MyLogEmailFormatter();
|
||||
* $logEmailWriter->setFormatter($myEmailFormatter);
|
||||
* </code>
|
||||
*
|
||||
* @package sapphire
|
||||
@ -65,6 +82,13 @@ class SSLog {
|
||||
return self::get_logger()->getWriters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all writers currently in use.
|
||||
*/
|
||||
public static function clear_writers() {
|
||||
self::get_logger()->clearWriters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a writer instance from the logger.
|
||||
* @param object $writer Zend_Log_Writer_Abstract instance
|
||||
|
@ -23,8 +23,8 @@ class SSLogEmailWriter extends Zend_Log_Writer_Abstract {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email to the designated emails set in
|
||||
* {@link Debug::send_errors_to()}
|
||||
* Send an email to the email address set in
|
||||
* this writer.
|
||||
*/
|
||||
public function _write($event) {
|
||||
// If no formatter set up, use the default
|
||||
|
42
dev/SSLogErrorFileFormatter.php
Normal file
42
dev/SSLogErrorFileFormatter.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Formats SS error entries in an error file log.
|
||||
* Format: [d-M-Y h:i:s] <type> at <file> line <line>: <errormessage> <url>
|
||||
* @package sapphire
|
||||
* @subpackage dev
|
||||
*/
|
||||
|
||||
require_once 'Zend/Log/Formatter/Interface.php';
|
||||
|
||||
class SSLogErrorFileFormatter implements Zend_Log_Formatter_Interface {
|
||||
|
||||
public function format($event) {
|
||||
$errno = $event['message']['errno'];
|
||||
$errstr = $event['message']['errstr'];
|
||||
$errfile = $event['message']['errfile'];
|
||||
$errline = $event['message']['errline'];
|
||||
$errcontext = $event['message']['errcontext'];
|
||||
|
||||
switch($event['priorityName']) {
|
||||
case 'ERR':
|
||||
$errtype = 'Error';
|
||||
break;
|
||||
case 'WARN':
|
||||
$errtype = 'Warning';
|
||||
break;
|
||||
case 'NOTICE':
|
||||
$errtype = 'Notice';
|
||||
break;
|
||||
}
|
||||
|
||||
$urlSuffix = '';
|
||||
$relfile = Director::makeRelative($errfile);
|
||||
if($relfile[0] == '/') $relfile = substr($relfile, 1);
|
||||
if(isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] && isset($_SERVER['REQUEST_URI'])) {
|
||||
$urlSuffix = " (http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI])";
|
||||
}
|
||||
|
||||
return '[' . date('d-M-Y h:i:s') . "] $errtype at $relfile line $errline: $errstr$urlSuffix\n";
|
||||
}
|
||||
|
||||
}
|
62
dev/SSLogFileWriter.php
Normal file
62
dev/SSLogFileWriter.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Sends an error message to an email whenever an
|
||||
* error occurs in sapphire.
|
||||
*
|
||||
* Note: You need to make sure your web server is able
|
||||
* to write to the file path that you specify to write
|
||||
* logs to.
|
||||
*
|
||||
* @uses error_log() built-in PHP function.
|
||||
* @see SSLog for more information on using writers.
|
||||
*
|
||||
* @package sapphire
|
||||
* @subpackage dev
|
||||
*/
|
||||
|
||||
require_once 'Zend/Log/Writer/Abstract.php';
|
||||
|
||||
class SSLogFileWriter extends Zend_Log_Writer_Abstract {
|
||||
|
||||
/**
|
||||
* The path to the file that errors will be stored in.
|
||||
* For example, "/var/logs/silverstripe/errors.log".
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Message type to pass to error_log()
|
||||
* @see http://us3.php.net/manual/en/function.error-log.php
|
||||
* @var int
|
||||
*/
|
||||
protected $messageType;
|
||||
|
||||
/**
|
||||
* Extra headers to pass to error_log()
|
||||
* @see http://us3.php.net/manual/en/function.error-log.php
|
||||
* @var string
|
||||
*/
|
||||
protected $extraHeaders;
|
||||
|
||||
public function __construct($path, $messageType = 3, $extraHeaders = '') {
|
||||
$this->path = $path;
|
||||
$this->messageType = $messageType;
|
||||
$this->extraHeaders = $extraHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the log message to the file path set
|
||||
* in this writer.
|
||||
*/
|
||||
public function _write($event) {
|
||||
if(!$this->_formatter) {
|
||||
$formatter = new SSLogErrorFileFormatter();
|
||||
$this->setFormatter($formatter);
|
||||
}
|
||||
$message = $this->_formatter->format($event);
|
||||
error_log($message, $this->messageType, $this->path, $this->extraHeaders);
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
* Modifications to Zend_Log to make it work nicer
|
||||
* with {@link SSLog}. Specifically, this includes removing
|
||||
* writers that have been added to the logger, as well as
|
||||
* listing which ones are currently in use since the Zend_Log
|
||||
* API does not support these methods.
|
||||
* Extensions to Zend_Log to make it work nicer
|
||||
* with {@link SSLog}.
|
||||
*
|
||||
* Please refer to {@link SSLog} for information on
|
||||
* setting up logging for your projects.
|
||||
*
|
||||
* @package sapphire
|
||||
* @subpackage dev
|
||||
@ -14,14 +14,16 @@ require_once 'Zend/Log.php';
|
||||
|
||||
class SSZendLog extends Zend_Log {
|
||||
|
||||
/**
|
||||
* Get all writers in this logger.
|
||||
* @return array of Zend_Log_Writer_Abstract instances
|
||||
*/
|
||||
public function getWriters() {
|
||||
return $this->_writers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a writer instance that exists in
|
||||
* the current writers collection for this logger.
|
||||
*
|
||||
* Remove a writer instance that exists in this logger.
|
||||
* @param object Zend_Log_Writer_Abstract instance
|
||||
*/
|
||||
public function removeWriter($writer) {
|
||||
@ -32,4 +34,11 @@ class SSZendLog extends Zend_Log {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all writers in this logger.
|
||||
*/
|
||||
public function clearWriters() {
|
||||
$this->_writers = array();
|
||||
}
|
||||
|
||||
}
|
@ -9,20 +9,27 @@ class SSLogTest extends SapphireTest {
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
SSLog::clear_writers(); // this test will break if existing writers are available!
|
||||
$this->testEmailWriter = new SSLogEmailWriter('sean@silverstripe.com');
|
||||
$this->testFileWriter = new SSLogFileWriter('../test.log');
|
||||
SSLog::add_writer($this->testEmailWriter, SSLog::ERR);
|
||||
SSLog::add_writer($this->testFileWriter, SSLog::WARN);
|
||||
}
|
||||
|
||||
function testExistingWriter() {
|
||||
$writers = SSLog::get_writers();
|
||||
$this->assertType('array', $writers);
|
||||
$this->assertEquals(1, count($writers));
|
||||
$this->assertEquals(2, count($writers));
|
||||
}
|
||||
|
||||
function testRemoveWriter() {
|
||||
SSLog::remove_writer($this->testEmailWriter);
|
||||
$writers = SSLog::get_writers();
|
||||
$this->assertType('array', $writers);
|
||||
$this->assertEquals(1, count($writers));
|
||||
SSLog::remove_writer($this->testFileWriter);
|
||||
$writers = SSLog::get_writers();
|
||||
$this->assertType('array', $writers);
|
||||
$this->assertEquals(0, count($writers));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user