CloudWatchLogsでRailsアプリのログを表示してみた

## はじめに
Railsアプリケーションを運用しているEC2上のログを、CloudWatchで表示するまでの手順をまとめました。
公式ドキュメントをベースに細かい部分も説明していきます。

## CloudWatchLogsのメリット
* 複数のサーバーがあってもログを一箇所に集約して管理できる。一々複数のサーバーにssh接続する必要がない。
* EventBridgeなど他のAWSリソースとの連携が簡単。エラー発生したらSlackに通知することもできる。
* Logs Insightsを使って高度な検索ができる

![スクリーンショット 2021-12-20 15.48.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603209/88f761bd-a0eb-f909-fe76-60314f3f7b8a.png)

## 前提
* AWSアカウント作成済み
* EC2インスタンス作成済み
* OS: CentOS 7.6.1810

## 手順の概要
1. ポリシーとロールを作成
1. EC2にロールをアタッチ
1. EC2にCloudWatchエージェントをインストール
1. エージェント設定ファイルを修正
1. EC2にアクセスキーを登録
1. CloudWatchエージェントを起動

### ポリシーとロールを作成
まずはポリシーを作成
1. `IAM > ロール > ポリシーを作成` を選択
1. JSONタブを選択し以下テキストをペーストし、次のステップ：タグへ

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogStreams"
    ],
      "Resource": [
        "*"
    ]
  }
 ]
}
```
３. 何も入力せず、次のステップ：確認　へ
4. 名前と説明を `CloudWatchLogsPolicy`と入力し、ポリシーの作成


次にロールを作成
1. `IAM > ロール > ロールを作成` を選択
1. `ユースケースの選択` で `EC2` を選択し、次のステップ：アクセス権限へ
1. ポリシーの検索で先程作成した `CloudWatchLogsPolicy`を選択し、次のステップ：タグへ
1. 何も入力せず次のステップ：確認へ
1. ロール名とロールの説明に `EC2Role`と入力しロールを作成

### EC2にロールをアタッチ
1. `EC2 > インスタンス > (対象のインスタンス詳細画面) > アクション（画面右上） > セキュリティ > IAMロールを変更` を選択
1. IAMロールに先程作成した`EC2Role`を選択し保存

### EC2にアクセスキーを登録
EC2とAWSを連携させるためアクセスキーを登録します

```bahs
# EC2にssh接続後、設定ファイルを開く
vi ~/.aws/credentials

#アクセスキーとシークレットアクセスキーを記述する
[default]
aws_access_key_id = **********************
aws_secret_access_key = **********************
```



### EC2にCloudWatchエージェントをインストール
OSごとにインストール方法が違うので注意。
本記事ではCentOS7.6.1810へのインストール方法を紹介します。
その他OSにインストールしたい場合は公式を参考にしてください。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/QuickStartEC2Instance.html


```bash
# EC2インスタンスにssh接続した後、以下コマンドを実行

# setup用のシェルをダウンロード
curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -O

# setupシェルを実行
# 選択肢を問われたら適当に回答。後で設定ファイルを編集するので適当に答えて大丈夫です。
sudo python ./awslogs-agent-setup.py --region ap-northeast-1

# 上記コマンドでエラー出たらこちらを実行
sudo python3 ./awslogs-agent-setup.py --region ap-northeast-1
```


### エージェント設定ファイルを修正
EC2からCloudWatchLogsにログを送る際の設定ファイルを修正します
筆者はEC2上で運用しているRailsアプリケーションのログをCloudWatchLogsで見たかったので、以下の書き方になりました

```bash
# 設定ファイルであるawslog.confを開く
vi /var/awslogs/etc/awslog.conf

# ファイルの末尾に[/var/log/messages]から始まる部分があるのでそこを以下に書き換える
[/aws/ec2/hoge_production]
# 日付のフォーマット。お好きな形式で。
datetime_format = %b %d %H:%M:%S
# EC2インスタンスからCloudWatchLogsに送るログファイルを指定する。今回はhogeアプリのproduction.logを指定。
file = /var/www/applications/workspace/hoge/log/production.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name =/aws/ec2/hoge_production
```
エージェント設定ファイルの詳細知りたい人はこちら 
 https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AgentReference.html


### CloudWatchエージェントを起動
エージェント設定ファイルを修正したらエージェントを起動します

```bash
# サービス起動
sudo service awslogs start

# システム起動時に毎回自動でサービス起動したい場合はこちらも実行
sudo chkconfig awslogs on
```

### CloudWatchLogsを確認
`CloudWatch > Log groups > /aws/ec2/hoge_production(エージェント設定ファイルのlog_group_name) > Log stream`からログを確認

Railsアプリケーションから吐き出されるEC2上のログがCloudWatchLogsに表示されているはずです！
もしログが作成されていなかった場合はEC2上の`/var/log/awslogs.log`を見てデバッグしましょう


### 参考文献
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/QuickStartEC2Instance.html