CloudWatchLogsのログをS3に転送する方法の比較

# はじめに
前回以下で各種ログの出力先をまとめていきましたが、CloudWatchLogsからS3にログを転送したいという場合にどのような方法をとるべきか今回記載していきたいと思います。

https://qiita.com/Regryp/items/1493e9e77836bf34c468

# なぜS3に転送するのか
そもそもなぜS3に転送する必要があるのかという疑問を持つ方がいるかもしれません。
CloudWatchLogsで保管もできるし、検索もできるのではないかと。
それはそのとおりなのですが、CloudWatchLogsのログ保管のコストはS3より高めに設定されており、純粋にログ保管をしたいだけであれば、S3に保存する（長期保管だけであればGlacier等）ことがおすすめです。
また、S3をデータレイクとし、各種データの分析等に利用するケースも考えられます。

# 方式
・手動でのS3エクスポート
・KinesisDataFirehoseを使ったS3エクスポート
・EventBridge＋LambdaでのS3エクスポート
・EventBridgeSchedulerでのS3エクスポート

上記４通りの手法があります。
１つずつ解説していきます。

## 手動でのS3エクスポート
以下のURLに記載がありますが、マネジメントコンソールまたはAWSCLI経由で、S3へのエクスポートを行う方法です。
あくまで手動なので、任意のタイミングでログをエクスポートするというケースで利用します。常にS3に転送したいというケースには不向きです。

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

## KinesisDataFirehoseを使ったS3エクスポート
以下のイメージです。
CloudWatchLogsのサブスクリプションフィルターにて、KinesisDataFirehoseを指定し、KinesisDataFirehose側ではターゲットとなるS3を指定します。

![スクリーンショット 2023-01-14 13.44.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/2d792a52-4952-b2b1-076b-fa8587552482.png)

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

本構成の特徴として、Lambda等でのコード管理が不要であり、お手軽に実施できるというメリットがあります。
また、KinesisDataFirehose側では、転送されてきたデータに対して、Lambdaと組み合わせることにより、S3へのエクスポート前にデータの変換を行うことができます。また、ほぼリアルタイムに転送できるというメリットもあります。
ただし、KinesisDataFirehose側ではバッファの設定が必要であり、指定した容量もしくは時間どちらかを経過した場合に、S3にログが出力されることとなります。そのため、ログファイルが細分化されてしまう可能性があります。
１日１ファイルのような構成にはできません。また、ロググループごとに出力先のS3バケットやプレフィックスを分けたい場合は、その分割単位でKinesisDataFirehoseのストリームを作成する必要があります。

## EventBridge＋LambdaでのS3エクスポート
EventBridgeからLambdaを呼び出しエクスポートする方法です。
![スクリーンショット 2023-01-14 14.04.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/b3102c4a-614b-e55b-ece4-e0766abf5679.png)

CreateExportAPIを利用することで、S3へのエクスポートが可能です。
KinesisDataFirehoseとは異なり、任意のタイミングでのログ転送となるため、リアルタイム性はありませんが、ファイルはエクスポートするタイミングでの生成となるため、分割したいレベルでエクスポートが可能です。
ただし、Lambdaのコード管理が必要とはなります。ログのデータ変換をしたい場合は、エクスポート後に別途変換を行う必要があります。

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/logs.html#CloudWatchLogs.Client.create_export_task


## EventBridgeSchedulerでのS3エクスポート
Lambdaを使わないとできない・・・と思っていたのですが、最近EventBeidgeSchedulerが公開され、AWS上のAPIを任意にたたけるようになったようです。もうLambdaいらないじゃん・・・・
Lambdaをどうしても使うケースとしては、プレフィックスに日付を入れたいなど、動的にカスタマイズする場合にかぎられますね。EventBeidgeSchedulerでCreateExportAPIを叩くだけなのでお手軽です。
特徴も前段で記載した内容と同じです。

![スクリーンショット 2023-01-14 14.14.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/4611ddd7-e776-d388-78e3-561635d4e0ea.png)

![スクリーンショット 2023-01-14 14.13.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/52d1bd6f-1dad-c968-7ea9-fe5ce9e222ea.png)

https://dev.classmethod.jp/articles/amazon-eventbridge-scheduler-new-way-to-launch-tasks/

# まとめ
エクスポート方法ごとにメリデメを整理しました。
要件に応じて適切に選択していきましょう。
また、エクスポートしたCloudWatchLogsに関しては、ライフサイクルルール等で定期的にログを削除しコストを抑えることをお忘れなく！

| エクスポート方法 | メリット | デメリット | 利用ケース |
| --- | --- | --- | --- |
| 手動でのS3エクスポート | 任意のタイミングで任意のS3バケットに出力できる | 手動なので、都度実施する必要がある | S3への常時転送が不要であり、一時的にログをS3にエクスポートしたい場合 |
| KinesisDataFirehoseを使ったS3エクスポート | コードの管理が不要。ほぼリアルタイムにエクスポート可能。エクスポート時にログの変換が可能。 | ログファイルが細分化する。出力先ごとにストリーム作成が必要。 | S3へのリアルタイム転送が必要な場合 |
| EventBeidge＋LambdaでのS3エクスポート | 指定したタイミングで自動的にS3に出力ができる。ログファイルの分割単位をコントロールできる。出力先プレフィックス等を動的にコントロールできる。 | コード管理が必要。リアルタイムに転送できない。 | リアルタイムな転送、転送時の変換が不要で、ファイルの分割単位、エクスポート先を動的にコントロールしたい場合 |
| EventBeidgeSchedulerでのS3エクスポート | 指定したタイミングで自動的にS3に出力ができる。ログファイルの分割単位をコントロールできる。コード管理が不要。 | エクスポート先を動的にコントロールできない。リアルタイムに転送できない。 | リアルタイムな転送、転送時の変換、エクスポート先を動的にコントロールすることが不要で、ファイルの分割単位をコントロールしたい場合 |