Laravel Vapor 自定义日志到 Amazon AWS Cloudwatch 作为 JSON

Laravel Vapor Custom Logs to Amazon AWS Cloudwatch as JSON

默认情况下Laravel Vapor 将laravel.log 文件推送到strerr 输出。这是由 Lambda 捡起并扔给 Cloudwatch 的。很难看透,除非你通过 Vapor UI 看。 寻找一种简单的方法来执行此操作并将它们直接推送到 Cloudwatch(包含多个文件)。

首先添加了这个很棒的库

composer require maxbanton/cwh 

然后将其添加到您的日志配置中...

        'cloudwatch' => [
            'driver' => 'custom',
            'via' => \App\Logging\CloudWatchLoggerFactory::class,
            'formatter' => Monolog\Formatter\JsonFormatter::class,
            'cloudwatch_stream_name' => 'laravel',
            'sdk' => [
                'region' => 'eu-west-1',
                'version' => 'latest',
                'credentials' => [
                    'key' => env('AWS_CW_ACCESS'),
                    'secret' => env('AWS_CW_SECRET')
                ]
            ],
            'retention' => 730,
            'level' => 'debug',
        ],

您需要为有权访问 Cloudwatch 的 IAM 用户添加 AWS_CW_ACCESSAWS_CW_SECRET 密钥。

然后添加App/Logging/CloudWatchLoggerFactory.php内容如下..

<?php

namespace App\Logging;

use Aws\CloudWatchLogs\CloudWatchLogsClient;
use Maxbanton\Cwh\Handler\CloudWatch;
use Monolog\Formatter\JsonFormatter;
use Monolog\Logger;

class CloudWatchLoggerFactory
{
    /**
     * Create a custom Monolog instance.
     *
     * @param  array  $config
     * @return \Monolog\Logger
     */
    public function __invoke(array $config)
    {
        $sdkParams = $config["sdk"];
        $tags = $config["tags"] ?? [ ];
        $name = $config["name"] ?? 'cloudwatch';
        
        // Instantiate AWS SDK CloudWatch Logs Client
        $client = new CloudWatchLogsClient($sdkParams);
        
        // Log group name, will be created if none
        $groupName = config('app.name') . '-' . config('app.env');

        // Log stream name, will be created if none
        // $streamName = config('app.hostname');
        $streamName = $config["cloudwatch_stream_name"];

        // Days to keep logs, 14 by default. Set to `null` to allow indefinite retention.
        $retentionDays = $config["retention"];
        // Instantiate handler (tags are optional)
        $handler = new CloudWatch($client, $groupName, $streamName, $retentionDays, 10000, $tags);
        $handler->setFormatter(new JsonFormatter());
        // Create a log channel
        $logger = new Logger($name);
        // Set handler
        $logger->pushHandler($handler);
        //$logger->pushProcessor(new CompanyLogProcessor()); //Use this if you want to adjust the JSON output using a log processor
        return $logger;
    }
}

然后您可以将其用作任何日志...即 Log::channel('cloudwatch')->info('hey');

要强制默认 laravel.log 到此处并在 vapor 中显示,只需将其添加为堆栈

        'vapor' => [
            'driver' => 'stack',
            'channels' => ['stderr', 'cloudwatch'],
            'ignore_exceptions' => false,
        ],

然后在您的环境变量中将 logging.default 设置设置为 vapor

如果您想要额外的日志记录通道,只需将 cloudwatch 通道设置复制一个新通道,并确保调整 cloudwatch_stream_name

感谢我在 Whosebug 上找到的另一个答案帮助我到达这里。我想直接在 Laravel Vapor 的答案下记录这个,因为我想很多其他人会在尝试这样做时遇到困难!