FluentBit × Kinesis × S3 でログ保存基盤を作る ~概要編~

# 概要
Fluent BitとAmazon Kinesis Data Firehoseを使って、サーバーからログをストリームし、S3に保存する基盤を作成したのでまとめました。
本編は概要編で、次の記事で実装編を書きます。

# ログを保存の方法は様々
ログには

* アプリケーションから吐かれるエラーログ
* アプリケーションから吐き出す障害調査用に備えたログ
* アプリケーションから吐き出すユーザー行動分析用のログ

などなど、用途に応じて様々なものがあるでしょう。

エラーログや障害調査用ログはAWSを使う場合、CloudWatch Agentをインスタンスに立てて、CloudWatchに吐き出すのが良くあるのではないでしょうか。

また、ユーザー行動分析用のログであればRDBにログ用のDBスキーマを作って保存したり、DynamoDBに保存したり、S3に保存したりなどがパターンとしてあるのかなと思います。

## ユーザー行動ログは結局どうするのが良いの？
### RDBに保存する
RDBを使っている場合、ユーザーデータと結合させて分析することを考えると、RDBにユーザー行動ログ保存するのがよくあるパターンですね。

しかし、スケールアウトしにくく、アプリケーションのボトルネックになりやすいRDBにログを保存するという手段は、どうしてもという理由がない限りはなるべく避けたいです。

RDBを使う理由としては、例えば

* 他のテーブルとjoinしなければならない
* 元々RDBを使っていて、急遽ログを取ることになったが、時間が足りずとりあえずRDBに突っ込む

あたりでしょうか。

ただ、前者のjoinしなければならない場合でも「ログに何を入れるか」の設計によってはある程度回避もできるのかなと思います。
この辺りを回避できれば、ログの保存先にRDBを使うという手段も無くなってきますね。

### ログ収集ツールを使ってRDB以外の場所に保存する
DBとは別の経路で保存するようにすれば、ボトルネックになりやすいDBへのconnectionを増やすことなくログを保存することができます。
例えば、パッと思いつくのはFluentd、FluentBit、Logstashなどのログ収集ツールを使って、Webサーバー内に吐かれたログを別の場所に送るという手段です。

ログ収集ツールのプロセスはWebサーバー上で動かすので、この部分はWebサーバーをスケーリングすれば負荷には対応できます。

そうすると、次に気にするべき点は収集先となるログの保存場所です。
ログの保存先として使うサービスにもいろいろありますが、今回は2つ紹介します。

#### Elasticsearch

保存場所をElasticsearchなどの全文検索エンジンに流すようにすれば、Kibanaを組み合わせるなどして柔軟なログの検索ができます。
ElasticsearchはAWSでもマネージドなサービスが出ているので、ログを別の場所に送る部分をWebサーバー側で意識するだけで、ログを保存する基盤が構築できますね。

#### S3
一方、S3に保存するという手段もあります。
S3だと下記のメリットがあるのかなと思います。

* Web開発において、AWS上にインフラを構築している場合に使用されるシーンが多く、追加の学習コストがかからない
* 料金コストが安価であり、数ヶ月や数年は使わないログをS3 Glacierに移動させることによって、さらに料金コストが減る
* 組織の都合で、「ログ分析用のAWSアカウントに既存のログを移動させたい」となった場合、AWS CLIを使ってクロスアカウントでも簡単に移行できる

S3にログを保存した場合は、AWSのマネージドサービスであるAthenaとGlueを組み合わせることで、SQLでログを検索、及び分析することができます。

今回はこちらのS3に保存する方を採用し、実装しました。

# 使用技術
保存先はS3と決まレバ、あとはS3までの経路を実現させるための技術選定です。

その経路の中で

* サーバーに吐かれたログを読み込み、AWS上の何かしらのサービスにログを送る
* AWS上でログをキャッチし、S3に書き込む

の2点を何かしらの技術で実現する必要があります。

普段はWebサーバーとして、DockerコンテナをECS上で動かしていたのでコンテナと相性が良いサービスを前提としました。

## Fluent Bit
![スクリーンショット 2020-04-25 19.35.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154121/fa756224-6a08-e7ed-c636-bb31953899fe.png)
https://fluentbit.io/

C言語で実装されたログ収集ツールです。
Fluentdと同じ類のツールですが、Fluentdよりも軽量でその分できることが少なくなっています。
FluentdとFluentBitの比較は[こちら]。(https://fluentbit.io/documentation/0.8/about/fluentd_and_fluentbit.html)

今回はログ収集ツールでは、ログが書き込まれたファイルからログを読み込み、AWSのマネージドなサービスにログを送ることさえできれば良かったのでFluentBitを使いました。

コンテナイメージが用意されていて、かつコンテナが軽量だったというのも選定理由の1つとしてありました。

## Amazon Kinesis Data Firehose
![スクリーンショット 2020-04-25 19.43.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154121/8f6ca3b0-7f4e-dfcd-ff85-16638f570186.png)
https://aws.amazon.com/jp/kinesis/data-firehose/

Webサーバーなどのデバイスから送られてきたデータをキャッチし、S3やRedshiftなどのデータストアに書き込むストリーミングサービスです。

Kinesisにはリアルタイムデータ分析用だったり、動画をストリーミングしたりなど、用途に応じたサービスがいくつかあります。
今回はリアルタイム分析は要件としてはなく、将来的に分析をかけられるようにS3にログを保存しておくというものでした。
そのため、データストアにログをストリーミングしてくれるだけのシンプルなAmazon Kinesis Data Firehoseを選定しました。

# アーキテクチャ
分析基盤も含め、下記の図のアーキテクチャとしました。
![スクリーンショット 2020-04-25 20.12.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154121/2e644117-0d1d-a424-05e5-866399681ded.png)

ECSでアプリケーションコンテナと、FluentBitのコンテナが動いていて、

1. アプリケーションコンテナにログが吐かれる
2. Fluent Bitがtailでファイルを監視し続け、ログファイルにログが吐かれたことを検知する
3. Fluent BitがKinesis Data Firehoseにログを送る
4. Kinesis Data FirehoseがS3にログを書き込む

~~ ここから分析基盤 ~~

1. GlueがS3からパーティションとしてログデータをロードする
2. ユーザーがAthenaを使ってGlueでロードされたデータにクエリをかける

と言った感じです。

ただし、今回は説明のためECSのホスト部分をローカル環境に置き換え、下記のアーキテクチャとします。
![スクリーンショット 2020-04-25 20.11.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154121/17c3ef52-97f8-8bbf-0409-1f12f7f86fff.png)

ECSの部分がローカルのDockerエンジンに置き換わった形です。

# 最後に
今回はFluentBit × Kinesis × S3でログ保存基盤を作るための概要とさせていただきました。
次回、実装編を書きたいと思います。