levacic / monolog-exception-with-context-processor
一个Monolog处理器,可自动从合适的异常中提取上下文
Requires
- php: ^7.4|^8.0
- levacic/exception-with-context: ^1.0
- monolog/monolog: ^2.2
Requires (Dev)
- phpunit/phpunit: ^9.5
README
此包处理通过日志记录的context
传递的异常,并将带有上下文的异常链提取到日志记录的extra
部分的一个键中。
链中包括所有链式异常,但上下文仅从实现ExceptionWithContext接口的异常中提取。
要求
- PHP >= 7.0
安装
composer require levacic/monolog-exception-with-context-processor
使用
配置
以下操作应在您通常配置日志基础设施的任何地方执行。
// Assuming a Monolog\Logger instance: $monolog->pushProcessor(new ExceptionWithContextProcessor());
这就是设置处理器所需的所有操作。
我为什么要这样做呢?
这个处理器本身相当无用了。使用它的主要好处是当也使用ExceptionWithContext接口来将附加上下文附加到异常时。
此处理器会检查日志记录上下文是否有exception
键设置,如果其值是异常(或者更确切地说,是Throwable
)。如果是,它将遍历该异常的链(使用$exception->getPrevious()
),并从链中每个实现ExceptionWithContext
的异常中提取上下文。
所有带有其上下文的异常链都将放置在日志记录的extra
部分的exception_chain_with_context
键中。每个异常都将有一个exception
键,它是异常的类名,以及一个context
键,它要么是异常返回的上下文(如果它实现了ExceptionWithContext
),要么是null
。
示例
假设以下异常类
<?php declare(strict_types=1); namespace App\Exceptions; use Levacic\Exceptions\ExceptionWithContext; use RuntimeException; use Throwable; class UserNotActivated extends RuntimeException implements ExceptionWithContext { /** * The ID of the non-activated user. */ private int $userId; /** * @param int $userId The ID of the non-activated user. * @param Throwable|null $previous The previous exception. * @param int $code The internal exception code. */ public function __construct(int $userId, ?Throwable $previous = null, int $code = 0) { parent::__construct('The user has not been activated yet.', $code, $previous); $this->userId = $userId; } /** * @inheritDoc */ public function getContext(): array { return [ 'userId' => $this->userId, ]; } }
现在假设你有一个$logger
,它是一个配置了此处理器的Monolog\Logger
实例。
// Create an exception chain where a RuntimeException wraps an instance of the // UserNotActivated exception. $exception = new RuntimeException( 'An error has occurred', 0, new \App\Exceptions\UserNotActivated(1234), ); $logger->error( $exception->getMessage(), [ 'exception' => $exception, ], );
此处理器会在日志记录的extra
部分添加一个新的键,如下所示
'exception_chain_with_context' => [ [ 'exception' => 'RuntimeException', 'context' => null ], [ 'exception' => 'App\Exceptions\UserNotActivated', 'context' => [ 'userId' => 1234 ], ] ],
这基本上允许你在记录任何东西的地方记录链中每个异常的上下文。这对于你只在文件中记录东西(尽管PHP应用程序此类日志的可读性通常令人怀疑)也是有用的,但它对于将日志记录到能够格式化和美观地显示与日志消息一起传递的附加信息的外部系统,或在日志数据上执行搜索/过滤/聚合来说是非常有帮助的。
许可证
此包是开源软件,根据[MIT许可证][LICENSE]授权。