Fargate のログを FireLens を通して、EC2 の Fluentd/td-agent に出力する

# 概要
AWS FireLens を利用して、Fargate に立ち上げた nginx から EC2 インスタンスに用意した td-agent にログを落とす構成を作ってみます。今回の例は ECS(Fargate) ですが、CPU Unit や Memory Limit 周り以外は設定としては ECS(EC2) でも同様です。

図示すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840/4894c949-9b76-11ac-1eb0-404421dccac6.png)

のような状態から、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840/89f7a25c-5825-3f22-93b3-46b1a44a4449.png)

のような構成を作ります。

# 構築
## Fargate で nginx が動作している状態
Task Definition は以下のようになっているはずです。

![image.png (155.0 kB)](https://img.esa.io/uploads/production/attachments/1672/2019/11/23/3044/89a61cb3-5bcc-4107-b9ec-e67fae5ac188.png)

![image.png (270.9 kB)](https://img.esa.io/uploads/production/attachments/1672/2019/11/23/3044/ead8a6b7-2dd9-47b4-8c0a-f2336e3c5143.png)


![image.png (108.5 kB)](https://img.esa.io/uploads/production/attachments/1672/2019/11/23/3044/03dd7b77-5cf9-4cf2-b393-30cc2564d2a0.png)

nginx コンテナは以下のようになっています。

![image.png (158.0 kB)](https://img.esa.io/uploads/production/attachments/1672/2019/11/23/3044/28ac3e44-699e-4b42-9591-839aa47724ec.png)

![image.png (132.9 kB)](https://img.esa.io/uploads/production/attachments/1672/2019/11/23/3044/c3a6dc7e-26fb-4789-ba3d-3b56dbad8fb6.png)

## FireLens の設定を入れる
Task Definition の設定で、 `Enable FireLens integration` にチェックを付けて `Apply` します。

![image.png (113.2 kB)](https://img.esa.io/uploads/production/attachments/1672/2019/11/23/3044/c3065677-9d0e-4a08-a771-e1abce389767.png)

すると、コンテナに log_router というコンテナが増えます(内部では用意されたイメージで fluentbit が動作します)

![image.png (72.5 kB)](https://img.esa.io/uploads/production/attachments/1672/2019/11/23/3044/39c2a164-5639-4f2a-9499-debacd4fb5e3.png)

**ログを出力する方のコンテナ(ここでは nginx)** 側で、ログをどう処理するかの設定を行います。今回は所定の fluentd が動作しているホストに forward したいので、以下のような設定を nginx コンテナに足します。
Log driver を `awesfirelens` にして、Name を `forward` にします。これでログの転送が行われます。Host と Port は今回用意するログの受け側のFluentd/td-agentのIPアドレス/ポートに設定します。

![image.png (67.4 kB)](https://img.esa.io/uploads/production/attachments/1672/2019/11/23/3044/85d7278a-c4f4-402d-b805-c7ba335c732a.png)

 ECS 側の設定はこれで完了です。
fluentd におけるログのタグは \<container name\>-firelens-* が FireLens に付与されます。この Task Definition だと、nginx-firelens-* というタグが付きます。

## td-agent をインストールした EC2 インスタンスを用意する
ログの受け側の EC2 インスタンスを作ります。
通常の Amazon Linux 2 でインスタンスを作成して、適切に security group を開けた後、以下のように設定を投入します。

### td-agent のインストール
```
# curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent3.sh | sh
# mkdir -p /var/log/firelens/nginx
# chown -R td-agent:td-agent /var/log/firelens/
```

### td-agent の設定
この設定により、転送されてきたログが  `/var/log/firelens/nginx.YYYYMMDD.log` に出力されます。

```/etc/td-agent/td-agent/conf
<source>
  @type forward
  @id input_forward
</source>

# FireLens の設定により、 nginx-firelens-* というタグで飛んでくるので、こうしておきます
<match nginx-firelens-*>
  @type file
  @id mdoi-nginx
  append true
  path /var/log/firelens/nginx
  time_slice_format %Y%m%d
  flush_interval 1s

  <format>
    @type single_value
    message_key log
  </format>
</match>
```

## 新しい Task Definition をデプロイする
受け側が設定できたので、Service で新しい Task Definition を展開すると、設定が反映されます。 td-agent 側の flush_interval にもよりますが、nginx にアクセスすると、すぐにアクセスログが `/var/log/firelens/nginx.YYYYMMDD.log` に出力され始めます。

# ハマったところ
- Fargate ではなく EC2 のクラスタで試した際にインスタンスの ECS Agent のバージョンが古いと正しく設定できないことがありました。 ECS Agent のバージョンは最新にしておきましょう。
- `Enable FireLens integration` したあと、何故か Task Definition がエラーで保存できないことがありましたが、 コンテナの設定を開いたり閉じたりしてみると解消します。エラーになったら試してみましょう。