dhs/cloudwatch-laravel-log

将日志推送到 CloudWatch 以支持 Laravel >= 9

dev-master 2024-03-16 03:34 UTC

This package is auto-updated.

Last update: 2024-09-16 04:37:03 UTC


README

此库通过 AWS PHP SDK 使用 AWS API,该 SDK 对并发请求有限制。这意味着在高并发或高负载的应用程序中,它可能无法以最佳方式工作。请考虑使用其他解决方案,例如使用 fluentd 将日志重定向到 stdout。

要求

  • PHP >=8.1
  • 具有适当权限的 AWS 账户(请参阅以下权限列表)

功能

  • 最多发送 10000 批次日志,以避免 速率超过 错误
  • 使用标签创建日志组
  • AWS CloudWatch Logs 员工懒惰加载
  • 适用于 Web 应用程序以及长时间运行的 CLI 守护程序和工作者

安装

通过运行以下命令使用 Composer 安装最新版本:

$ composer require dhs/cloudwatch-laravel-log:dev-master

基本 Laravel 使用方法

  • 创建一个名为 Logging 的文件夹,并创建一个名为 CloudWatchLoggerFactory.php 的文件
  • 指南链接: 指南
<?php

namespace App\Logging;

use Aws\CloudWatchLogs\CloudWatchLogsClient;
use Dhs\CloudWatchLogs\Handler\CloudWatch;
use Monolog\Logger;
use Monolog\Formatter\JsonFormatter;
use Monolog\Level;

class CloudWatchLoggerFactory
{
    /**
     * Create a custom Monolog instance.
     *
     * @param  array  $config
     * @return \Monolog\Logger
     */
    public function __invoke(array $config)
    {        
        // Instantiate AWS SDK CloudWatch Logs Client
        $client = new CloudWatchLogsClient($config['sdk']);

        // Instantiate handler (tags are optional)
        $handler = new CloudWatch(
            $client, 
            $config['group_name'],
            $config['stream_name'],
            $config['retention'], 
            10000,
            ['my-awesome-tag' => 'tag-value'],
            Level::Info
        );

        // Optionally set the JsonFormatter to be able to access your log messages in a structured way
        $handler->setFormatter(new JsonFormatter());

        $name = $config['name'] ?? 'cloudwatch';
        
        // Create a log channel
        $logger = new Logger($name);
        
        // Set handler
        $logger->pushHandler($handler);
        
        return $logger;
    }
}

配置使用

  • 打开 Laravel 应用程序配置文件夹中的 logging.php 文件,并添加以下配置代码
<?php
return [
    //...
    'channels' => [
        //....
        'cloudwatch' => [
            'driver' => 'custom',
            'via' => \App\Logging\CloudWatchLoggerFactory::class,
            'sdk' => [
                'region' => env('AWS_DEFAULT_REGION', 'eu-west-1'),
                'version' => 'latest',
                'credentials' => [
                    'key' => env('AWS_ACCESS_KEY_ID', ''),
                    'secret' => env('AWS_SECRET_ACCESS_KEY', ''),
                    // 'token' => '', // token is optional
                ]
            ],
            'retention' => 30,
            'level' => 'info',
            'group_name' => env('CLOUDWATCH_LOG_GROUP', 'group-log'),
            'stream_name' => env('CLOUDWATCH_LOG_STREAM', 'error-log'),
        ],
    ],
];

基本 PHP 使用方法

<?php

use Aws\CloudWatchLogs\CloudWatchLogsClient;
use Monolog\Logger;
use Monolog\Level;
use Monolog\Formatter\JsonFormatter;
use Dhs\CloudWatchLogs\Handler\CloudWatch;

$sdkParams = [
    'region' => 'eu-west-1',
    'version' => 'latest',
    'credentials' => [
        'key' => 'your AWS key',
        'secret' => 'your AWS secret',
        'token' => 'your AWS session token', // token is optional
    ]
];

// Instantiate AWS SDK CloudWatch Logs Client
$client = new CloudWatchLogsClient($sdkParams);

// Log group name, will be created if none
$groupName = 'php-logtest';

// Log stream name, will be created if none
$streamName = 'ec2-instance-1';

// Days to keep logs, 14 by default. Set to `null` to allow indefinite retention.
$retentionDays = 30;

// Instantiate handler (tags are optional)
$handler = new CloudWatch($client, $groupName, $streamName, $retentionDays, 10000, ['my-awesome-tag' => 'tag-value'], Level::Info);

// Optionally set the JsonFormatter to be able to access your log messages in a structured way
$handler->setFormatter(new JsonFormatter());

// Create a log channel
$log = new Logger('name');

// Set handler
$log->pushHandler($handler);

// Add records to the log
$log->debug('Foo');
$log->warning('Bar');
$log->error('Baz');

框架集成

以及其他许多框架

AWS IAM 需要的权限

如果您希望使用单独的程序 IAM 用户(推荐)或想定义策略,请确保包含以下权限:

  1. CreateLogGroup aws 文档
  2. CreateLogStream aws 文档
  3. PutLogEvents aws 文档
  4. PutRetentionPolicy aws 文档
  5. DescribeLogStreams aws 文档
  6. DescribeLogGroups aws 文档

当将 $createGroup 参数设置为 false 时,可以省略 DescribeLogGroupsCreateLogGroup 权限

示例 1:将日志写入日志组中的任何日志流

此策略示例允许将日志写入名为 my-app 的日志组中的任何日志流。日志流将自动创建。

注意:第一条语句允许创建日志组,当将 $createGroup 参数设置为 false 时,此操作不是必需的。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:DescribeLogGroups"
            ],
            "Resource": "arn:aws:logs:*:*:log-group:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:DescribeLogStreams",
                "logs:PutRetentionPolicy",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:log-group:my-app:*"
        }
    ]
}

示例 2:将日志写入日志组中的特定日志流

此策略示例允许将日志写入名为 my-stream-1my-stream-2 的特定日志流,这些日志流位于名为 my-app 的日志组中。日志流将自动创建。

注意:第一条语句允许创建日志组,当将 $createGroup 参数设置为 false 时,此操作不是必需的。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:DescribeLogGroups"
            ],
            "Resource": "arn:aws:logs:*:*:log-group:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:DescribeLogStreams",
                "logs:PutRetentionPolicy"
            ],
            "Resource": "arn:aws:logs:*:*:log-group:my-app:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:my-app:log-stream:my-stream-1",
                "arn:aws:logs:*:*:log-group:my-app:log-stream:my-stream-2",
            ]
        }
    ]
}