【EC2/Amazon Linux2】RailsアプリケーションのログをCloudWatchLogsに転送

# はじめに
Railsアプリケーションではデフォルトでlogsフォルダにログ情報を出力してくれます。
本番環境で運用している場合、EC2インスタンスを複数台用意して冗長構成としている場合が多いと思います。
その際、ログを確認するために各サーバーにSSH接続を行うのはとても面倒なため、１箇所に集約して確認することができるととても便利です。

本記事では、CloudWatchLogsを使って複数台の場合でも一括で確認する方法、またloglotateを使用した古いログの削除する設定を記載しています。

# CloudWatchLogsの設定

### IAMポリシーの作成

1 [IAM]-[ポリシー]-[ポリシーを作成] を選択
2 [JSONタブを選択] 以下テキストをペーストし、[次のステップ：タグへ]

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogStreams"
    ],
      "Resource": [
        "*"
    ]
  }
 ]
}
```

3 [タグを追加(オプション)]-[次のステップ:確認]
  ここでは特に入力の必要はありません
4[ポリシーの確認]--[ポリシーの作成]
  名前と説明を入力し、「ポリシーの作成」を押します。

### IAMロールの作成
1 [IAM]-[ロール]-[ロールを作成] を選択
2 [信頼されたエンティティを選択] 下記項目を選択し「次へ」を押す
- 信頼されたエンティティタイプ: AWSのサービス を選択
- ユースケース: EC2を選択

3 [許可を追加] IAMポリシーで作成したポリシーを選択を選択し「次へ」を押す
4 [ロールの詳細] ロール名と説明を入力し、「ロールの作成」を押す

### EC2にロールを設定
稼働している EC2を選択し、[アクション]-[セキュリティ]-[IAMロールを変更]から作成した
IAMロールを設定します。

### EC2でのRailsアプリケーションの構築
EC2上でRailsアプリケーションを構築していない場合、下記URLを参考に作成してください。
※構築済みであれば、スキップしてください。
https://qiita.com/yokku21/items/e7b324072c3963449423#ec2%E4%BD%9C%E6%88%90

### CloudWatchLogsエージェントのインストール

```
sudo yum update -y

sudo yum install -y awslogs
```

### 設定ファイルの修正
```/etc/awslogs/awscli.conf
[plugins]
cwlogs = cwlogs
[default]
region = ap-northeast-1
```

```/etc/awslogs/awslogs.conf
# 一番最後の行に追加
[application.log]
datetime_format = %b %d %H:%M:%S
file = /['railsアプリケーションディレクトリ']/log/development.log
buffer_duration = 5000
log_stream_name = application_log
initial_position = start_of_file
log_group_name = /aws/ec2/app
```

### CloudWatchLogsエージェントの起動

```
# サービス起動コマンド
sudo systemctl start awslogsd

# 自動起動設定コマンド
sudo systemctl enable awslogsd.service
```

### CloudWatchの確認
CloudWatchの画面から、ロググループを選択し、設定したログを確認します。

CloudWatchLogsの設定は以上です。

# loglotateの設定

### logrotateとは
複数のログファイルが際限なく増えてしまうことを防ぐために、一定の容量や期間ごとに古いログを圧縮、削除する機能です。

[【日本語man】logrotateの全オプション解説](https://hackers-high.com/linux/man-jp-logrotate/)

### Railsアプリケーションのログローテート設定
今回は、オプションに `copytruncate`を使用しています。
これは、copyの動作を行なった後、もとのログファイルの内容を消去するオプションです
Railsの再起動が不要になる代わりに、ログファイルが喪失するタイミングあるため注意が必要です。

```
/'railsアプリケーションディレクトリ']/log/*.log {
    create 0644 ec2-user ec2-user
    daily
    rotate 10
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
    endscript
    copytruncate
}
```

### CloudWatchLogsのログローテート設定
```
/var/log/awslogs.log {
    missingok
    notifempty
    size 100M
    create 0644 root root
    delaycompress
    compress
    rotate 4
    postrotate
        systemctl restart awslogsd
    endscript
}

```

# cron
logrotateのオプションcopytruncateを使用したデメリットを回避するため、本記事では深夜3:00ににローテーションを行うようにしています。
※ユーザーが使用しないであろう時間帯

```cron
0 3 * * * sudo /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.d/awslogs
0 3 * * * sudo /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.d/puma
```

logrotetaの設定は異常となります。

# 参考資料
https://qiita.com/kiiimiis/items/b9bc67922fb0baf37a1e#:~:text=logrotate(daily%2C%20weekly%2Cmonthly)%E3%81%AE%E5%AE%9F%E8%A1%8C%E3%82%BF%E3%82%A4%E3%83%9F%E3%83%B3%E3%82%B0&text=3%3A11%EF%BD%9E3%3A50,%E9%96%93%E3%81%AB%E5%AE%9F%E8%A1%8C%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82

chrono_logger gem の紹介しつつ Rails アプリのロギングを振り返る
https://qiita.com/ma2ge/items/1fba78a08e8d3b82b3c2#logger--logrotate

日本語man】logrotateの全オプション解説
https://hackers-high.com/linux/man-jp-logrotate/#copytruncate

時差計算
https://www.jisakeisan.com/?y=2022&m=3&d=24&hh=17&mm=30&t1=gmt&t2=jst

ログファイルを決まった時間に日別でローテートする方法
https://www.webolve.com/mainte/server/how-to-rotate-log-files-time-by-time/

第21章 システムタスクの自動化
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/ch-automating_system_tasks