cspray / marked-logs
一个PSR-3 Logger,确保所有日志都带有标识符,以便标记日志的上下文。
2.0.0
2023-03-10 18:43 UTC
Requires
- php: ^8.1
- psr/log: ^3.0
Requires (Dev)
- monolog/monolog: ^3.3
- phpunit/phpunit: ^10.0
- roave/security-advisories: dev-latest
README
提供PSR-3 Logger装饰器,确保每个日志消息都带有标识符,以便轻松分组类似的日志消息并找到所需的日志。
安装
Composer是安装此库的唯一支持方法。Composer
composer require cspray/marked-logs
使用指南
想象一个场景,当你与RESTful API交互并希望确保有详细的日志。Marked Logs提供了一种轻松分组这些日志的方法,以获得对与API交互的整体情况的了解。让我们看看一些示例代码。
<?php declare(strict_types=1); namespace Acme\MarkedLogsDemo; use Cspray\MarkedLogs\SelfDescribingMarker; use Cspray\MarkedLogs\MarkedLogger; use Psr\Log\LoggerInterface; use Psr\Http\Client\ClientInterface; // Make sure you make this a meaningful name! It will be what shows up as the marker in your logs class RestfulApiMarker extends SelfDescribingMarker {} class WidgetService { private readonly LoggerInterface $logger; public function __construct( private readonly ClientInterface $client, LoggerInterface $logger ) { // Here's the part where you actually interact with Marked Logs! $this->logger = new MarkedLogger(new RestfulApiMarker(), $logger); } public function fetch(string $id) : Widget { $this->logger->info('Fetching widget with id {id}', ['id' => $id]); // Rest of client interactions below $this->client->sendRequest( ... ); } public function update(Widget $widget) : Widget { $this->logger->info('Updating widget with id {id}', ['id' => $widget->id]); // Rest of client interactions below $this->client->sendRequest( ... ); } public function remove(Widget $widget) : void { $this->logger->info('Removing widget with id {id}', ['id' => $widget->id]); // Rest of client interactions below $this->client->sendRequest( ... ); } } // Now... let's use it! $service = new WidgetService( YourHttpClientFactory::create(), YourLoggerFactory::create() ); $widget = $service->fetch('1234'); $widget->withState(WidgetState::Done); $widget = $service->update($widget); $service->remove($widget); // Logged Messages and Context would look like // record 0: "Fetching widget with id 1234", ['id' => '1234', 'marker' => ['Acme\MarkedLogsDemo\RestfulApiMarker']] // record 1: "Updating widget with id 1234", ['id' => '1234', 'marker' => ['Acme\MarkedLogsDemo\RestfulApiMarker']] // record 2: "Removing widget with id 1234", ['id' => '1234', 'marker' => ['Acme\MarkedLogsDemo\RestfulApiMarker']]
现在,您可以通过在日志聚合器中搜索提供的Marker来查看与RESTful API交互的所有日志!
多个Marker
上面引入的RestfulApiMarker
已被证明非常有用,除了小部件之外的其他端点也开始使用它。如果您想了解API使用的整体情况,这很有帮助,但如果您只关心小部件,它可能会有些嘈杂。多个Marker可以帮助解决这个问题,您可以通过使用Cspray\MarkedLogs\CompositeMarker
对象来实现这一点!保持上面相同的Marker,我们将添加一个,并更新传递给MarkedLogger
的参数。
<?php declare(strict_types=1); namespace Acme\MarkedLogsDemo; use Cspray\MarkedLogs\CompositeMarker; use Cspray\MarkedLogs\Marker; use Cspray\MarkedLogs\MarkedLogger; use Cspray\MarkedLogs\SelfDescribingMarker; use Psr\Log\LoggerInterface; use Psr\Http\Client\ClientInterface; class RestfulApiMarker extends SelfDescribingMarker {} class WidgetApiMarker implements Marker {} class WidgetService { private readonly LoggerInterface $logger; public function __construct( private readonly ClientInterface $client, LoggerInterface $logger ) { // Here's the part where you actually interact with Marked Logs! $this->logger = new MarkedLogger( new CompositeMarker( new RestfulApiMarker(), new WidgetApiMarker() ), $logger ); } # rest of class as it appears above... }
现在,我们的Marker将包括提供的两个类名,允许您在API交互的更广泛的整体上下文中保留这些日志,并允许您进一步深入到特定的端点。
祝您日志记录愉快!