fotografde/logging

集成日志处理的常用方式。

3.0.1 2024-09-18 13:49 UTC

README

示例日志格式

{
  "@timestamp": "2022-07-06T12:28:54.571699+00:00",
  "@version": 1,
  "timestamp": 1657110534571,
  "host": "maually/automatic defined host",
  "environment": "prod",
  "app": "ServiceName",
  "message": "Something happened",
  "context": {
    "hello": "people"
  },
  "extra": {
    "system-id": "48446546"
  },
  "level": 200,
  "level_name": "INFO",
  "channel": "security",
  "entity.name": "newrelic_defined",
  "entity.type": "newrelic_defined",
  "hostname": "newrelic_defined",
  "trace.id": "newrelic_defined",
  "span.id": "newrelic_defined"
}

异常上下文

有时我们希望记录异常出现时或从其他地方获取的额外数据。在许多情况下,你需要添加额外的依赖项,即Logger。我们可以通过异常上下文来自动化这个过程。你可以创建自定义错误和规则,以从它们中提取上下文。请参阅ExceptionContext文件夹中的示例。

以下是一个Guzzle示例

class GuzzleRequestExceptionContext implements ExceptionContext
{
    /**
     * @return array{message?: string}
     */
    public function __invoke(RequestException $exception): array
    {
        if ($exception->getResponse() !== null && $exception->getResponse()->getBody() !== null) {
            return ['message' => $exception->getResponse()->getBody()->getContents()];
        }
        return [];
    }
}

!警告:它目前只与Symfony集成自动工作。如果你想,你总是可以为其他框架添加集成。

配置

Laravel

config/logging.php 文件的 channels 节中添加

        'gotphoto' => [
            'driver' => 'custom',
            'via' => new Gotphoto\Logging\Laravel\LaravelLoggerCreating,
            'app_name' => 'ServiceName',
            'channel' => 'app'(security/reauest/order),
            'processors' => [new Monolog\Processor\ProcessorInterface()], //OPTIONAL
            'level' => Monolog\Logger::INFO, //OPTIONAL
            'stream_to' => 'php://stderr', //OPTIONAL
        ]
        'security' => [
            'driver' => 'custom',
            'via' => new Gotphoto\Logging\Laravel\LaravelLoggerCreating,
            'app_name' => 'ServiceName',
            'channel' => 'security',
            'processors' => [new Monolog\Processor\ProcessorInterface()], //OPTIONAL
            'exceptionContexts' => [ //OPTIONAL
                RequestException::class => [new GuzzleRequestExceptionContext()],
                AwsException::class => [new AwsExceptionContext()],
            ], //OPTIONAL
            'level' => Monolog\Logger::INFO, //OPTIONAL
            'stream_to' => 'php://stderr', //OPTIONAL
        ],

不要忘记在同一文件中将其中一个设置为默认值: 'default' => env('LOG_CHANNEL', 'gotphoto'),

Symfony

添加包 Gotphoto\Logging\Symfony\SymfonyLoggingBundle::class => ['all' => true],;

添加配置 gotphoto_logging.yaml

symfony_logging:
 app_name: ServiceName

使monolog配置看起来像这样

<?php declare(strict_types=1);

use Gotphoto\Logging\Formatter;
use Gotphoto\Logging\OtelFormatter;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Config\MonologConfig;

return static function (MonologConfig $monolog, ContainerConfigurator $containerConfigurator): void {

    $monolog->handler('newrelic')
        ->type('stream')
        ->path('php://stderr')
        ->formatter(Formatter::class)
        // log start from info messages (debug is lowest level)
        ->level('info');
    $monolog->handler('otel')
        ->type('service')
        ->id(Handler::class)
        // log start from info messages (debug is lowest level)
        ->level('info');
    
};

其中最重要的部分是

NewRelic

        ->type('stream')
        ->path('php://stderr')
        ->formatter(Formatter::class)

Otel

        ->type('service')
        ->id(Handler::class)

异常上下文

在Symfony中自动工作。只需创建接口 Gotphoto\Logging\ExceptionContext\ExceptionContext 的实现并将其添加为服务(通常应该由 $services->load() 自动完成)。然后Symfony将自动开始为你使用它。