mirror of
https://github.com/Seldaek/monolog.git
synced 2025-07-28 17:00:17 +02:00
Add Record/Level/LevelName type aliases and improve phpstan type coverage to level 6
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
parameters:
|
||||
level: 5
|
||||
level: 6
|
||||
|
||||
treatPhpDocTypesAsCertain: false
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
@@ -18,3 +18,8 @@ parameters:
|
||||
- message: '#Method Monolog\\Handler\\LogglyHandler::loadCurlHandle\(\) never returns resource so it can be removed from the return typehint.#'
|
||||
paths:
|
||||
- src/Monolog/Handler/LogglyHandler.php
|
||||
|
||||
# blocked by https://github.com/phpstan/phpstan/issues/5091
|
||||
- '#has unknown class Monolog\\Handler\\Record#'
|
||||
- '#::processRecord#'
|
||||
- '#is incompatible with native type array.#'
|
||||
|
@@ -25,19 +25,30 @@ use Psr\Log\LogLevel;
|
||||
*/
|
||||
class ErrorHandler
|
||||
{
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
private $previousExceptionHandler;
|
||||
private $uncaughtExceptionLevelMap;
|
||||
/** @var ?callable */
|
||||
private $previousExceptionHandler = null;
|
||||
/** @var array<class-string, LogLevel::*> an array of class name to LogLevel::* constant mapping */
|
||||
private $uncaughtExceptionLevelMap = [];
|
||||
|
||||
private $previousErrorHandler;
|
||||
private $errorLevelMap;
|
||||
private $handleOnlyReportedErrors;
|
||||
/** @var callable|true|null */
|
||||
private $previousErrorHandler = null;
|
||||
/** @var array<int, LogLevel::*> an array of E_* constant to LogLevel::* constant mapping */
|
||||
private $errorLevelMap = [];
|
||||
/** @var bool */
|
||||
private $handleOnlyReportedErrors = true;
|
||||
|
||||
private $hasFatalErrorHandler;
|
||||
private $fatalLevel;
|
||||
private $reservedMemory;
|
||||
/** @var bool */
|
||||
private $hasFatalErrorHandler = false;
|
||||
/** @var LogLevel::* */
|
||||
private $fatalLevel = LogLevel::ALERT;
|
||||
/** @var ?string */
|
||||
private $reservedMemory = null;
|
||||
/** @var ?mixed */
|
||||
private $lastFatalTrace;
|
||||
/** @var int[] */
|
||||
private static $fatalErrors = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR];
|
||||
|
||||
public function __construct(LoggerInterface $logger)
|
||||
@@ -50,10 +61,10 @@ class ErrorHandler
|
||||
*
|
||||
* 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 array|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling
|
||||
* @param string|null|false $fatalLevel a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling
|
||||
* @param LoggerInterface $logger
|
||||
* @param array<int, LogLevel::*>|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
|
||||
* @param array<class-string, LogLevel::*>|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling
|
||||
* @param LogLevel::*|null|false $fatalLevel a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling
|
||||
* @return ErrorHandler
|
||||
*/
|
||||
public static function register(LoggerInterface $logger, $errorLevelMap = [], $exceptionLevelMap = [], $fatalLevel = null): self
|
||||
@@ -73,7 +84,11 @@ class ErrorHandler
|
||||
return $handler;
|
||||
}
|
||||
|
||||
public function registerExceptionHandler($levelMap = [], $callPrevious = true): self
|
||||
/**
|
||||
* @param array<class-string, LogLevel::*> $levelMap an array of class name to LogLevel::* constant mapping
|
||||
* @return $this
|
||||
*/
|
||||
public function registerExceptionHandler(array $levelMap = [], bool $callPrevious = true): self
|
||||
{
|
||||
$prev = set_exception_handler(function (\Throwable $e): void {
|
||||
$this->handleException($e);
|
||||
@@ -91,12 +106,18 @@ class ErrorHandler
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function registerErrorHandler(array $levelMap = [], $callPrevious = true, $errorTypes = -1, $handleOnlyReportedErrors = true): self
|
||||
/**
|
||||
* @param array<int, LogLevel::*> $levelMap an array of E_* constant to LogLevel::* constant mapping
|
||||
* @return $this
|
||||
*/
|
||||
public function registerErrorHandler(array $levelMap = [], bool $callPrevious = true, int $errorTypes = -1, bool $handleOnlyReportedErrors = true): self
|
||||
{
|
||||
$prev = set_error_handler([$this, 'handleError'], $errorTypes);
|
||||
$this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap);
|
||||
if ($callPrevious) {
|
||||
$this->previousErrorHandler = $prev ?: true;
|
||||
} else {
|
||||
$this->previousErrorHandler = null;
|
||||
}
|
||||
|
||||
$this->handleOnlyReportedErrors = $handleOnlyReportedErrors;
|
||||
@@ -105,20 +126,23 @@ class ErrorHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $level a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling
|
||||
* @param int $reservedMemorySize Amount of KBs to reserve in memory so that it can be freed when handling fatal errors giving Monolog some room in memory to get its job done
|
||||
* @param LogLevel::*|null $level a LogLevel::* constant, null to use the default LogLevel::ALERT
|
||||
* @param int $reservedMemorySize Amount of KBs to reserve in memory so that it can be freed when handling fatal errors giving Monolog some room in memory to get its job done
|
||||
*/
|
||||
public function registerFatalHandler($level = null, int $reservedMemorySize = 20): self
|
||||
{
|
||||
register_shutdown_function([$this, 'handleFatalError']);
|
||||
|
||||
$this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize);
|
||||
$this->fatalLevel = $level;
|
||||
$this->fatalLevel = null === $level ? LogLevel::ALERT : $level;
|
||||
$this->hasFatalErrorHandler = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string, LogLevel::*>
|
||||
*/
|
||||
protected function defaultExceptionLevelMap(): array
|
||||
{
|
||||
return [
|
||||
@@ -127,6 +151,9 @@ class ErrorHandler
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, LogLevel::*>
|
||||
*/
|
||||
protected function defaultErrorLevelMap(): array
|
||||
{
|
||||
return [
|
||||
@@ -148,7 +175,10 @@ class ErrorHandler
|
||||
];
|
||||
}
|
||||
|
||||
private function handleException(\Throwable $e)
|
||||
/**
|
||||
* @phpstan-return never
|
||||
*/
|
||||
private function handleException(\Throwable $e): void
|
||||
{
|
||||
$level = LogLevel::ERROR;
|
||||
foreach ($this->uncaughtExceptionLevelMap as $class => $candidate) {
|
||||
@@ -177,11 +207,13 @@ class ErrorHandler
|
||||
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function handleError($code, $message, $file = '', $line = 0, $context = [])
|
||||
public function handleError(int $code, string $message, string $file = '', int $line = 0, array $context = []): bool
|
||||
{
|
||||
if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries
|
||||
@@ -197,7 +229,7 @@ class ErrorHandler
|
||||
if ($this->previousErrorHandler === true) {
|
||||
return false;
|
||||
} elseif ($this->previousErrorHandler) {
|
||||
return ($this->previousErrorHandler)($code, $message, $file, $line, $context);
|
||||
return (bool) ($this->previousErrorHandler)($code, $message, $file, $line, $context);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -206,14 +238,14 @@ class ErrorHandler
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
public function handleFatalError()
|
||||
public function handleFatalError(): void
|
||||
{
|
||||
$this->reservedMemory = '';
|
||||
|
||||
$lastError = error_get_last();
|
||||
if ($lastError && in_array($lastError['type'], self::$fatalErrors, true)) {
|
||||
$this->logger->log(
|
||||
$this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel,
|
||||
$this->fatalLevel,
|
||||
'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'],
|
||||
['code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'], 'trace' => $this->lastFatalTrace]
|
||||
);
|
||||
@@ -226,6 +258,9 @@ class ErrorHandler
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $code
|
||||
*/
|
||||
private static function codeToString($code): string
|
||||
{
|
||||
switch ($code) {
|
||||
|
@@ -22,6 +22,8 @@ class ChromePHPFormatter implements FormatterInterface
|
||||
{
|
||||
/**
|
||||
* Translates Monolog log levels to Wildfire levels.
|
||||
*
|
||||
* @var array<int, 'log'|'info'|'warn'|'error'>
|
||||
*/
|
||||
private $logLevels = [
|
||||
Logger::DEBUG => 'log',
|
||||
|
@@ -17,6 +17,8 @@ use Elastica\Document;
|
||||
* Format a log message into an Elastica Document
|
||||
*
|
||||
* @author Jelle Vink <jelle.vink@gmail.com>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class ElasticaFormatter extends NormalizerFormatter
|
||||
{
|
||||
@@ -68,8 +70,8 @@ class ElasticaFormatter extends NormalizerFormatter
|
||||
|
||||
/**
|
||||
* Convert a log message into an Elastica Document
|
||||
* @param array $record
|
||||
* @return Document
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
protected function getDocument(array $record): Document
|
||||
{
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Monolog\Formatter;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
* Format a log message into an Elasticsearch record
|
||||
@@ -37,7 +37,7 @@ class ElasticsearchFormatter extends NormalizerFormatter
|
||||
public function __construct(string $index, string $type)
|
||||
{
|
||||
// Elasticsearch requires an ISO 8601 format date with optional millisecond precision.
|
||||
parent::__construct(DateTime::ISO8601);
|
||||
parent::__construct(DateTimeInterface::ISO8601);
|
||||
|
||||
$this->index = $index;
|
||||
$this->type = $type;
|
||||
@@ -76,8 +76,8 @@ class ElasticsearchFormatter extends NormalizerFormatter
|
||||
/**
|
||||
* Convert a log message into an Elasticsearch record
|
||||
*
|
||||
* @param array $record Log message
|
||||
* @return array
|
||||
* @param mixed[] $record Log message
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getDocument(array $record): array
|
||||
{
|
||||
|
@@ -36,6 +36,8 @@ class FlowdockFormatter implements FormatterInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function format(array $record): array
|
||||
{
|
||||
@@ -70,6 +72,8 @@ class FlowdockFormatter implements FormatterInterface
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return mixed[][]
|
||||
*/
|
||||
public function formatBatch(array $records): array
|
||||
{
|
||||
|
@@ -15,6 +15,8 @@ namespace Monolog\Formatter;
|
||||
* Interface for formatters
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
interface FormatterInterface
|
||||
{
|
||||
@@ -23,6 +25,8 @@ interface FormatterInterface
|
||||
*
|
||||
* @param array $record A record to format
|
||||
* @return mixed The formatted record
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function format(array $record);
|
||||
|
||||
@@ -31,6 +35,8 @@ interface FormatterInterface
|
||||
*
|
||||
* @param array $records A set of records to format
|
||||
* @return mixed The formatted set of records
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
public function formatBatch(array $records);
|
||||
}
|
||||
|
@@ -47,6 +47,8 @@ class GelfMessageFormatter extends NormalizerFormatter
|
||||
|
||||
/**
|
||||
* Translates Monolog log levels to Graylog2 log priorities.
|
||||
*
|
||||
* @var array<int, int>
|
||||
*/
|
||||
private $logLevels = [
|
||||
Logger::DEBUG => 7,
|
||||
|
@@ -25,6 +25,8 @@ class HtmlFormatter extends NormalizerFormatter
|
||||
{
|
||||
/**
|
||||
* Translates Monolog log levels to html color priorities.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $logLevels = [
|
||||
Logger::DEBUG => '#CCCCCC',
|
||||
@@ -79,7 +81,6 @@ class HtmlFormatter extends NormalizerFormatter
|
||||
/**
|
||||
* Formats a log record.
|
||||
*
|
||||
* @param array $record A record to format
|
||||
* @return string The formatted record
|
||||
*/
|
||||
public function format(array $record): string
|
||||
@@ -113,7 +114,6 @@ class HtmlFormatter extends NormalizerFormatter
|
||||
/**
|
||||
* Formats a set of log records.
|
||||
*
|
||||
* @param array $records A set of records to format
|
||||
* @return string The formatted set of records
|
||||
*/
|
||||
public function formatBatch(array $records): string
|
||||
@@ -126,6 +126,9 @@ class HtmlFormatter extends NormalizerFormatter
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
protected function convertToString($data): string
|
||||
{
|
||||
if (null === $data || is_scalar($data)) {
|
||||
|
@@ -19,21 +19,26 @@ use Throwable;
|
||||
* This can be useful to log to databases or remote APIs
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class JsonFormatter extends NormalizerFormatter
|
||||
{
|
||||
public const BATCH_MODE_JSON = 1;
|
||||
public const BATCH_MODE_NEWLINES = 2;
|
||||
|
||||
/** @var self::BATCH_MODE_* */
|
||||
protected $batchMode;
|
||||
/** @var bool */
|
||||
protected $appendNewline;
|
||||
/** @var bool */
|
||||
protected $ignoreEmptyContextAndExtra;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
/** @var bool */
|
||||
protected $includeStacktraces = false;
|
||||
|
||||
/**
|
||||
* @param self::BATCH_MODE_* $batchMode
|
||||
*/
|
||||
public function __construct(int $batchMode = self::BATCH_MODE_JSON, bool $appendNewline = true, bool $ignoreEmptyContextAndExtra = false)
|
||||
{
|
||||
$this->batchMode = $batchMode;
|
||||
@@ -101,6 +106,9 @@ class JsonFormatter extends NormalizerFormatter
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function includeStacktraces(bool $include = true)
|
||||
{
|
||||
$this->includeStacktraces = $include;
|
||||
@@ -108,6 +116,8 @@ class JsonFormatter extends NormalizerFormatter
|
||||
|
||||
/**
|
||||
* Return a JSON-encoded array of records.
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
protected function formatBatchJson(array $records): string
|
||||
{
|
||||
@@ -117,6 +127,8 @@ class JsonFormatter extends NormalizerFormatter
|
||||
/**
|
||||
* Use new lines to separate records instead of a
|
||||
* JSON-encoded array.
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
protected function formatBatchNewlines(array $records): string
|
||||
{
|
||||
@@ -175,6 +187,8 @@ class JsonFormatter extends NormalizerFormatter
|
||||
/**
|
||||
* Normalizes given exception with or without its own stack trace based on
|
||||
* `includeStacktraces` property.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function normalizeException(Throwable $e, int $depth = 0): array
|
||||
{
|
||||
|
@@ -25,9 +25,13 @@ class LineFormatter extends NormalizerFormatter
|
||||
{
|
||||
public const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
|
||||
|
||||
/** @var string */
|
||||
protected $format;
|
||||
/** @var bool */
|
||||
protected $allowInlineLineBreaks;
|
||||
/** @var bool */
|
||||
protected $ignoreEmptyContextAndExtra;
|
||||
/** @var bool */
|
||||
protected $includeStacktraces;
|
||||
|
||||
/**
|
||||
@@ -44,7 +48,7 @@ class LineFormatter extends NormalizerFormatter
|
||||
parent::__construct($dateFormat);
|
||||
}
|
||||
|
||||
public function includeStacktraces(bool $include = true)
|
||||
public function includeStacktraces(bool $include = true): void
|
||||
{
|
||||
$this->includeStacktraces = $include;
|
||||
if ($this->includeStacktraces) {
|
||||
@@ -52,12 +56,12 @@ class LineFormatter extends NormalizerFormatter
|
||||
}
|
||||
}
|
||||
|
||||
public function allowInlineLineBreaks(bool $allow = true)
|
||||
public function allowInlineLineBreaks(bool $allow = true): void
|
||||
{
|
||||
$this->allowInlineLineBreaks = $allow;
|
||||
}
|
||||
|
||||
public function ignoreEmptyContextAndExtra(bool $ignore = true)
|
||||
public function ignoreEmptyContextAndExtra(bool $ignore = true): void
|
||||
{
|
||||
$this->ignoreEmptyContextAndExtra = $ignore;
|
||||
}
|
||||
@@ -121,6 +125,9 @@ class LineFormatter extends NormalizerFormatter
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function stringify($value): string
|
||||
{
|
||||
return $this->replaceNewlines($this->convertToString($value));
|
||||
@@ -139,6 +146,9 @@ class LineFormatter extends NormalizerFormatter
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
protected function convertToString($data): string
|
||||
{
|
||||
if (null === $data || is_bool($data)) {
|
||||
|
@@ -21,8 +21,11 @@ use Monolog\Utils;
|
||||
*/
|
||||
class MongoDBFormatter implements FormatterInterface
|
||||
{
|
||||
/** @var bool */
|
||||
private $exceptionTraceAsString;
|
||||
/** @var int */
|
||||
private $maxNestingLevel;
|
||||
/** @var bool */
|
||||
private $isLegacyMongoExt;
|
||||
|
||||
/**
|
||||
@@ -39,6 +42,8 @@ class MongoDBFormatter implements FormatterInterface
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return scalar[]
|
||||
*/
|
||||
public function format(array $record): array
|
||||
{
|
||||
@@ -47,40 +52,48 @@ class MongoDBFormatter implements FormatterInterface
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return array<scalar[]>
|
||||
*/
|
||||
public function formatBatch(array $records): array
|
||||
{
|
||||
$formatted = [];
|
||||
foreach ($records as $key => $record) {
|
||||
$records[$key] = $this->format($record);
|
||||
$formatted[$key] = $this->format($record);
|
||||
}
|
||||
|
||||
return $records;
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string Array except when max nesting level is reached then a string "[...]"
|
||||
* @param mixed[] $array
|
||||
* @return mixed[]|string Array except when max nesting level is reached then a string "[...]"
|
||||
*/
|
||||
protected function formatArray(array $record, int $nestingLevel = 0)
|
||||
protected function formatArray(array $array, int $nestingLevel = 0)
|
||||
{
|
||||
if ($this->maxNestingLevel == 0 || $nestingLevel <= $this->maxNestingLevel) {
|
||||
foreach ($record as $name => $value) {
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
$record[$name] = $this->formatDate($value, $nestingLevel + 1);
|
||||
} elseif ($value instanceof \Throwable) {
|
||||
$record[$name] = $this->formatException($value, $nestingLevel + 1);
|
||||
} elseif (is_array($value)) {
|
||||
$record[$name] = $this->formatArray($value, $nestingLevel + 1);
|
||||
} elseif (is_object($value)) {
|
||||
$record[$name] = $this->formatObject($value, $nestingLevel + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$record = '[...]';
|
||||
if ($this->maxNestingLevel > 0 && $nestingLevel > $this->maxNestingLevel) {
|
||||
return '[...]';
|
||||
}
|
||||
|
||||
return $record;
|
||||
foreach ($array as $name => $value) {
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
$array[$name] = $this->formatDate($value, $nestingLevel + 1);
|
||||
} elseif ($value instanceof \Throwable) {
|
||||
$array[$name] = $this->formatException($value, $nestingLevel + 1);
|
||||
} elseif (is_array($value)) {
|
||||
$array[$name] = $this->formatArray($value, $nestingLevel + 1);
|
||||
} elseif (is_object($value)) {
|
||||
$array[$name] = $this->formatObject($value, $nestingLevel + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return mixed[]|string
|
||||
*/
|
||||
protected function formatObject($value, int $nestingLevel)
|
||||
{
|
||||
$objectVars = get_object_vars($value);
|
||||
@@ -89,6 +102,9 @@ class MongoDBFormatter implements FormatterInterface
|
||||
return $this->formatArray($objectVars, $nestingLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]|string
|
||||
*/
|
||||
protected function formatException(\Throwable $exception, int $nestingLevel)
|
||||
{
|
||||
$formattedException = [
|
||||
|
@@ -123,7 +123,7 @@ class NormalizerFormatter implements FormatterInterface
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @return int|bool|string|null|array
|
||||
* @return scalar|array<scalar>
|
||||
*/
|
||||
protected function normalize($data, int $depth = 0)
|
||||
{
|
||||
@@ -189,7 +189,7 @@ class NormalizerFormatter implements FormatterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function normalizeException(Throwable $e, int $depth = 0)
|
||||
{
|
||||
@@ -248,6 +248,9 @@ class NormalizerFormatter implements FormatterInterface
|
||||
return Utils::jsonEncode($data, $this->jsonEncodeOptions, $ignoreErrors);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function formatDate(\DateTimeInterface $date)
|
||||
{
|
||||
// in case the date format isn't custom then we defer to the custom DateTimeImmutable
|
||||
@@ -259,12 +262,12 @@ class NormalizerFormatter implements FormatterInterface
|
||||
return $date->format($this->dateFormat);
|
||||
}
|
||||
|
||||
public function addJsonEncodeOption(int $option)
|
||||
public function addJsonEncodeOption(int $option): void
|
||||
{
|
||||
$this->jsonEncodeOptions |= $option;
|
||||
}
|
||||
|
||||
public function removeJsonEncodeOption(int $option)
|
||||
public function removeJsonEncodeOption(int $option): void
|
||||
{
|
||||
$this->jsonEncodeOptions &= ~$option;
|
||||
}
|
||||
|
@@ -21,6 +21,8 @@ class ScalarFormatter extends NormalizerFormatter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @phpstan-return scalar[] $record
|
||||
*/
|
||||
public function format(array $record): array
|
||||
{
|
||||
|
@@ -19,11 +19,15 @@ use Monolog\Logger;
|
||||
* @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
* @author Kirill chEbba Chebunin <iam@chebba.org>
|
||||
*
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
class WildfireFormatter extends NormalizerFormatter
|
||||
{
|
||||
/**
|
||||
* Translates Monolog log levels to Wildfire levels.
|
||||
*
|
||||
* @var array<Level, string>
|
||||
*/
|
||||
private $logLevels = [
|
||||
Logger::DEBUG => 'LOG',
|
||||
@@ -49,6 +53,8 @@ class WildfireFormatter extends NormalizerFormatter
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(array $record): string
|
||||
{
|
||||
@@ -108,6 +114,8 @@ class WildfireFormatter extends NormalizerFormatter
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @phpstan-return never
|
||||
*/
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
@@ -116,7 +124,8 @@ class WildfireFormatter extends NormalizerFormatter
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return int|bool|string|null|array|object
|
||||
*
|
||||
* @return scalar|array<scalar>|object
|
||||
*/
|
||||
protected function normalize($data, int $depth = 0)
|
||||
{
|
||||
|
@@ -18,10 +18,17 @@ use Monolog\ResettableInterface;
|
||||
* Base Handler class providing basic level/bubble support
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
abstract class AbstractHandler extends Handler implements ResettableInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @phpstan-var Level
|
||||
*/
|
||||
protected $level = Logger::DEBUG;
|
||||
/** @var bool */
|
||||
protected $bubble = true;
|
||||
|
||||
/**
|
||||
@@ -59,6 +66,8 @@ abstract class AbstractHandler extends Handler implements ResettableInterface
|
||||
* Gets minimum logging level at which this handler will be triggered.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @phpstan-return Level
|
||||
*/
|
||||
public function getLevel(): int
|
||||
{
|
||||
@@ -90,6 +99,9 @@ abstract class AbstractHandler extends Handler implements ResettableInterface
|
||||
return $this->bubble;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
}
|
||||
|
@@ -18,6 +18,10 @@ namespace Monolog\Handler;
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-type FormattedRecord array{message: string, context: mixed[], level: Level, level_name: LevelName, channel: string, datetime: \DateTimeImmutable, extra: mixed[], formatted: mixed}
|
||||
*/
|
||||
abstract class AbstractProcessingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
|
||||
{
|
||||
@@ -46,9 +50,14 @@ abstract class AbstractProcessingHandler extends AbstractHandler implements Proc
|
||||
|
||||
/**
|
||||
* Writes the record down to the log of the implementing handler
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
abstract protected function write(array $record): void;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
parent::reset();
|
||||
|
@@ -17,13 +17,18 @@ use Monolog\Formatter\LineFormatter;
|
||||
|
||||
/**
|
||||
* Common syslog functionality
|
||||
*
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
abstract class AbstractSyslogHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var int */
|
||||
protected $facility;
|
||||
|
||||
/**
|
||||
* Translates Monolog log levels to syslog log priorities.
|
||||
* @var array
|
||||
* @phpstan-var array<Level, int>
|
||||
*/
|
||||
protected $logLevels = [
|
||||
Logger::DEBUG => LOG_DEBUG,
|
||||
@@ -38,6 +43,7 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler
|
||||
|
||||
/**
|
||||
* List of valid log facility names.
|
||||
* @var array<string, int>
|
||||
*/
|
||||
protected $facilities = [
|
||||
'auth' => LOG_AUTH,
|
||||
|
@@ -18,6 +18,9 @@ use PhpAmqpLib\Message\AMQPMessage;
|
||||
use PhpAmqpLib\Channel\AMQPChannel;
|
||||
use AMQPExchange;
|
||||
|
||||
/**
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class AmqpHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/**
|
||||
@@ -108,6 +111,8 @@ class AmqpHandler extends AbstractProcessingHandler
|
||||
|
||||
/**
|
||||
* Gets the routing key for the AMQP exchange
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
protected function getRoutingKey(array $record): string
|
||||
{
|
||||
|
@@ -19,10 +19,14 @@ use Monolog\Utils;
|
||||
* Handler sending logs to browser's javascript console with no browser extension required
|
||||
*
|
||||
* @author Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class BrowserConsoleHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var bool */
|
||||
protected static $initialized = false;
|
||||
/** @var FormattedRecord[] */
|
||||
protected static $records = [];
|
||||
|
||||
/**
|
||||
@@ -165,6 +169,9 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
|
||||
return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private static function handleStyles(string $formatted): array
|
||||
{
|
||||
$args = [];
|
||||
@@ -205,6 +212,10 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
|
||||
}, $style);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $dict
|
||||
* @return mixed[]
|
||||
*/
|
||||
private static function dump(string $title, array $dict): array
|
||||
{
|
||||
$script = [];
|
||||
@@ -229,13 +240,22 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
|
||||
return '"' . addcslashes($arg, "\"\n\\") . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $args
|
||||
*/
|
||||
private static function call(...$args): string
|
||||
{
|
||||
$method = array_shift($args);
|
||||
if (!is_string($method)) {
|
||||
throw new \UnexpectedValueException('Expected the first arg to be a string, got: '.var_export($method, true));
|
||||
}
|
||||
|
||||
return static::call_array($method, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $args
|
||||
*/
|
||||
private static function call_array(string $method, array $args): string
|
||||
{
|
||||
return 'c.' . $method . '(' . implode(', ', $args) . ');';
|
||||
|
@@ -22,6 +22,8 @@ use Monolog\Formatter\FormatterInterface;
|
||||
* sending one per log message.
|
||||
*
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class BufferHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
|
||||
{
|
||||
@@ -29,10 +31,15 @@ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterfa
|
||||
|
||||
/** @var HandlerInterface */
|
||||
protected $handler;
|
||||
/** @var int */
|
||||
protected $bufferSize = 0;
|
||||
/** @var int */
|
||||
protected $bufferLimit;
|
||||
/** @var bool */
|
||||
protected $flushOnOverflow;
|
||||
/** @var Record[] */
|
||||
protected $buffer = [];
|
||||
/** @var bool */
|
||||
protected $initialized = false;
|
||||
|
||||
/**
|
||||
|
@@ -42,6 +42,7 @@ class ChromePHPHandler extends AbstractProcessingHandler
|
||||
*/
|
||||
protected const USER_AGENT_REGEX = '{\b(?:Chrome/\d+(?:\.\d+)*|HeadlessChrome|Firefox/(?:4[3-9]|[5-9]\d|\d{3,})(?:\.\d)*)\b}';
|
||||
|
||||
/** @var bool */
|
||||
protected static $initialized = false;
|
||||
|
||||
/**
|
||||
@@ -53,12 +54,14 @@ class ChromePHPHandler extends AbstractProcessingHandler
|
||||
*/
|
||||
protected static $overflowed = false;
|
||||
|
||||
/** @var mixed[] */
|
||||
protected static $json = [
|
||||
'version' => self::VERSION,
|
||||
'columns' => ['label', 'log', 'backtrace', 'type'],
|
||||
'rows' => [],
|
||||
];
|
||||
|
||||
/** @var bool */
|
||||
protected static $sendHeaders = true;
|
||||
|
||||
/**
|
||||
|
@@ -22,8 +22,12 @@ use Monolog\Logger;
|
||||
*/
|
||||
class CouchDBHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var mixed[] */
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @param mixed[] $options
|
||||
*/
|
||||
public function __construct(array $options = [], $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
$this->options = array_merge([
|
||||
|
@@ -22,11 +22,17 @@ use Monolog\Utils;
|
||||
*/
|
||||
class CubeHandler extends AbstractProcessingHandler
|
||||
{
|
||||
private $udpConnection;
|
||||
private $httpConnection;
|
||||
/** @var resource|\Socket|null */
|
||||
private $udpConnection = null;
|
||||
/** @var resource|\CurlHandle|null */
|
||||
private $httpConnection = null;
|
||||
/** @var string */
|
||||
private $scheme;
|
||||
/** @var string */
|
||||
private $host;
|
||||
/** @var int */
|
||||
private $port;
|
||||
/** @var string[] */
|
||||
private $acceptedSchemes = ['http', 'udp'];
|
||||
|
||||
/**
|
||||
@@ -53,7 +59,7 @@ class CubeHandler extends AbstractProcessingHandler
|
||||
|
||||
$this->scheme = $urlInfo['scheme'];
|
||||
$this->host = $urlInfo['host'];
|
||||
$this->port = $urlInfo['port'];
|
||||
$this->port = (int) $urlInfo['port'];
|
||||
|
||||
parent::__construct($level, $bubble);
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ use CurlHandle;
|
||||
*/
|
||||
final class Util
|
||||
{
|
||||
/** @var array<int> */
|
||||
private static $retriableErrorCodes = [
|
||||
CURLE_COULDNT_RESOLVE_HOST,
|
||||
CURLE_COULDNT_CONNECT,
|
||||
|
@@ -32,6 +32,8 @@ use Monolog\Logger;
|
||||
* same way.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class DeduplicationHandler extends BufferHandler
|
||||
{
|
||||
@@ -100,6 +102,9 @@ class DeduplicationHandler extends BufferHandler
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function isDuplicate(array $record): bool
|
||||
{
|
||||
if (!file_exists($this->deduplicationStore)) {
|
||||
@@ -166,6 +171,9 @@ class DeduplicationHandler extends BufferHandler
|
||||
$this->gc = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function appendRecord(array $record): void
|
||||
{
|
||||
file_put_contents($this->deduplicationStore, $record['datetime']->getTimestamp() . ':' . $record['level_name'] . ':' . preg_replace('{[\r\n].*}', '', $record['message']) . "\n", FILE_APPEND);
|
||||
|
@@ -23,6 +23,7 @@ use Doctrine\CouchDB\CouchDBClient;
|
||||
*/
|
||||
class DoctrineCouchDBHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var CouchDBClient */
|
||||
private $client;
|
||||
|
||||
public function __construct(CouchDBClient $client, $level = Logger::DEBUG, bool $bubble = true)
|
||||
|
@@ -86,6 +86,10 @@ class DynamoDbHandler extends AbstractProcessingHandler
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $record
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function filterEmptyFields(array $record): array
|
||||
{
|
||||
return array_filter($record, function ($value) {
|
||||
|
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Monolog\Handler;
|
||||
|
||||
use Elastica\Document;
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Formatter\ElasticaFormatter;
|
||||
use Monolog\Logger;
|
||||
@@ -41,13 +42,13 @@ class ElasticaHandler extends AbstractProcessingHandler
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* @var array Handler config options
|
||||
* @var mixed[] Handler config options
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @param Client $client Elastica Client object
|
||||
* @param array $options Handler configuration
|
||||
* @param mixed[] $options Handler configuration
|
||||
* @param int|string $level The minimum logging level at which this handler will be triggered
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*/
|
||||
@@ -85,6 +86,9 @@ class ElasticaHandler extends AbstractProcessingHandler
|
||||
throw new \InvalidArgumentException('ElasticaHandler is only compatible with ElasticaFormatter');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
@@ -109,6 +113,9 @@ class ElasticaHandler extends AbstractProcessingHandler
|
||||
|
||||
/**
|
||||
* Use Elasticsearch bulk API to send list of documents
|
||||
*
|
||||
* @param Document[] $documents
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function bulkSend(array $documents): void
|
||||
|
@@ -49,13 +49,13 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* @var array Handler config options
|
||||
* @var mixed[] Handler config options
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @param Client $client Elasticsearch Client object
|
||||
* @param array $options Handler configuration
|
||||
* @param mixed[] $options Handler configuration
|
||||
* @param string|int $level The minimum logging level at which this handler will be triggered
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*/
|
||||
@@ -96,7 +96,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Getter options
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
@@ -123,7 +123,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Use Elasticsearch bulk API to send list of documents
|
||||
*
|
||||
* @param array $records
|
||||
* @param array[] $records Records + _index/_type keys
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function bulkSend(array $records): void
|
||||
@@ -162,7 +162,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
||||
*
|
||||
* Only the first error is converted into an exception.
|
||||
*
|
||||
* @param array $responses returned by $this->client->bulk()
|
||||
* @param mixed[] $responses returned by $this->client->bulk()
|
||||
*/
|
||||
protected function createExceptionFromResponses(array $responses): ElasticsearchRuntimeException
|
||||
{
|
||||
@@ -178,7 +178,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Creates elasticsearch exception from error array
|
||||
*
|
||||
* @param array $error
|
||||
* @param mixed[] $error
|
||||
*/
|
||||
protected function createExceptionFromError(array $error): ElasticsearchRuntimeException
|
||||
{
|
||||
|
@@ -25,7 +25,9 @@ class ErrorLogHandler extends AbstractProcessingHandler
|
||||
public const OPERATING_SYSTEM = 0;
|
||||
public const SAPI = 4;
|
||||
|
||||
/** @var int */
|
||||
protected $messageType;
|
||||
/** @var bool */
|
||||
protected $expandNewlines;
|
||||
|
||||
/**
|
||||
@@ -49,7 +51,7 @@ class ErrorLogHandler extends AbstractProcessingHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array With all available types
|
||||
* @return int[] With all available types
|
||||
*/
|
||||
public static function getAvailableTypes(): array
|
||||
{
|
||||
|
@@ -14,6 +14,7 @@ namespace Monolog\Handler;
|
||||
use Monolog\Logger;
|
||||
use Monolog\ResettableInterface;
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Simple handler wrapper that filters records based on a list of levels
|
||||
@@ -22,6 +23,10 @@ use Monolog\Formatter\FormatterInterface;
|
||||
*
|
||||
* @author Hennadiy Verkh
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
*/
|
||||
class FilterHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface
|
||||
{
|
||||
@@ -30,7 +35,8 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
||||
/**
|
||||
* Handler or factory callable($record, $this)
|
||||
*
|
||||
* @var callable|\Monolog\Handler\HandlerInterface
|
||||
* @var callable|HandlerInterface
|
||||
* @phpstan-var callable(?Record, HandlerInterface): HandlerInterface|HandlerInterface
|
||||
*/
|
||||
protected $handler;
|
||||
|
||||
@@ -38,6 +44,7 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
||||
* Minimum level for logs that are passed to handler
|
||||
*
|
||||
* @var int[]
|
||||
* @phpstan-var Level[]
|
||||
*/
|
||||
protected $acceptedLevels;
|
||||
|
||||
@@ -49,12 +56,14 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
||||
protected $bubble;
|
||||
|
||||
/**
|
||||
* @psalm-param HandlerInterface|callable(?array, HandlerInterface): HandlerInterface $handler
|
||||
* @psalm-param HandlerInterface|callable(?Record, HandlerInterface): HandlerInterface $handler
|
||||
*
|
||||
* @param callable|HandlerInterface $handler Handler or factory callable($record|null, $filterHandler).
|
||||
* @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided
|
||||
* @param int|string $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::*|array<Level|LevelName|LogLevel::*> $minLevelOrList
|
||||
*/
|
||||
public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, bool $bubble = true)
|
||||
{
|
||||
@@ -67,6 +76,9 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return Level[]
|
||||
*/
|
||||
public function getAcceptedLevels(): array
|
||||
{
|
||||
return array_flip($this->acceptedLevels);
|
||||
@@ -75,6 +87,8 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
||||
/**
|
||||
* @param int|string|array $minLevelOrList A list of levels to accept or a minimum level or level name if maxLevel is provided
|
||||
* @param int|string $maxLevel Maximum level or level name to accept, only used if $minLevelOrList is not an array
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::*|array<Level|LevelName|LogLevel::*> $minLevelOrList
|
||||
*/
|
||||
public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY): self
|
||||
{
|
||||
@@ -141,6 +155,8 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
||||
* If the handler was provided as a factory callable, this will trigger the handler's instantiation.
|
||||
*
|
||||
* @return HandlerInterface
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function getHandler(array $record = null)
|
||||
{
|
||||
|
@@ -15,11 +15,15 @@ namespace Monolog\Handler\FingersCrossed;
|
||||
* Interface for activation strategies for the FingersCrossedHandler.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
interface ActivationStrategyInterface
|
||||
{
|
||||
/**
|
||||
* Returns whether the given record activates the handler.
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function isHandlerActivated(array $record): bool;
|
||||
}
|
||||
|
@@ -32,6 +32,9 @@ use Monolog\Logger;
|
||||
* </code>
|
||||
*
|
||||
* @author Mike Meessen <netmikey@gmail.com>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
class ChannelLevelActivationStrategy implements ActivationStrategyInterface
|
||||
{
|
||||
@@ -41,13 +44,15 @@ class ChannelLevelActivationStrategy implements ActivationStrategyInterface
|
||||
private $defaultActionLevel;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, Level>
|
||||
*/
|
||||
private $channelToActionLevel;
|
||||
|
||||
/**
|
||||
* @param int|string $defaultActionLevel The default action level to be used if the record's category doesn't match any
|
||||
* @param array $channelToActionLevel An array that maps channel names to action levels.
|
||||
* @param int|string $defaultActionLevel The default action level to be used if the record's category doesn't match any
|
||||
* @param array<string, int> $channelToActionLevel An array that maps channel names to action levels.
|
||||
*
|
||||
* @phpstan-param array<string, Level> $channelToActionLevel
|
||||
*/
|
||||
public function __construct($defaultActionLevel, array $channelToActionLevel = [])
|
||||
{
|
||||
@@ -55,6 +60,9 @@ class ChannelLevelActivationStrategy implements ActivationStrategyInterface
|
||||
$this->channelToActionLevel = array_map('Monolog\Logger::toMonologLevel', $channelToActionLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function isHandlerActivated(array $record): bool
|
||||
{
|
||||
if (isset($this->channelToActionLevel[$record['channel']])) {
|
||||
|
@@ -32,23 +32,40 @@ use Monolog\Formatter\FormatterInterface;
|
||||
* Monolog\Handler\FingersCrossed\ namespace.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
*/
|
||||
class FingersCrossedHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface
|
||||
{
|
||||
use ProcessableHandlerTrait;
|
||||
|
||||
/** @var HandlerInterface */
|
||||
/**
|
||||
* @var callable|HandlerInterface
|
||||
* @phpstan-var callable(?Record, HandlerInterface): HandlerInterface|HandlerInterface
|
||||
*/
|
||||
protected $handler;
|
||||
/** @var ActivationStrategyInterface */
|
||||
protected $activationStrategy;
|
||||
/** @var bool */
|
||||
protected $buffering = true;
|
||||
/** @var int */
|
||||
protected $bufferSize;
|
||||
/** @var Record[] */
|
||||
protected $buffer = [];
|
||||
/** @var bool */
|
||||
protected $stopBuffering;
|
||||
/**
|
||||
* @var ?int
|
||||
* @phpstan-var ?Level
|
||||
*/
|
||||
protected $passthruLevel;
|
||||
/** @var bool */
|
||||
protected $bubble;
|
||||
|
||||
/**
|
||||
* @psalm-param HandlerInterface|callable(?array, FingersCrossedHandler): HandlerInterface $handler
|
||||
* @psalm-param HandlerInterface|callable(?Record, HandlerInterface): HandlerInterface $handler
|
||||
*
|
||||
* @param callable|HandlerInterface $handler Handler or factory callable($record|null, $fingersCrossedHandler).
|
||||
* @param int|string|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action, or a level name/value at which the handler is activated
|
||||
@@ -171,7 +188,7 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
|
||||
return $record['level'] >= $level;
|
||||
});
|
||||
if (count($this->buffer) > 0) {
|
||||
$this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer);
|
||||
$this->getHandler(end($this->buffer))->handleBatch($this->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +202,8 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
|
||||
* If the handler was provided as a factory callable, this will trigger the handler's instantiation.
|
||||
*
|
||||
* @return HandlerInterface
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function getHandler(array $record = null)
|
||||
{
|
||||
|
@@ -18,6 +18,8 @@ use Monolog\Formatter\FormatterInterface;
|
||||
* Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol.
|
||||
*
|
||||
* @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class FirePHPHandler extends AbstractProcessingHandler
|
||||
{
|
||||
@@ -45,6 +47,7 @@ class FirePHPHandler extends AbstractProcessingHandler
|
||||
|
||||
/**
|
||||
* Whether or not Wildfire vendor-specific headers have been generated & sent yet
|
||||
* @var bool
|
||||
*/
|
||||
protected static $initialized = false;
|
||||
|
||||
@@ -54,14 +57,15 @@ class FirePHPHandler extends AbstractProcessingHandler
|
||||
*/
|
||||
protected static $messageIndex = 1;
|
||||
|
||||
/** @var bool */
|
||||
protected static $sendHeaders = true;
|
||||
|
||||
/**
|
||||
* Base header creation function used by init headers & record headers
|
||||
*
|
||||
* @param array $meta Wildfire Plugin, Protocol & Structure Indexes
|
||||
* @param string $message Log message
|
||||
* @return array Complete header string ready for the client as key and message as value
|
||||
* @param array<int|string> $meta Wildfire Plugin, Protocol & Structure Indexes
|
||||
* @param string $message Log message
|
||||
* @return array<string, string> Complete header string ready for the client as key and message as value
|
||||
*/
|
||||
protected function createHeader(array $meta, string $message): array
|
||||
{
|
||||
@@ -73,7 +77,11 @@ class FirePHPHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Creates message header from record
|
||||
*
|
||||
* @return array<string, string>
|
||||
*
|
||||
* @see createHeader()
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
protected function createRecordHeader(array $record): array
|
||||
{
|
||||
@@ -98,6 +106,8 @@ class FirePHPHandler extends AbstractProcessingHandler
|
||||
*
|
||||
* @see createHeader()
|
||||
* @see sendHeader()
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function getInitHeaders(): array
|
||||
{
|
||||
@@ -124,7 +134,6 @@ class FirePHPHandler extends AbstractProcessingHandler
|
||||
*
|
||||
* @see sendHeader()
|
||||
* @see sendInitHeaders()
|
||||
* @param array $record
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
|
@@ -22,6 +22,8 @@ use Monolog\Logger;
|
||||
*
|
||||
* @see https://fleep.io/integrations/webhooks/ Fleep Webhooks Documentation
|
||||
* @author Ando Roots <ando@sqroot.eu>
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class FleepHookHandler extends SocketHandler
|
||||
{
|
||||
@@ -104,6 +106,8 @@ class FleepHookHandler extends SocketHandler
|
||||
|
||||
/**
|
||||
* Builds the body of API call
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
private function buildContent(array $record): string
|
||||
{
|
||||
|
@@ -26,6 +26,8 @@ use Monolog\Formatter\FormatterInterface;
|
||||
*
|
||||
* @author Dominik Liebler <liebler.dominik@gmail.com>
|
||||
* @see https://www.flowdock.com/api/push
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class FlowdockHandler extends SocketHandler
|
||||
{
|
||||
@@ -72,8 +74,6 @@ class FlowdockHandler extends SocketHandler
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $record
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
@@ -94,6 +94,8 @@ class FlowdockHandler extends SocketHandler
|
||||
|
||||
/**
|
||||
* Builds the body of API call
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
private function buildContent(array $record): string
|
||||
{
|
||||
|
@@ -25,6 +25,7 @@ class GroupHandler extends Handler implements ProcessableHandlerInterface, Reset
|
||||
|
||||
/** @var HandlerInterface[] */
|
||||
protected $handlers;
|
||||
/** @var bool */
|
||||
protected $bubble;
|
||||
|
||||
/**
|
||||
|
@@ -15,6 +15,9 @@ namespace Monolog\Handler;
|
||||
* Interface that all Monolog Handlers must implement
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
interface HandlerInterface
|
||||
{
|
||||
@@ -30,6 +33,8 @@ interface HandlerInterface
|
||||
* @param array $record Partial log record containing only a level key
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @phpstan-param array{level: Level} $record
|
||||
*/
|
||||
public function isHandling(array $record): bool;
|
||||
|
||||
@@ -46,6 +51,8 @@ interface HandlerInterface
|
||||
* @param array $record The record to handle
|
||||
* @return bool true means that this handler handled the record, and that bubbling is not permitted.
|
||||
* false means the record was either not processed or that this handler allows bubbling.
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function handle(array $record): bool;
|
||||
|
||||
@@ -53,6 +60,8 @@ interface HandlerInterface
|
||||
* Handles a set of records at once.
|
||||
*
|
||||
* @param array $records The records to handle (an array of record arrays)
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
public function handleBatch(array $records): void;
|
||||
|
||||
|
@@ -27,7 +27,9 @@ use Monolog\Utils;
|
||||
*/
|
||||
class IFTTTHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var string */
|
||||
private $eventName;
|
||||
/** @var string */
|
||||
private $secretKey;
|
||||
|
||||
/**
|
||||
|
@@ -37,8 +37,10 @@ class LogglyHandler extends AbstractProcessingHandler
|
||||
*/
|
||||
protected $curlHandlers = [];
|
||||
|
||||
/** @var string */
|
||||
protected $token;
|
||||
|
||||
/** @var string[] */
|
||||
protected $tag = [];
|
||||
|
||||
/**
|
||||
|
@@ -18,6 +18,8 @@ use Monolog\Formatter\HtmlFormatter;
|
||||
* Base class for all mail handlers
|
||||
*
|
||||
* @author Gyula Sallai
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
abstract class MailHandler extends AbstractProcessingHandler
|
||||
{
|
||||
@@ -45,6 +47,8 @@ abstract class MailHandler extends AbstractProcessingHandler
|
||||
*
|
||||
* @param string $content formatted email body to be sent
|
||||
* @param array $records the array of log records that formed this content
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
abstract protected function send(string $content, array $records): void;
|
||||
|
||||
@@ -56,6 +60,10 @@ abstract class MailHandler extends AbstractProcessingHandler
|
||||
$this->send((string) $record['formatted'], [$record]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record[] $records
|
||||
* @phpstan-return Record
|
||||
*/
|
||||
protected function getHighestRecord(array $records): array
|
||||
{
|
||||
$highestRecord = null;
|
||||
|
@@ -33,8 +33,11 @@ use Monolog\Formatter\MongoDBFormatter;
|
||||
*/
|
||||
class MongoDBHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var \MongoDB\Collection */
|
||||
private $collection;
|
||||
/** @var Client|Manager */
|
||||
private $manager;
|
||||
/** @var string */
|
||||
private $namespace;
|
||||
|
||||
/**
|
||||
|
@@ -24,7 +24,7 @@ class NativeMailerHandler extends MailHandler
|
||||
{
|
||||
/**
|
||||
* The email addresses to which the message will be sent
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
@@ -36,13 +36,13 @@ class NativeMailerHandler extends MailHandler
|
||||
|
||||
/**
|
||||
* Optional headers for the message
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $headers = [];
|
||||
|
||||
/**
|
||||
* Optional parameters for the message
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $parameters = [];
|
||||
|
||||
@@ -65,7 +65,7 @@ class NativeMailerHandler extends MailHandler
|
||||
protected $encoding = 'utf-8';
|
||||
|
||||
/**
|
||||
* @param string|array $to The receiver of the mail
|
||||
* @param string|string[] $to The receiver of the mail
|
||||
* @param string $subject The subject of the mail
|
||||
* @param string $from The sender of the mail
|
||||
* @param string|int $level The minimum logging level at which this handler will be triggered
|
||||
@@ -84,7 +84,7 @@ class NativeMailerHandler extends MailHandler
|
||||
/**
|
||||
* Add headers to the message
|
||||
*
|
||||
* @param string|array $headers Custom added headers
|
||||
* @param string|string[] $headers Custom added headers
|
||||
*/
|
||||
public function addHeader($headers): self
|
||||
{
|
||||
@@ -101,7 +101,7 @@ class NativeMailerHandler extends MailHandler
|
||||
/**
|
||||
* Add parameters to the message
|
||||
*
|
||||
* @param string|array $parameters Custom added parameters
|
||||
* @param string|string[] $parameters Custom added parameters
|
||||
*/
|
||||
public function addParameter($parameters): self
|
||||
{
|
||||
|
@@ -30,14 +30,14 @@ class NewRelicHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Name of the New Relic application that will receive logs from this handler.
|
||||
*
|
||||
* @var string|null
|
||||
* @var ?string
|
||||
*/
|
||||
protected $appName;
|
||||
|
||||
/**
|
||||
* Name of the current transaction
|
||||
*
|
||||
* @var string|null
|
||||
* @var ?string
|
||||
*/
|
||||
protected $transactionName;
|
||||
|
||||
@@ -135,6 +135,8 @@ class NewRelicHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Returns the appname where this log should be sent. Each log can override the default appname, set in this
|
||||
* handler's constructor, by providing the appname in it's context.
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
protected function getAppName(array $context): ?string
|
||||
{
|
||||
@@ -148,6 +150,8 @@ class NewRelicHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Returns the name of the current transaction. Each log can override the default transaction name, set in this
|
||||
* handler's constructor, by providing the transaction_name in it's context
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
protected function getTransactionName(array $context): ?string
|
||||
{
|
||||
|
@@ -87,10 +87,7 @@ class OverflowHandler extends AbstractHandler implements FormattableHandlerInter
|
||||
* Unless the bubbling is interrupted (by returning true), the Logger class will keep on
|
||||
* calling further handlers in the stack with a given log record.
|
||||
*
|
||||
* @param array $record The record to handle
|
||||
*
|
||||
* @return Boolean true means that this handler handled the record, and that bubbling is not permitted.
|
||||
* false means the record was either not processed or that this handler allows bubbling.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
|
@@ -37,9 +37,12 @@ use PhpConsole\Helper;
|
||||
* PC::debug($_SERVER); // PHP Console debugger for any type of vars
|
||||
*
|
||||
* @author Sergey Barbushin https://www.linkedin.com/in/barbushin
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class PHPConsoleHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var array<string, mixed> */
|
||||
private $options = [
|
||||
'enabled' => true, // bool Is PHP Console server enabled
|
||||
'classesPartialsTraceIgnore' => ['Monolog\\'], // array Hide calls of classes started with...
|
||||
@@ -67,10 +70,10 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
||||
private $connector;
|
||||
|
||||
/**
|
||||
* @param array $options See \Monolog\Handler\PHPConsoleHandler::$options for more details
|
||||
* @param Connector|null $connector Instance of \PhpConsole\Connector class (optional)
|
||||
* @param string|int $level The minimum logging level at which this handler will be triggered.
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not.
|
||||
* @param array<string, mixed> $options See \Monolog\Handler\PHPConsoleHandler::$options for more details
|
||||
* @param Connector|null $connector Instance of \PhpConsole\Connector class (optional)
|
||||
* @param string|int $level The minimum logging level at which this handler will be triggered.
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not.
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct(array $options = [], ?Connector $connector = null, $level = Logger::DEBUG, bool $bubble = true)
|
||||
@@ -83,6 +86,10 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
||||
$this->connector = $this->initConnector($connector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $options
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function initOptions(array $options): array
|
||||
{
|
||||
$wrongOptions = array_diff(array_keys($options), array_keys($this->options));
|
||||
@@ -153,6 +160,9 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
||||
return $this->connector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
@@ -181,6 +191,9 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function handleDebugRecord(array $record): void
|
||||
{
|
||||
$tags = $this->getRecordTags($record);
|
||||
@@ -191,11 +204,17 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
||||
$this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function handleExceptionRecord(array $record): void
|
||||
{
|
||||
$this->connector->getErrorsDispatcher()->dispatchException($record['context']['exception']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function handleErrorRecord(array $record): void
|
||||
{
|
||||
$context = $record['context'];
|
||||
@@ -209,6 +228,10 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
* @return string
|
||||
*/
|
||||
private function getRecordTags(array &$record)
|
||||
{
|
||||
$tags = null;
|
||||
|
@@ -44,12 +44,12 @@ class ProcessHandler extends AbstractProcessingHandler
|
||||
private $cwd;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var resource[]
|
||||
*/
|
||||
private $pipes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string[]>
|
||||
*/
|
||||
protected const DESCRIPTOR_SPEC = [
|
||||
0 => ['pipe', 'r'], // STDIN is a pipe that the child will read from
|
||||
|
@@ -17,13 +17,15 @@ use Monolog\Processor\ProcessorInterface;
|
||||
* Interface to describe loggers that have processors
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
interface ProcessableHandlerInterface
|
||||
{
|
||||
/**
|
||||
* Adds a processor in the stack.
|
||||
*
|
||||
* @psalm-param ProcessorInterface|callable(array): array $callback
|
||||
* @psalm-param ProcessorInterface|callable(Record): Record $callback
|
||||
*
|
||||
* @param ProcessorInterface|callable $callback
|
||||
* @return HandlerInterface self
|
||||
@@ -33,10 +35,10 @@ interface ProcessableHandlerInterface
|
||||
/**
|
||||
* Removes the processor on top of the stack and returns it.
|
||||
*
|
||||
* @psalm-return callable(array): array
|
||||
* @psalm-return ProcessorInterface|callable(Record): Record $callback
|
||||
*
|
||||
* @throws \LogicException In case the processor stack is empty
|
||||
* @return callable
|
||||
* @return callable|ProcessorInterface
|
||||
*/
|
||||
public function popProcessor(): callable;
|
||||
}
|
||||
|
@@ -12,16 +12,20 @@
|
||||
namespace Monolog\Handler;
|
||||
|
||||
use Monolog\ResettableInterface;
|
||||
use Monolog\Processor\ProcessorInterface;
|
||||
|
||||
/**
|
||||
* Helper trait for implementing ProcessableInterface
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
trait ProcessableHandlerTrait
|
||||
{
|
||||
/**
|
||||
* @var callable[]
|
||||
* @phpstan-var array<ProcessorInterface|callable(Record): Record>
|
||||
*/
|
||||
protected $processors = [];
|
||||
|
||||
@@ -49,6 +53,9 @@ trait ProcessableHandlerTrait
|
||||
|
||||
/**
|
||||
* Processes a record.
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
* @phpstan-return Record
|
||||
*/
|
||||
protected function processRecord(array $record): array
|
||||
{
|
||||
|
@@ -19,24 +19,35 @@ use Monolog\Utils;
|
||||
*
|
||||
* @author Sebastian Göttschkes <sebastian.goettschkes@googlemail.com>
|
||||
* @see https://www.pushover.net/api
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class PushoverHandler extends SocketHandler
|
||||
{
|
||||
/** @var string */
|
||||
private $token;
|
||||
/** @var array<int|string> */
|
||||
private $users;
|
||||
/** @var ?string */
|
||||
private $title;
|
||||
private $user;
|
||||
/** @var string|int|null */
|
||||
private $user = null;
|
||||
/** @var int */
|
||||
private $retry;
|
||||
/** @var int */
|
||||
private $expire;
|
||||
|
||||
/** @var int */
|
||||
private $highPriorityLevel;
|
||||
/** @var int */
|
||||
private $emergencyLevel;
|
||||
/** @var bool */
|
||||
private $useFormattedMessage = false;
|
||||
|
||||
/**
|
||||
* All parameters that can be sent to Pushover
|
||||
* @see https://pushover.net/api
|
||||
* @var array
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $parameterNames = [
|
||||
'token' => true,
|
||||
@@ -57,7 +68,7 @@ class PushoverHandler extends SocketHandler
|
||||
/**
|
||||
* Sounds the api supports by default
|
||||
* @see https://pushover.net/api#sounds
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
private $sounds = [
|
||||
'pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming',
|
||||
@@ -81,6 +92,8 @@ class PushoverHandler extends SocketHandler
|
||||
* send the same notification to the user.
|
||||
* @param int $expire The expire parameter specifies how many seconds your notification will continue
|
||||
* to be retried for (every retry seconds).
|
||||
*
|
||||
* @phpstan-param string|array<int|string> $users
|
||||
*/
|
||||
public function __construct(
|
||||
string $token,
|
||||
@@ -113,6 +126,9 @@ class PushoverHandler extends SocketHandler
|
||||
return $this->buildHeader($content) . $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
private function buildContent(array $record): string
|
||||
{
|
||||
// Pushover has a limit of 512 characters on title and message combined.
|
||||
@@ -177,6 +193,9 @@ class PushoverHandler extends SocketHandler
|
||||
$this->user = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $value
|
||||
*/
|
||||
public function setHighPriorityLevel($value): self
|
||||
{
|
||||
$this->highPriorityLevel = Logger::toMonologLevel($value);
|
||||
@@ -184,6 +203,9 @@ class PushoverHandler extends SocketHandler
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $value
|
||||
*/
|
||||
public function setEmergencyLevel($value): self
|
||||
{
|
||||
$this->emergencyLevel = Logger::toMonologLevel($value);
|
||||
|
@@ -25,11 +25,16 @@ use Monolog\Logger;
|
||||
* $log->pushHandler($redis);
|
||||
*
|
||||
* @author Thomas Tourlourat <thomas@tourlourat.com>
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class RedisHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var \Predis\Client|\Redis */
|
||||
private $redisClient;
|
||||
/** @var string */
|
||||
private $redisKey;
|
||||
/** @var int */
|
||||
protected $capSize;
|
||||
|
||||
/**
|
||||
@@ -67,6 +72,8 @@ class RedisHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Write and cap the collection
|
||||
* Writes the record to the redis list and caps its
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
protected function writeCapped(array $record): void
|
||||
{
|
||||
|
@@ -28,7 +28,9 @@ use Monolog\Logger;
|
||||
*/
|
||||
class RedisPubSubHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var \Predis\Client|\Redis */
|
||||
private $redisClient;
|
||||
/** @var string */
|
||||
private $channelKey;
|
||||
|
||||
/**
|
||||
|
@@ -38,6 +38,7 @@ class RollbarHandler extends AbstractProcessingHandler
|
||||
*/
|
||||
protected $rollbarLogger;
|
||||
|
||||
/** @var string[] */
|
||||
protected $levelMap = [
|
||||
Logger::DEBUG => 'debug',
|
||||
Logger::INFO => 'info',
|
||||
@@ -56,6 +57,7 @@ class RollbarHandler extends AbstractProcessingHandler
|
||||
*/
|
||||
private $hasRecords = false;
|
||||
|
||||
/** @var bool */
|
||||
protected $initialized = false;
|
||||
|
||||
/**
|
||||
|
@@ -30,11 +30,17 @@ class RotatingFileHandler extends StreamHandler
|
||||
public const FILE_PER_MONTH = 'Y-m';
|
||||
public const FILE_PER_YEAR = 'Y';
|
||||
|
||||
/** @var string */
|
||||
protected $filename;
|
||||
/** @var int */
|
||||
protected $maxFiles;
|
||||
/** @var bool */
|
||||
protected $mustRotate;
|
||||
/** @var \DateTimeImmutable */
|
||||
protected $nextRotation;
|
||||
/** @var string */
|
||||
protected $filenameFormat;
|
||||
/** @var string */
|
||||
protected $dateFormat;
|
||||
|
||||
/**
|
||||
|
@@ -26,13 +26,17 @@ use Monolog\Formatter\FormatterInterface;
|
||||
*
|
||||
* @author Bryan Davis <bd808@wikimedia.org>
|
||||
* @author Kunal Mehta <legoktm@gmail.com>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
class SamplingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
|
||||
{
|
||||
use ProcessableHandlerTrait;
|
||||
|
||||
/**
|
||||
* @var callable|HandlerInterface $handler
|
||||
* @var HandlerInterface|callable
|
||||
* @phpstan-var HandlerInterface|callable(Record, HandlerInterface): HandlerInterface
|
||||
*/
|
||||
protected $handler;
|
||||
|
||||
@@ -42,7 +46,7 @@ class SamplingHandler extends AbstractHandler implements ProcessableHandlerInter
|
||||
protected $factor;
|
||||
|
||||
/**
|
||||
* @psalm-param HandlerInterface|callable(array, HandlerInterface): HandlerInterface $handler
|
||||
* @psalm-param HandlerInterface|callable(Record, HandlerInterface): HandlerInterface $handler
|
||||
*
|
||||
* @param callable|HandlerInterface $handler Handler or factory callable($record|null, $samplingHandler).
|
||||
* @param int $factor Sample factor (e.g. 10 means every ~10th record is sampled)
|
||||
@@ -81,6 +85,8 @@ class SamplingHandler extends AbstractHandler implements ProcessableHandlerInter
|
||||
*
|
||||
* If the handler was provided as a factory callable, this will trigger the handler's instantiation.
|
||||
*
|
||||
* @phpstan-param Record|array{level: Level}|null $record
|
||||
*
|
||||
* @return HandlerInterface
|
||||
*/
|
||||
public function getHandler(array $record = null)
|
||||
|
@@ -40,7 +40,7 @@ class SendGridHandler extends MailHandler
|
||||
|
||||
/**
|
||||
* The email addresses to which the message will be sent
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
@@ -51,13 +51,13 @@ class SendGridHandler extends MailHandler
|
||||
protected $subject;
|
||||
|
||||
/**
|
||||
* @param string $apiUser The SendGrid API User
|
||||
* @param string $apiKey The SendGrid API Key
|
||||
* @param string $from The sender of the email
|
||||
* @param string|array $to The recipients of the email
|
||||
* @param string $subject The subject of the mail
|
||||
* @param int|string $level The minimum logging level at which this handler will be triggered
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
* @param string $apiUser The SendGrid API User
|
||||
* @param string $apiKey The SendGrid API Key
|
||||
* @param string $from The sender of the email
|
||||
* @param string|string[] $to The recipients of the email
|
||||
* @param string $subject The subject of the mail
|
||||
* @param int|string $level The minimum logging level at which this handler will be triggered
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*/
|
||||
public function __construct(string $apiUser, string $apiKey, string $from, $to, string $subject, $level = Logger::ERROR, bool $bubble = true)
|
||||
{
|
||||
|
@@ -23,6 +23,8 @@ use Monolog\Formatter\FormatterInterface;
|
||||
* @author Haralan Dobrev <hkdobrev@gmail.com>
|
||||
* @see https://api.slack.com/incoming-webhooks
|
||||
* @see https://api.slack.com/docs/message-attachments
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from \Monolog\Handler\AbstractProcessingHandler
|
||||
*/
|
||||
class SlackRecord
|
||||
{
|
||||
@@ -72,7 +74,7 @@ class SlackRecord
|
||||
|
||||
/**
|
||||
* Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
private $excludeFields;
|
||||
|
||||
@@ -86,6 +88,9 @@ class SlackRecord
|
||||
*/
|
||||
private $normalizerFormatter;
|
||||
|
||||
/**
|
||||
* @param string[] $excludeFields
|
||||
*/
|
||||
public function __construct(
|
||||
?string $channel = null,
|
||||
?string $username = null,
|
||||
@@ -114,6 +119,9 @@ class SlackRecord
|
||||
/**
|
||||
* Returns required data in format that Slack
|
||||
* is expecting.
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
* @phpstan-return string[]
|
||||
*/
|
||||
public function getSlackData(array $record): array
|
||||
{
|
||||
@@ -208,6 +216,8 @@ class SlackRecord
|
||||
|
||||
/**
|
||||
* Stringifies an array of key/value pairs to be used in attachment fields
|
||||
*
|
||||
* @param mixed[] $fields
|
||||
*/
|
||||
public function stringify(array $fields): string
|
||||
{
|
||||
@@ -285,6 +295,9 @@ class SlackRecord
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $excludeFields
|
||||
*/
|
||||
public function excludeFields(array $excludeFields = []): self
|
||||
{
|
||||
$this->excludeFields = $excludeFields;
|
||||
@@ -302,7 +315,8 @@ class SlackRecord
|
||||
/**
|
||||
* Generates attachment field
|
||||
*
|
||||
* @param string|array $value
|
||||
* @param string|mixed[] $value
|
||||
* @return array{title: string, value: string, short: false}
|
||||
*/
|
||||
private function generateAttachmentField(string $title, $value): array
|
||||
{
|
||||
@@ -319,6 +333,9 @@ class SlackRecord
|
||||
|
||||
/**
|
||||
* Generates a collection of attachment fields from array
|
||||
*
|
||||
* @param mixed[] $data
|
||||
* @return array<array{title: string, value: string, short: false}>
|
||||
*/
|
||||
private function generateAttachmentFields(array $data): array
|
||||
{
|
||||
@@ -332,6 +349,9 @@ class SlackRecord
|
||||
|
||||
/**
|
||||
* Get a copy of record with fields excluded according to $this->excludeFields
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function removeExcludedFields(array $record): array
|
||||
{
|
||||
|
@@ -21,6 +21,8 @@ use Monolog\Handler\Slack\SlackRecord;
|
||||
*
|
||||
* @author Greg Kedzierski <greg@gregkedzierski.com>
|
||||
* @see https://api.slack.com/
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class SlackHandler extends SocketHandler
|
||||
{
|
||||
@@ -46,7 +48,7 @@ class SlackHandler extends SocketHandler
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
* @param bool $useShortAttachment Whether the context/extra messages added to Slack as attachments are in a short style
|
||||
* @param bool $includeContextAndExtra Whether the attachment should include context and extra data
|
||||
* @param array $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
|
||||
* @param string[] $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
|
||||
* @throws MissingExtensionException If no OpenSSL PHP extension configured
|
||||
*/
|
||||
public function __construct(
|
||||
@@ -102,6 +104,8 @@ class SlackHandler extends SocketHandler
|
||||
|
||||
/**
|
||||
* Builds the body of API call
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
private function buildContent(array $record): string
|
||||
{
|
||||
@@ -110,6 +114,10 @@ class SlackHandler extends SocketHandler
|
||||
return http_build_query($dataArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param FormattedRecord $record
|
||||
* @return string[]
|
||||
*/
|
||||
protected function prepareContentData(array $record): array
|
||||
{
|
||||
$dataArray = $this->slackRecord->getSlackData($record);
|
||||
@@ -224,6 +232,9 @@ class SlackHandler extends SocketHandler
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $excludeFields
|
||||
*/
|
||||
public function excludeFields(array $excludeFields): self
|
||||
{
|
||||
$this->slackRecord->excludeFields($excludeFields);
|
||||
|
@@ -46,7 +46,7 @@ class SlackWebhookHandler extends AbstractProcessingHandler
|
||||
* @param bool $includeContextAndExtra Whether the attachment should include context and extra data
|
||||
* @param string|int $level The minimum logging level at which this handler will be triggered
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
* @param array $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
|
||||
* @param string[] $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
|
||||
*/
|
||||
public function __construct(
|
||||
string $webhookUrl,
|
||||
@@ -87,8 +87,6 @@ class SlackWebhookHandler extends AbstractProcessingHandler
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $record
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
|
@@ -18,10 +18,15 @@ use Monolog\Logger;
|
||||
*
|
||||
* @author Pablo de Leon Belloc <pablolb@gmail.com>
|
||||
* @see http://php.net/manual/en/function.fsockopen.php
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class SocketHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var string */
|
||||
private $connectionString;
|
||||
/** @var float */
|
||||
private $connectionTimeout;
|
||||
/** @var resource|null */
|
||||
private $resource;
|
||||
@@ -29,14 +34,18 @@ class SocketHandler extends AbstractProcessingHandler
|
||||
private $timeout = 0.0;
|
||||
/** @var float */
|
||||
private $writingTimeout = 10.0;
|
||||
/** @var ?int */
|
||||
private $lastSentBytes = null;
|
||||
/** @var int */
|
||||
private $chunkSize = null;
|
||||
/** @var bool */
|
||||
private $persistent = false;
|
||||
private $errno;
|
||||
private $errstr;
|
||||
/** @var ?int */
|
||||
private $errno = null;
|
||||
/** @var ?string */
|
||||
private $errstr = null;
|
||||
/** @var ?float */
|
||||
private $lastWritingAt;
|
||||
private $lastWritingAt = null;
|
||||
|
||||
/**
|
||||
* @param string $connectionString Socket connection string
|
||||
@@ -53,7 +62,7 @@ class SocketHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* Connect (if necessary) and write to the socket
|
||||
*
|
||||
* @param array $record
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws \UnexpectedValueException
|
||||
* @throws \RuntimeException
|
||||
@@ -208,6 +217,8 @@ class SocketHandler extends AbstractProcessingHandler
|
||||
|
||||
/**
|
||||
* Wrapper to allow mocking
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
protected function pfsockopen()
|
||||
{
|
||||
@@ -216,6 +227,8 @@ class SocketHandler extends AbstractProcessingHandler
|
||||
|
||||
/**
|
||||
* Wrapper to allow mocking
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
protected function fsockopen()
|
||||
{
|
||||
@@ -226,6 +239,8 @@ class SocketHandler extends AbstractProcessingHandler
|
||||
* Wrapper to allow mocking
|
||||
*
|
||||
* @see http://php.net/manual/en/function.stream-set-timeout.php
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function streamSetTimeout()
|
||||
{
|
||||
@@ -239,6 +254,8 @@ class SocketHandler extends AbstractProcessingHandler
|
||||
* Wrapper to allow mocking
|
||||
*
|
||||
* @see http://php.net/manual/en/function.stream-set-chunk-size.php
|
||||
*
|
||||
* @return int|bool
|
||||
*/
|
||||
protected function streamSetChunkSize()
|
||||
{
|
||||
@@ -247,29 +264,32 @@ class SocketHandler extends AbstractProcessingHandler
|
||||
|
||||
/**
|
||||
* Wrapper to allow mocking
|
||||
*
|
||||
* @return int|bool
|
||||
*/
|
||||
protected function fwrite($data)
|
||||
protected function fwrite(string $data)
|
||||
{
|
||||
return @fwrite($this->resource, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to allow mocking
|
||||
*
|
||||
* @return mixed[]|bool
|
||||
*/
|
||||
protected function streamGetMetadata()
|
||||
{
|
||||
return stream_get_meta_data($this->resource);
|
||||
}
|
||||
|
||||
private function validateTimeout($value)
|
||||
private function validateTimeout(float $value): void
|
||||
{
|
||||
$ok = filter_var($value, FILTER_VALIDATE_FLOAT);
|
||||
if ($ok === false || $value < 0) {
|
||||
if ($value < 0) {
|
||||
throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got $value)");
|
||||
}
|
||||
}
|
||||
|
||||
private function connectIfNotConnected()
|
||||
private function connectIfNotConnected(): void
|
||||
{
|
||||
if ($this->isConnected()) {
|
||||
return;
|
||||
@@ -277,6 +297,9 @@ class SocketHandler extends AbstractProcessingHandler
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
protected function generateDataStream(array $record): string
|
||||
{
|
||||
return (string) $record['formatted'];
|
||||
|
@@ -41,9 +41,7 @@ class SqsHandler extends AbstractProcessingHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the record down to the log of the implementing handler.
|
||||
*
|
||||
* @param array $record
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
|
@@ -20,6 +20,8 @@ use Monolog\Utils;
|
||||
* Can be used to store into php://stderr, remote and local files, etc.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class StreamHandler extends AbstractProcessingHandler
|
||||
{
|
||||
@@ -27,12 +29,16 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
|
||||
/** @var resource|null */
|
||||
protected $stream;
|
||||
protected $url;
|
||||
/** @var string|null */
|
||||
private $errorMessage;
|
||||
/** @var ?string */
|
||||
protected $url = null;
|
||||
/** @var ?string */
|
||||
private $errorMessage = null;
|
||||
/** @var ?int */
|
||||
protected $filePermission;
|
||||
/** @var bool */
|
||||
protected $useLocking;
|
||||
private $dirCreated;
|
||||
/** @var true|null */
|
||||
private $dirCreated = null;
|
||||
|
||||
/**
|
||||
* @param resource|string $stream If a missing path can't be created, an UnexpectedValueException will be thrown on first write
|
||||
@@ -132,13 +138,15 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
* Write to stream
|
||||
* @param resource $stream
|
||||
* @param array $record
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
protected function streamWrite($stream, array $record): void
|
||||
{
|
||||
fwrite($stream, (string) $record['formatted']);
|
||||
}
|
||||
|
||||
private function customErrorHandler($code, $msg): bool
|
||||
private function customErrorHandler(int $code, string $msg): bool
|
||||
{
|
||||
$this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg);
|
||||
|
||||
|
@@ -21,14 +21,18 @@ use Swift;
|
||||
* SwiftMailerHandler uses Swift_Mailer to send the emails
|
||||
*
|
||||
* @author Gyula Sallai
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class SwiftMailerHandler extends MailHandler
|
||||
{
|
||||
/** @var \Swift_Mailer */
|
||||
protected $mailer;
|
||||
/** @var Swift_Message|callable(string, Record[]): Swift_Message */
|
||||
private $messageTemplate;
|
||||
|
||||
/**
|
||||
* @psalm-param Swift_Message|callable(string, array): Swift_Message $message
|
||||
* @psalm-param Swift_Message|callable(string, Record[]): Swift_Message $message
|
||||
*
|
||||
* @param \Swift_Mailer $mailer The mailer to use
|
||||
* @param callable|Swift_Message $message An example message for real messages, only the body will be replaced
|
||||
@@ -67,6 +71,8 @@ class SwiftMailerHandler extends MailHandler
|
||||
* @param string $content formatted email body to be sent
|
||||
* @param array $records Log records that formed the content
|
||||
* @return Swift_Message
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
protected function buildMessage(string $content, array $records): Swift_Message
|
||||
{
|
||||
|
@@ -28,7 +28,9 @@ use Monolog\Logger;
|
||||
*/
|
||||
class SyslogHandler extends AbstractSyslogHandler
|
||||
{
|
||||
/** @var string */
|
||||
protected $ident;
|
||||
/** @var int */
|
||||
protected $logopts;
|
||||
|
||||
/**
|
||||
|
@@ -39,6 +39,11 @@ class UdpSocket
|
||||
$this->socket = socket_create($domain, SOCK_DGRAM, $protocol) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @param string $header
|
||||
* @return void
|
||||
*/
|
||||
public function write($line, $header = "")
|
||||
{
|
||||
$this->send($this->assembleMessage($line, $header));
|
||||
|
@@ -27,14 +27,18 @@ class SyslogUdpHandler extends AbstractSyslogHandler
|
||||
const RFC5424 = 1;
|
||||
const RFC5424e = 2;
|
||||
|
||||
/** @var array<self::RFC*, string> */
|
||||
private $dateFormats = array(
|
||||
self::RFC3164 => 'M d H:i:s',
|
||||
self::RFC5424 => \DateTime::RFC3339,
|
||||
self::RFC5424e => \DateTime::RFC3339_EXTENDED,
|
||||
);
|
||||
|
||||
/** @var UdpSocket */
|
||||
protected $socket;
|
||||
/** @var string */
|
||||
protected $ident;
|
||||
/** @var self::RFC* */
|
||||
protected $rfc;
|
||||
|
||||
/**
|
||||
@@ -45,6 +49,8 @@ class SyslogUdpHandler extends AbstractSyslogHandler
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
* @param string $ident Program name or tag for each log message.
|
||||
* @param int $rfc RFC to format the message for.
|
||||
*
|
||||
* @phpstan-param self::RFC* $rfc
|
||||
*/
|
||||
public function __construct(string $host, int $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, bool $bubble = true, string $ident = 'php', int $rfc = self::RFC5424)
|
||||
{
|
||||
@@ -72,6 +78,10 @@ class SyslogUdpHandler extends AbstractSyslogHandler
|
||||
$this->socket->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $message
|
||||
* @return string[]
|
||||
*/
|
||||
private function splitMessageIntoLines($message): array
|
||||
{
|
||||
if (is_array($message)) {
|
||||
|
@@ -33,7 +33,7 @@ class TelegramBotHandler extends AbstractProcessingHandler
|
||||
private const BOT_API = 'https://api.telegram.org/bot';
|
||||
|
||||
/**
|
||||
* @var array AVAILABLE_PARSE_MODES The available values of parseMode according to the Telegram api documentation
|
||||
* The available values of parseMode according to the Telegram api documentation
|
||||
*/
|
||||
private const AVAILABLE_PARSE_MODES = [
|
||||
'HTML',
|
||||
@@ -59,19 +59,19 @@ class TelegramBotHandler extends AbstractProcessingHandler
|
||||
* The kind of formatting that is used for the message.
|
||||
* See available options at https://core.telegram.org/bots/api#formatting-options
|
||||
* or in AVAILABLE_PARSE_MODES
|
||||
* @var string|null
|
||||
* @var ?string
|
||||
*/
|
||||
private $parseMode;
|
||||
|
||||
/**
|
||||
* Disables link previews for links in the message.
|
||||
* @var bool|null
|
||||
* @var ?bool
|
||||
*/
|
||||
private $disableWebPagePreview;
|
||||
|
||||
/**
|
||||
* Sends the message silently. Users will receive a notification with no sound.
|
||||
* @var bool|null
|
||||
* @var ?bool
|
||||
*/
|
||||
private $disableNotification;
|
||||
|
||||
|
@@ -12,6 +12,7 @@
|
||||
namespace Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Used for testing purposes.
|
||||
@@ -64,24 +65,42 @@ use Monolog\Logger;
|
||||
* @method bool hasNoticeThatPasses($message)
|
||||
* @method bool hasInfoThatPasses($message)
|
||||
* @method bool hasDebugThatPasses($message)
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
*/
|
||||
class TestHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var Record[] */
|
||||
protected $records = [];
|
||||
/** @var array<Level, Record[]> */
|
||||
protected $recordsByLevel = [];
|
||||
/** @var bool */
|
||||
private $skipReset = false;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @phpstan-return Record[]
|
||||
*/
|
||||
public function getRecords()
|
||||
{
|
||||
return $this->records;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->records = [];
|
||||
$this->recordsByLevel = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if (!$this->skipReset) {
|
||||
@@ -89,6 +108,9 @@ class TestHandler extends AbstractProcessingHandler
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setSkipReset(bool $skipReset)
|
||||
{
|
||||
$this->skipReset = $skipReset;
|
||||
@@ -105,6 +127,9 @@ class TestHandler extends AbstractProcessingHandler
|
||||
/**
|
||||
* @param string|array $record Either a message string or an array containing message and optionally context keys that will be checked against all records
|
||||
* @param string|int $level Logging level value or name
|
||||
*
|
||||
* @phpstan-param array{message: string, context?: mixed[]}|string $record
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $level
|
||||
*/
|
||||
public function hasRecord($record, $level): bool
|
||||
{
|
||||
@@ -136,6 +161,8 @@ class TestHandler extends AbstractProcessingHandler
|
||||
|
||||
/**
|
||||
* @param string|int $level Logging level value or name
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $level
|
||||
*/
|
||||
public function hasRecordThatMatches(string $regex, $level): bool
|
||||
{
|
||||
@@ -145,10 +172,11 @@ class TestHandler extends AbstractProcessingHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param callable(array, int): mixed $predicate
|
||||
*
|
||||
* @param string|int $level Logging level value or name
|
||||
* @return bool
|
||||
*
|
||||
* @psalm-param callable(Record, int): mixed $predicate
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $level
|
||||
*/
|
||||
public function hasRecordThatPasses(callable $predicate, $level)
|
||||
{
|
||||
@@ -176,6 +204,11 @@ class TestHandler extends AbstractProcessingHandler
|
||||
$this->records[] = $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param mixed[] $args
|
||||
* @return bool
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) {
|
||||
|
@@ -20,13 +20,15 @@ use Monolog\Logger;
|
||||
*
|
||||
* @author Christian Bergau <cbergau86@gmail.com>
|
||||
* @author Jason Davis <happydude@jasondavis.net>
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class ZendMonitorHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/**
|
||||
* Monolog level / ZendMonitor Custom Event priority map
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, int>
|
||||
*/
|
||||
protected $levelMap = [];
|
||||
|
||||
@@ -75,6 +77,8 @@ class ZendMonitorHandler extends AbstractProcessingHandler
|
||||
* @param string $message Text displayed in "Error String"
|
||||
* @param array $formatted Displayed in Custom Variables tab
|
||||
* @param int $severity Set the event severity level (-1,0,1)
|
||||
*
|
||||
* @phpstan-param FormattedRecord $formatted
|
||||
*/
|
||||
protected function writeZendMonitorCustomEvent(string $type, string $message, array $formatted, int $severity): void
|
||||
{
|
||||
@@ -89,6 +93,9 @@ class ZendMonitorHandler extends AbstractProcessingHandler
|
||||
return new NormalizerFormatter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, int>
|
||||
*/
|
||||
public function getLevelMap(): array
|
||||
{
|
||||
return $this->levelMap;
|
||||
|
@@ -15,6 +15,7 @@ use DateTimeZone;
|
||||
use Monolog\Handler\HandlerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\InvalidArgumentException;
|
||||
use Psr\Log\LogLevel;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
@@ -24,6 +25,10 @@ use Throwable;
|
||||
* and uses them to store records that are added to it.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-type Level Logger::DEBUG|Logger::INFO|Logger::NOTICE|Logger::WARNING|Logger::ERROR|Logger::CRITICAL|Logger::ALERT|Logger::EMERGENCY
|
||||
* @phpstan-type LevelName 'DEBUG'|'INFO'|'NOTICE'|'WARNING'|'ERROR'|'CRITICAL'|'ALERT'|'EMERGENCY'
|
||||
* @phpstan-type Record array{message: string, context: mixed[], level: Level, level_name: LevelName, channel: string, datetime: \DateTimeImmutable, extra: mixed[]}
|
||||
*/
|
||||
class Logger implements LoggerInterface, ResettableInterface
|
||||
{
|
||||
@@ -91,6 +96,8 @@ class Logger implements LoggerInterface, ResettableInterface
|
||||
* This is a static variable and not a constant to serve as an extension point for custom levels
|
||||
*
|
||||
* @var array<int, string> $levels Logging levels with the levels as key
|
||||
*
|
||||
* @phpstan-var array<Level, LevelName> $levels Logging levels with the levels as key
|
||||
*/
|
||||
protected static $levels = [
|
||||
self::DEBUG => 'DEBUG',
|
||||
@@ -276,6 +283,8 @@ class Logger implements LoggerInterface, ResettableInterface
|
||||
* @param string $message The log message
|
||||
* @param mixed[] $context The log context
|
||||
* @return bool Whether the record has been processed
|
||||
*
|
||||
* @phpstan-param Level $level
|
||||
*/
|
||||
public function addRecord(int $level, string $message, array $context = []): bool
|
||||
{
|
||||
@@ -383,6 +392,9 @@ class Logger implements LoggerInterface, ResettableInterface
|
||||
* Gets the name of the logging level.
|
||||
*
|
||||
* @throws \Psr\Log\InvalidArgumentException If level is not defined
|
||||
*
|
||||
* @phpstan-param Level $level
|
||||
* @phpstan-return LevelName
|
||||
*/
|
||||
public static function getLevelName(int $level): string
|
||||
{
|
||||
@@ -398,11 +410,15 @@ class Logger implements LoggerInterface, ResettableInterface
|
||||
*
|
||||
* @param string|int $level Level number (monolog) or name (PSR-3)
|
||||
* @throws \Psr\Log\InvalidArgumentException If level is not defined
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $level
|
||||
* @phpstan-return Level
|
||||
*/
|
||||
public static function toMonologLevel($level): int
|
||||
{
|
||||
if (is_string($level)) {
|
||||
if (is_numeric($level)) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
return intval($level);
|
||||
}
|
||||
|
||||
@@ -413,18 +429,21 @@ class Logger implements LoggerInterface, ResettableInterface
|
||||
return constant(__CLASS__ . '::' . $upper);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
|
||||
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels) + static::$levels));
|
||||
}
|
||||
|
||||
if (!is_int($level)) {
|
||||
throw new InvalidArgumentException('Level "'.var_export($level, true).'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
|
||||
throw new InvalidArgumentException('Level "'.var_export($level, true).'" is not defined, use one of: '.implode(', ', array_keys(static::$levels) + static::$levels));
|
||||
}
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
return $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the Logger has a handler that listens on the given level
|
||||
*
|
||||
* @phpstan-param Level $level
|
||||
*/
|
||||
public function isHandling(int $level): bool
|
||||
{
|
||||
@@ -463,9 +482,11 @@ class Logger implements LoggerInterface, ResettableInterface
|
||||
*
|
||||
* This method allows for compatibility with common interfaces.
|
||||
*
|
||||
* @param mixed $level The log level
|
||||
* @param string $message The log message
|
||||
* @param mixed[] $context The log context
|
||||
* @param int|string $level The log level
|
||||
* @param string $message The log message
|
||||
* @param mixed[] $context The log context
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $level
|
||||
*/
|
||||
public function log($level, $message, array $context = []): void
|
||||
{
|
||||
@@ -599,6 +620,9 @@ class Logger implements LoggerInterface, ResettableInterface
|
||||
/**
|
||||
* Delegates exception management to the custom exception handler,
|
||||
* or throws the exception if no custom handler is set.
|
||||
*
|
||||
* @param array $record
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
protected function handleException(Throwable $e, array $record): void
|
||||
{
|
||||
|
@@ -21,8 +21,10 @@ use Monolog\Logger;
|
||||
*/
|
||||
class GitProcessor implements ProcessorInterface
|
||||
{
|
||||
/** @var int */
|
||||
private $level;
|
||||
private static $cache;
|
||||
/** @var array{branch: string, commit: string}|array<never>|null */
|
||||
private static $cache = null;
|
||||
|
||||
/**
|
||||
* @param string|int $level The minimum logging level at which this Processor will be triggered
|
||||
@@ -32,6 +34,9 @@ class GitProcessor implements ProcessorInterface
|
||||
$this->level = Logger::toMonologLevel($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
// return if the level is not high enough
|
||||
@@ -44,6 +49,9 @@ class GitProcessor implements ProcessorInterface
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{branch: string, commit: string}|array<never>
|
||||
*/
|
||||
private static function getGitInfo(): array
|
||||
{
|
||||
if (self::$cache) {
|
||||
|
@@ -16,6 +16,7 @@ namespace Monolog\Processor;
|
||||
*/
|
||||
class HostnameProcessor implements ProcessorInterface
|
||||
{
|
||||
/** @var string */
|
||||
private static $host;
|
||||
|
||||
public function __construct()
|
||||
@@ -23,6 +24,9 @@ class HostnameProcessor implements ProcessorInterface
|
||||
self::$host = (string) gethostname();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
$record['extra']['hostname'] = self::$host;
|
||||
|
@@ -26,19 +26,21 @@ use Monolog\Logger;
|
||||
*/
|
||||
class IntrospectionProcessor implements ProcessorInterface
|
||||
{
|
||||
/** @var int */
|
||||
private $level;
|
||||
|
||||
/** @var string[] */
|
||||
private $skipClassesPartials;
|
||||
|
||||
/** @var int */
|
||||
private $skipStackFramesCount;
|
||||
|
||||
/** @var string[] */
|
||||
private $skipFunctions = [
|
||||
'call_user_func',
|
||||
'call_user_func_array',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string|int $level The minimum logging level at which this Processor will be triggered
|
||||
* @param string|int $level The minimum logging level at which this Processor will be triggered
|
||||
* @param string[] $skipClassesPartials
|
||||
*/
|
||||
public function __construct($level = Logger::DEBUG, array $skipClassesPartials = [], int $skipStackFramesCount = 0)
|
||||
{
|
||||
@@ -47,6 +49,9 @@ class IntrospectionProcessor implements ProcessorInterface
|
||||
$this->skipStackFramesCount = $skipStackFramesCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
// return if the level is not high enough
|
||||
@@ -97,7 +102,10 @@ class IntrospectionProcessor implements ProcessorInterface
|
||||
return $record;
|
||||
}
|
||||
|
||||
private function isTraceClassOrSkippedFunction(array $trace, int $index)
|
||||
/**
|
||||
* @param array[] $trace
|
||||
*/
|
||||
private function isTraceClassOrSkippedFunction(array $trace, int $index): bool
|
||||
{
|
||||
if (!isset($trace[$index])) {
|
||||
return false;
|
||||
|
@@ -19,6 +19,9 @@ namespace Monolog\Processor;
|
||||
*/
|
||||
class MemoryPeakUsageProcessor extends MemoryProcessor
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
$usage = memory_get_peak_usage($this->realUsage);
|
||||
|
@@ -19,6 +19,9 @@ namespace Monolog\Processor;
|
||||
*/
|
||||
class MemoryUsageProcessor extends MemoryProcessor
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
$usage = memory_get_usage($this->realUsage);
|
||||
|
@@ -20,8 +20,10 @@ use Monolog\Logger;
|
||||
*/
|
||||
class MercurialProcessor implements ProcessorInterface
|
||||
{
|
||||
/** @var int */
|
||||
private $level;
|
||||
private static $cache;
|
||||
/** @var array{branch: string, revision: string}|array<never>|null */
|
||||
private static $cache = null;
|
||||
|
||||
/**
|
||||
* @param string|int $level The minimum logging level at which this Processor will be triggered
|
||||
@@ -31,6 +33,9 @@ class MercurialProcessor implements ProcessorInterface
|
||||
$this->level = Logger::toMonologLevel($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
// return if the level is not high enough
|
||||
@@ -43,6 +48,9 @@ class MercurialProcessor implements ProcessorInterface
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{branch: string, revision: string}|array<never>
|
||||
*/
|
||||
private static function getMercurialInfo(): array
|
||||
{
|
||||
if (self::$cache) {
|
||||
|
@@ -18,6 +18,9 @@ namespace Monolog\Processor;
|
||||
*/
|
||||
class ProcessIdProcessor implements ProcessorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
$record['extra']['process_id'] = getmypid();
|
||||
|
@@ -15,11 +15,16 @@ namespace Monolog\Processor;
|
||||
* An optional interface to allow labelling Monolog processors.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
interface ProcessorInterface
|
||||
{
|
||||
/**
|
||||
* @return array The processed record
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
* @phpstan-return Record
|
||||
*/
|
||||
public function __invoke(array $record);
|
||||
}
|
||||
|
@@ -41,8 +41,7 @@ class PsrLogMessageProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $record
|
||||
* @return array
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
|
@@ -18,13 +18,20 @@ namespace Monolog\Processor;
|
||||
*/
|
||||
class TagProcessor implements ProcessorInterface
|
||||
{
|
||||
/** @var string[] */
|
||||
private $tags;
|
||||
|
||||
/**
|
||||
* @param string[] $tags
|
||||
*/
|
||||
public function __construct(array $tags = [])
|
||||
{
|
||||
$this->setTags($tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $tags
|
||||
*/
|
||||
public function addTags(array $tags = []): self
|
||||
{
|
||||
$this->tags = array_merge($this->tags, $tags);
|
||||
@@ -32,6 +39,9 @@ class TagProcessor implements ProcessorInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $tags
|
||||
*/
|
||||
public function setTags(array $tags = []): self
|
||||
{
|
||||
$this->tags = $tags;
|
||||
@@ -39,6 +49,9 @@ class TagProcessor implements ProcessorInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
$record['extra']['tags'] = $this->tags;
|
||||
|
@@ -20,6 +20,7 @@ use Monolog\ResettableInterface;
|
||||
*/
|
||||
class UidProcessor implements ProcessorInterface, ResettableInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $uid;
|
||||
|
||||
public function __construct(int $length = 7)
|
||||
@@ -31,6 +32,9 @@ class UidProcessor implements ProcessorInterface, ResettableInterface
|
||||
$this->uid = $this->generateUid($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
$record['extra']['uid'] = $this->uid;
|
||||
|
@@ -19,7 +19,7 @@ namespace Monolog\Processor;
|
||||
class WebProcessor implements ProcessorInterface
|
||||
{
|
||||
/**
|
||||
* @var array|\ArrayAccess
|
||||
* @var array<string, mixed>|\ArrayAccess<string, mixed>
|
||||
*/
|
||||
protected $serverData;
|
||||
|
||||
@@ -28,7 +28,7 @@ class WebProcessor implements ProcessorInterface
|
||||
*
|
||||
* Array is structured as [key in record.extra => key in $serverData]
|
||||
*
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $extraFields = [
|
||||
'url' => 'REQUEST_URI',
|
||||
@@ -39,8 +39,8 @@ class WebProcessor implements ProcessorInterface
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array|\ArrayAccess|null $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data
|
||||
* @param array|null $extraFields Field names and the related key inside $serverData to be added. If not provided it defaults to: url, ip, http_method, server, referrer
|
||||
* @param array<string, mixed>|\ArrayAccess<string, mixed>|null $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data
|
||||
* @param array<string, string>|null $extraFields Field names and the related key inside $serverData to be added. If not provided it defaults to: url, ip, http_method, server, referrer
|
||||
*/
|
||||
public function __construct($serverData = null, array $extraFields = null)
|
||||
{
|
||||
@@ -69,6 +69,9 @@ class WebProcessor implements ProcessorInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
// skip processing if for some reason request data
|
||||
@@ -89,6 +92,10 @@ class WebProcessor implements ProcessorInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $extra
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function appendExtraFields(array $extra): array
|
||||
{
|
||||
foreach ($this->extraFields as $extraName => $serverName) {
|
||||
|
@@ -51,6 +51,7 @@ class Registry
|
||||
* @param string|null $name Name of the logging channel ($logger->getName() by default)
|
||||
* @param bool $overwrite Overwrite instance in the registry if the given name already exists?
|
||||
* @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists
|
||||
* @return void
|
||||
*/
|
||||
public static function addLogger(Logger $logger, ?string $name = null, bool $overwrite = false)
|
||||
{
|
||||
@@ -122,7 +123,7 @@ class Registry
|
||||
* Gets Logger instance from the registry via static method call
|
||||
*
|
||||
* @param string $name Name of the requested Logger instance
|
||||
* @param array $arguments Arguments passed to static method call
|
||||
* @param mixed[] $arguments Arguments passed to static method call
|
||||
* @throws \InvalidArgumentException If named Logger instance is not in the registry
|
||||
* @return Logger Requested instance of Logger
|
||||
*/
|
||||
|
@@ -22,10 +22,14 @@ use ReflectionExtension;
|
||||
*/
|
||||
class SignalHandler
|
||||
{
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
/** @var array<int, callable|int> SIG_DFL, SIG_IGN or previous callable */
|
||||
private $previousSignalHandler = [];
|
||||
/** @var array<int, int> */
|
||||
private $signalLevelMap = [];
|
||||
/** @var array<int, bool> */
|
||||
private $signalRestartSyscalls = [];
|
||||
|
||||
public function __construct(LoggerInterface $logger)
|
||||
@@ -33,12 +37,21 @@ class SignalHandler
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function registerSignalHandler($signo, $level = LogLevel::CRITICAL, bool $callPrevious = true, bool $restartSyscalls = true, ?bool $async = true): self
|
||||
/**
|
||||
* @param int|string $level Level or level name
|
||||
* @param bool $callPrevious
|
||||
* @param bool $restartSyscalls
|
||||
* @param bool|null $async
|
||||
* @return $this
|
||||
*/
|
||||
public function registerSignalHandler(int $signo, $level = LogLevel::CRITICAL, bool $callPrevious = true, bool $restartSyscalls = true, ?bool $async = true): self
|
||||
{
|
||||
if (!extension_loaded('pcntl') || !function_exists('pcntl_signal')) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$level = Logger::toMonologLevel($level);
|
||||
|
||||
if ($callPrevious) {
|
||||
$handler = pcntl_signal_get_handler($signo);
|
||||
$this->previousSignalHandler[$signo] = $handler;
|
||||
@@ -57,7 +70,10 @@ class SignalHandler
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function handleSignal($signo, array $siginfo = null): void
|
||||
/**
|
||||
* @param mixed $siginfo
|
||||
*/
|
||||
public function handleSignal(int $signo, $siginfo = null): void
|
||||
{
|
||||
static $signals = [];
|
||||
|
||||
@@ -80,7 +96,7 @@ class SignalHandler
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->previousSignalHandler[$signo] === true || $this->previousSignalHandler[$signo] === SIG_DFL) {
|
||||
if ($this->previousSignalHandler[$signo] === SIG_DFL) {
|
||||
if (extension_loaded('pcntl') && function_exists('pcntl_signal') && function_exists('pcntl_sigprocmask') && function_exists('pcntl_signal_dispatch')
|
||||
&& extension_loaded('posix') && function_exists('posix_getpid') && function_exists('posix_kill')
|
||||
) {
|
||||
|
@@ -17,15 +17,23 @@ use Monolog\Formatter\FormatterInterface;
|
||||
|
||||
/**
|
||||
* Lets you easily generate log records and a dummy formatter for testing purposes
|
||||
* *
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
class TestCase extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @param mixed[] $context
|
||||
*
|
||||
* @return array Record
|
||||
*
|
||||
* @phpstan-param Level $level
|
||||
* @phpstan-return Record
|
||||
*/
|
||||
protected function getRecord($level = Logger::WARNING, $message = 'test', array $context = []): array
|
||||
protected function getRecord(int $level = Logger::WARNING, string $message = 'test', array $context = []): array
|
||||
{
|
||||
return [
|
||||
'message' => (string) $message,
|
||||
@@ -38,6 +46,9 @@ class TestCase extends \PHPUnit\Framework\TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return Record[]
|
||||
*/
|
||||
protected function getMultipleRecords(): array
|
||||
{
|
||||
return [
|
||||
|
@@ -54,8 +54,8 @@ class ErrorHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
public function fatalHandlerProvider()
|
||||
{
|
||||
return [
|
||||
[null, 10, str_repeat(' ', 1024 * 10), null],
|
||||
[E_ALL, 15, str_repeat(' ', 1024 * 15), E_ALL],
|
||||
[null, 10, str_repeat(' ', 1024 * 10), LogLevel::ALERT],
|
||||
[LogLevel::DEBUG, 15, str_repeat(' ', 1024 * 15), LogLevel::DEBUG],
|
||||
];
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user