-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: COQUARD Cyrille <[email protected]> Co-authored-by: Cyrille C <[email protected]> Co-authored-by: Vasilis Manthos <[email protected]>
- Loading branch information
1 parent
2c2caed
commit e84638c
Showing
41 changed files
with
4,640 additions
and
1,050 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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 | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the WP_Rocket\Dependencies\Monolog package. | ||
* | ||
* (c) Jordi Boggiano <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace WP_Rocket\Dependencies\Monolog; | ||
|
||
use WP_Rocket\Dependencies\Psr\Log\LoggerInterface; | ||
use WP_Rocket\Dependencies\Psr\Log\LogLevel; | ||
use WP_Rocket\Dependencies\Monolog\Handler\AbstractHandler; | ||
|
||
/** | ||
* WP_Rocket\Dependencies\Monolog error handler | ||
* | ||
* A facility to enable logging of runtime errors, exceptions and fatal errors. | ||
* | ||
* Quick setup: <code>ErrorHandler::register($logger);</code> | ||
* | ||
* @author Jordi Boggiano <[email protected]> | ||
*/ | ||
class ErrorHandler | ||
{ | ||
private $logger; | ||
|
||
private $previousExceptionHandler; | ||
private $uncaughtExceptionLevel; | ||
|
||
private $previousErrorHandler; | ||
private $errorLevelMap; | ||
private $handleOnlyReportedErrors; | ||
|
||
private $hasFatalErrorHandler; | ||
private $fatalLevel; | ||
private $reservedMemory; | ||
private $lastFatalTrace; | ||
private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR); | ||
|
||
public function __construct(LoggerInterface $logger) | ||
{ | ||
$this->logger = $logger; | ||
} | ||
|
||
/** | ||
* Registers a new ErrorHandler for a given Logger | ||
* | ||
* By default it will handle errors, exceptions and fatal errors | ||
* | ||
* @param LoggerInterface $logger | ||
* @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling | ||
* @param int|false $exceptionLevel a LogLevel::* constant, or false to disable exception handling | ||
* @param int|false $fatalLevel a LogLevel::* constant, or false to disable fatal error handling | ||
* @return ErrorHandler | ||
*/ | ||
public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null) | ||
{ | ||
//Forces the autoloader to run for LogLevel. Fixes an autoload issue at compile-time on PHP5.3. See https://github.com/Seldaek/monolog/pull/929 | ||
class_exists('\\Psr\\Log\\LogLevel', true); | ||
|
||
/** @phpstan-ignore-next-line */ | ||
$handler = new static($logger); | ||
if ($errorLevelMap !== false) { | ||
$handler->registerErrorHandler($errorLevelMap); | ||
} | ||
if ($exceptionLevel !== false) { | ||
$handler->registerExceptionHandler($exceptionLevel); | ||
} | ||
if ($fatalLevel !== false) { | ||
$handler->registerFatalHandler($fatalLevel); | ||
} | ||
|
||
return $handler; | ||
} | ||
|
||
public function registerExceptionHandler($level = null, $callPrevious = true) | ||
{ | ||
$prev = set_exception_handler(array($this, 'handleException')); | ||
$this->uncaughtExceptionLevel = $level; | ||
if ($callPrevious && $prev) { | ||
$this->previousExceptionHandler = $prev; | ||
} | ||
} | ||
|
||
public function registerErrorHandler(array $levelMap = array(), $callPrevious = true, $errorTypes = -1, $handleOnlyReportedErrors = true) | ||
{ | ||
$prev = set_error_handler(array($this, 'handleError'), $errorTypes); | ||
$this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap); | ||
if ($callPrevious) { | ||
$this->previousErrorHandler = $prev ?: true; | ||
} | ||
|
||
$this->handleOnlyReportedErrors = $handleOnlyReportedErrors; | ||
} | ||
|
||
public function registerFatalHandler($level = null, $reservedMemorySize = 20) | ||
{ | ||
register_shutdown_function(array($this, 'handleFatalError')); | ||
|
||
$this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize); | ||
$this->fatalLevel = $level; | ||
$this->hasFatalErrorHandler = true; | ||
} | ||
|
||
protected function defaultErrorLevelMap() | ||
{ | ||
return array( | ||
E_ERROR => LogLevel::CRITICAL, | ||
E_WARNING => LogLevel::WARNING, | ||
E_PARSE => LogLevel::ALERT, | ||
E_NOTICE => LogLevel::NOTICE, | ||
E_CORE_ERROR => LogLevel::CRITICAL, | ||
E_CORE_WARNING => LogLevel::WARNING, | ||
E_COMPILE_ERROR => LogLevel::ALERT, | ||
E_COMPILE_WARNING => LogLevel::WARNING, | ||
E_USER_ERROR => LogLevel::ERROR, | ||
E_USER_WARNING => LogLevel::WARNING, | ||
E_USER_NOTICE => LogLevel::NOTICE, | ||
E_STRICT => LogLevel::NOTICE, | ||
E_RECOVERABLE_ERROR => LogLevel::ERROR, | ||
E_DEPRECATED => LogLevel::NOTICE, | ||
E_USER_DEPRECATED => LogLevel::NOTICE, | ||
); | ||
} | ||
|
||
/** | ||
* @private | ||
*/ | ||
public function handleException($e) | ||
{ | ||
$this->logger->log( | ||
$this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel, | ||
sprintf('Uncaught Exception %s: "%s" at %s line %s', Utils::getClass($e), $e->getMessage(), $e->getFile(), $e->getLine()), | ||
array('exception' => $e) | ||
); | ||
|
||
if ($this->previousExceptionHandler) { | ||
call_user_func($this->previousExceptionHandler, $e); | ||
} | ||
|
||
exit(255); | ||
} | ||
|
||
/** | ||
* @private | ||
*/ | ||
public function handleError($code, $message, $file = '', $line = 0, $context = array()) | ||
{ | ||
if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) { | ||
return; | ||
} | ||
|
||
// fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries | ||
if (!$this->hasFatalErrorHandler || !in_array($code, self::$fatalErrors, true)) { | ||
$level = isset($this->errorLevelMap[$code]) ? $this->errorLevelMap[$code] : LogLevel::CRITICAL; | ||
$this->logger->log($level, self::codeToString($code).': '.$message, array('code' => $code, 'message' => $message, 'file' => $file, 'line' => $line)); | ||
} else { | ||
// http://php.net/manual/en/function.debug-backtrace.php | ||
// As of 5.3.6, DEBUG_BACKTRACE_IGNORE_ARGS option was added. | ||
// Any version less than 5.3.6 must use the DEBUG_BACKTRACE_IGNORE_ARGS constant value '2'. | ||
$trace = debug_backtrace((PHP_VERSION_ID < 50306) ? 2 : DEBUG_BACKTRACE_IGNORE_ARGS); | ||
array_shift($trace); // Exclude handleError from trace | ||
$this->lastFatalTrace = $trace; | ||
} | ||
|
||
if ($this->previousErrorHandler === true) { | ||
return false; | ||
} elseif ($this->previousErrorHandler) { | ||
return call_user_func($this->previousErrorHandler, $code, $message, $file, $line, $context); | ||
} | ||
} | ||
|
||
/** | ||
* @private | ||
*/ | ||
public function handleFatalError() | ||
{ | ||
$this->reservedMemory = null; | ||
|
||
$lastError = error_get_last(); | ||
if ($lastError && in_array($lastError['type'], self::$fatalErrors, true)) { | ||
$this->logger->log( | ||
$this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel, | ||
'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'], | ||
array('code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'], 'trace' => $this->lastFatalTrace) | ||
); | ||
|
||
if ($this->logger instanceof Logger) { | ||
foreach ($this->logger->getHandlers() as $handler) { | ||
if ($handler instanceof AbstractHandler) { | ||
$handler->close(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private static function codeToString($code) | ||
{ | ||
switch ($code) { | ||
case E_ERROR: | ||
return 'E_ERROR'; | ||
case E_WARNING: | ||
return 'E_WARNING'; | ||
case E_PARSE: | ||
return 'E_PARSE'; | ||
case E_NOTICE: | ||
return 'E_NOTICE'; | ||
case E_CORE_ERROR: | ||
return 'E_CORE_ERROR'; | ||
case E_CORE_WARNING: | ||
return 'E_CORE_WARNING'; | ||
case E_COMPILE_ERROR: | ||
return 'E_COMPILE_ERROR'; | ||
case E_COMPILE_WARNING: | ||
return 'E_COMPILE_WARNING'; | ||
case E_USER_ERROR: | ||
return 'E_USER_ERROR'; | ||
case E_USER_WARNING: | ||
return 'E_USER_WARNING'; | ||
case E_USER_NOTICE: | ||
return 'E_USER_NOTICE'; | ||
case E_STRICT: | ||
return 'E_STRICT'; | ||
case E_RECOVERABLE_ERROR: | ||
return 'E_RECOVERABLE_ERROR'; | ||
case E_DEPRECATED: | ||
return 'E_DEPRECATED'; | ||
case E_USER_DEPRECATED: | ||
return 'E_USER_DEPRECATED'; | ||
} | ||
|
||
return 'Unknown PHP error'; | ||
} | ||
} |
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 | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the WP_Rocket\Dependencies\Monolog package. | ||
* | ||
* (c) Jordi Boggiano <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace WP_Rocket\Dependencies\Monolog\Formatter; | ||
|
||
/** | ||
* Interface for formatters | ||
* | ||
* @author Jordi Boggiano <[email protected]> | ||
*/ | ||
interface FormatterInterface | ||
{ | ||
/** | ||
* Formats a log record. | ||
* | ||
* @param array $record A record to format | ||
* @return mixed The formatted record | ||
*/ | ||
public function format(array $record); | ||
|
||
/** | ||
* Formats a set of log records. | ||
* | ||
* @param array $records A set of records to format | ||
* @return mixed The formatted set of records | ||
*/ | ||
public function formatBatch(array $records); | ||
} |
Oops, something went wrong.