ApacheのログをCloudWatch Logsに保存する

# 概要
Apacheのエラーログを「CloudWatch Logs エージェント」を使用してCloudWatch Logsに保存します。
/var/log などに吐き出されるログをCloudWatchで管理できます。
オートスケールを使っていていると、EC2のtarminateによりログが失われる可能性があります。
そのため別の場所に保存しておく必要があります。

### 注意
現在「CloudWatch Logs エージェント」ではなく、「CloudWatch 統合エージェント」を使用することが推奨されています。
設定方法が違うのでご注意ください。

>CloudWatch Logs エージェントを使用して、Linux または Windows Server を実行する Amazon EC2 インスタンスのログデータおよび AWS CloudTrail から記録されたイベントを発行できます。代わりに CloudWatch 統合エージェントを使用してログデータを発行することをお勧めします。
> https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/UsePreviousCloudWatchLogsAgent.html

# 環境
- すべてAWSを使用
- OSはAmazon Linux 2
- Apacheのインストールはyumで行う

```
# cat /etc/system-release
Amazon Linux release 2 (Karoo)
```

# エージェントのインストール
エージェントがログをCloudWatch Logsに保存してくれますのでエージェントのインストールを行います。
インストールはyumで行い、導入されたコンフィグの初期値を表示させています。

```bash
# yum install awslogs
# cd /etc/awslogs/
# ls
awscli.conf  awslogs.conf  config  proxy.conf

# grep -v ^# awslogs.conf

[general]
state_file = /var/lib/awslogs/agent-state

[/var/log/messages]
datetime_format = %b %d %H:%M:%S
file = /var/log/messages
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/messages
```

# 設定方法
## EC2に権限を付与する

IAMロールを作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408925/2e7a1f8c-f8ee-a327-f5fc-a2228f75bade.png)

EC2で使用するのでEC2を選びます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408925/e41c731f-44cc-412e-98d1-7e769065fda7.png)

ロールの作成でCloudWatchLogsFullAccessの権限を付与します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408925/61792ea5-d7c9-3b43-f943-5d429d183742.png)

適当な名前をつけます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408925/fc40e72b-8eb7-1f7d-878e-f78fb64ca690.png)

EC2の画面に戻って先ほど作成したロールの割当を行います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408925/144218bc-038f-133e-7c15-c3d1295208a0.png)

## CloudWatch Logsの設定
### リージョンの指定
東京リージョンを使用しているのでap-northeast-1を指定します。

```
vi /etc/awslogs/awscli.conf
region = ap-northeast-1
```

### awslogs.conf の設定
まずは取り込みたいログのフォーマットを確認します
Apacheのエラーログです

```
[Sat Aug 10 16:54:37.292742 2019] [mpm_prefork:notice] [pid 3690] AH00163: Apache/2.4.39 () configured -- resuming normal operations
```

形式にあった設定を行います

```
[/var/log/httpd/error_log]
file = /var/log/httpd/error_log*
datetime_format = [%a %b %d %H:%M:%S.%f %Y]
buffer_duration = 5000
log_stream_name = {instance_id}_{ip_address}_Error
initial_position = start_of_file
log_group_name = Apache_log
#time_zone = LOCAL
```

- datetime_format
    - ログでどのような時間指定がされているかを指定します
    - [Sat Aug 10 16:54:37.292742 2019]　の部分と一致するようにしていします
    - フォーマットの指定は以下を参考にします
        - https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AgentReference.html
        - awslogs.conf の中に記載があります（今回見たタイミングでは上記URLより情報が多かった）
- log_stream_name
    - CloudWatchで見たときのフォルダ分けの設定です
    - 今回はインスタンスIDとIPアドレスを表示させるようにしました
- initial_position
    - ログデータの読み出し位置の指定
- log_group_name
    - 送信先ロググループの指定
    - ロググループの下にログストリームが作成されます
- time_zone 
    - EC2のタイムゾーンはJSTです。指定しなくても問題なさそうです

# 今回できなかったこと

accessログの時間が読み取れませんでした。
上記でエラーログのみを扱っているのはaccessログの設定がうまくできなかったからです。

アクセスログのフォーマット

```
127.0.0.1 - - [10/Aug/2019:16:39:30 +0900] "GET / HTTP/1.1" 403 3630 "-" "curl/7.61.1"
```

ログの取得自体はできますが、CloudWatchで認識した時間と実際のログの時間が一致しませんでした。
ログの読み込みに関する設定 multi_line_start_pattern をうまく指定すれば解決できるかもしれません。
もしくはJSTを諦め、全てUTCで管理するというのも手かもしれません。

## 更新履歴
### 2020/03/26 統合 CloudWatch エージェントについて追記しました