FuelPHP1.8.2でログをCloudWatchLogsに保存する

AWSで動作させる際にログをCloudWatchLogsに保存する際の対応です。
従来のファイル出力と切り替えが行えるように対応します。

## 環境を整える

```bash
# version 1 の最新に変更します
# version 2 はFuelPHP 1.8.2 をインストールした際のライブラリでエラーが出ます
php composer.phar self-update --1
php composer.phar require aws/aws-sdk-php
# FuelPHP 1.8.2 の時は「1.18.x」だと思いますが、1.20が必要なのでバージョンを上げます
php composer.phar require monolog/monolog:1.20.0
# 他のライブラリとの兼ね合いで v1系の最新を使用
php composer.phar require maxbanton/cwh:v1.1.14
```

## FuelPHP - config

log周りの設定はconfig.phpにありますので、そちらに「log_driver」を追加します。

```fuel/app/config/config.php
   // ログ関連の場所に下記を追加
   // file/cloudwatchlogs
   'log_driver' => 'cloudwatchlogs',
```

下記はAWS用のconfigとして追加

```fuel/app/config/aws.php
<?php
/**
 * AWS関連の設定.
 */
return [
    'client' => [
        'credentials' => [
            'key'    => 'xxx',
            'secret' => 'xxx',
        ],
        'region'  => 'xxx',
        'version' => 'latest',
    ],
    'cloudWatch' => [
        'group'         => 'xxx',
        'retentionDays' => 365,
    ],
];
```

## 作成するログの読込設定

```fuel/app/bootstrap.php
Autoloader::add_classes([
    'Log' => APPPATH . 'classes/log.php',
    'Log_Driver' => APPPATH . 'classes/log/driver.php',
    'Log_Cloudwatchlogs' => APPPATH . 'classes/log/cloudwatchlogs.php',
]);
```

## ログクラス

```fuel/app/classes/log.php
class Log extends Fuel\Core\Log
{
    /**
     * デフォルトのドライバー
     */
    protected const DEFAULT_DRIVER = 'file';

    /**
     * driver.
     */
    protected static $driver = null;

    /**
     * _initをオーバーライド.
     */
    public static function _init()
    {
        $driver = Config::get('log_driver', self::DEFAULT_DRIVER);
        $class  = 'Log_' . ucfirst($driver);

        self::$driver = class_exists($class) ? $driver : self::DEFAULT_DRIVER;

        if (self::DEFAULT_DRIVER === self::$driver) {
            parent::_init();
        } else {
            self::$monolog = $class::instance();
            self::initialize();
        }
    }
}
```

```fuel/app/classes/log/driver.php
<?php

use Monolog\Logger;

/**
 * ログドライバー.
 */
abstract class Log_Driver
{
    /**
     * Monologのインスタンスを生成して返す.
     *
     * @return Logger Monolog
     */
    abstract public static function instance(): Logger;
}
```

```fuel/app/classes/log/cloudwatchlogs.php
<?php

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

/**
 * CloudWatchLogs.
 */
class Log_Cloudwatchlogs extends Log_Driver
{
    /**
     * instance.
     */
    public static function instance(): Logger
    {
        Config::load('aws', true);

        $profile     = Config::get('aws.client');
        $cloudWatch = Config::get('aws.cloudWatch');

        $client = new CloudWatchLogsClient($profile);
        $handler = new CloudWatch(
            $client,
            $cloudWatch['group'], // ロググループ名
            Fuel::$env, // ログストリーム名
            $cloudWatch['retentionDays'],
            10000
        );

        return (new Logger('app'))->pushHandler($handler);
    }
}
```

上記で対応は完了となります。
上記のように作成を行えば、開発環境はファイルに保存、本番環境はCloudWatchLogsに保存することが可能になります。

## 環境ごとに出力方法を切り替える

```fuel/app/config/development/config.php
<php

return [
   // 開発環境はファイルに保存
   'log_driver' => 'file',
];
```