CloudWatchに保存するログの費用を減らそう

CloudWatch Logsに保存されているログを移動する方法について記載した記事です。
2023.11.21

こんにちはクラスメソッドのスジェです。
普通AWS環境を運用しながらログを保存し活用するためにCloudWatchをよく導入します。
ですが時間がすぎてログにアクセスする頻度が少なくなって、ただログを保存するだけにCloudWatchを使うと他ストレージサービスより高い費用が発生することになります。
それでできれば長期間の保存が必要だったらS3にログを保存するケースが多いです。
今回はCloudWatchに保存するログが一定の時間がすぎたらS3に移動するようにしてAWSの費用を減らす方法について見てみます。

CloudWatchとS3の比較

単純に保存するためにはストレージサービスであるS3を利用し、保存以外の方向でも活用する場合はCloudWatchを利用することがいいと思われます。

費用

S3がストレージサービスであるため、保存費用だけだとS3より安いです。(東京リージョン基準)

サービス 費用 備考
S3 Standard USD 0.025/GB 最初の 50 TB/月
CloudWatch 0.033USD/GB 保存昨日だけ

また、長期間保存だけ必要な場合はS3 One Zone か Glacier に保存しますとより安く保存できます。

機能比較

S3だけ利用してS3に保存されたログを活用することは難しいです。
S3に保存されたログを検索去るためには AWS Athena を利用することで可能ですが、クエリの速度や追加費用なども問題もあります。
Athena を使用して Amazon S3 サーバーアクセスログを分析する方法を教えてください。

CloudWatchはログとメトリックの収集および活用のために導入するサービスであるため、CloudWatchだけでもログをいろんな方向で活用できます。
CloudWatch Logs Insightsを使うと Amazon CloudWatch Logs に保存されたログの会話型検索・分析もできます。
また、ロググループに保存されたログをフィルタリングしたりフィルタリングさらたログとメトリックを関連付けてアラートを発生させることも可能です。
Amazon CloudWatch の特徴

ログ保存費用の節約

結論的にログが保存以外で活用される期間までは CloudWatch に保存し、そのあとはS3に保存して費用を節約するのがいいと思われます。
ログ保存費用を節約するためには次の流れで作業を進めましょう。

  • CloudWatchとS3でのログ保存期間の検討
  • ログ移動作業実装
  • ロググループの保存期間設定
  • S3のライフサイクル設定(オプション)

まず、現状に合わせて CloudWatch から S3 へログの移動が必要なのか検討します。
移動することに決定されましたら各サービスで保存する期間を定義します。

期間検討が完了になりましたら移動方法につきまして検討し実装します。
実装できる方法として次になると思います。

  • CloudWatchのエクスポート機能を利用
  • AWS Lambdaを利用して移動
  • Kinesis Data Firehoseを利用して移動

それぞれ考慮すべきポイントが違うので状況に合わせて導入方法を選びましょう。

移動方法を実装できましたらCloudWatchのロググループ保存期間を変更します。
CloudWatch Logs でログデータ保管期間を変更する

必要におうじて一定期間が過ぎたログを S3 Standard から S3 One Zone や Glacier に移動する必要がありましたら S3 のライフサイクルを設定します。
S3 One Zone や Glacier に移動すると保存費用をお節約することができます。
バケットのライフサイクル設定の指定

CloudWatchのエクスポート機能を利用

まず、この方法について参考記事はこちらです。

CloudWatchはロググループを対象にしてS3にエクスポートする機能があります。
その機能を利用するためには次のIAM権限が必要になります。

  • logs:CreateExportTask
  • logs:CancelExportTask
  • logs:DescribeExportTasks
  • logs:DescribeLogStreams
  • logs:DescribeLogGroups

コンソールで手動としてS3に設定することも可能ですが、EventBridgeを利用して自動化することも可能です。

Evnet Bridgeを利用した自動化設定

前提は下記の通りです。

  • CloudWatchに保存するログの保存機関は30日
  • エクスポートのインターバルは「保存期間 - 1日」。つまり29日

S3バケット作成
ログを保存するバケットを作成し次のポリシーを追加します。
公式ドキュメントステップ 3: S3 バケットのアクセス許可を設定する を参考にしてポリシーを設定します。

EventBridgeに紐つくIAMポリシーおよびロール作成
上記の必要権限が含まれている IAMポリシー(Policies)を作成します。
続いて IAM ロール(Roles)を作成します。ロールを作成する際はカスタム信頼ポリシー(Custom trust policy)を選択して次のポリシーを追加します。
そして作成したポリシーと AmazonS3ReadOnlyAccess ポリシーを選択します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "scheduler.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

EventBridge 作成
定義的に動くようにスケジューリングするために EventBridge を作成します。
EventBridge のスケジュール(Schedules)から作成できます。

スケジュールは前提の通りに29日として指定し、フレックスタイムウィンドウ(flexible retention)はオフ(off)にします。
ターゲットは全てのAPI > CloudWatch Logs > CreateExportTask を選択します。
続いてターゲットロググループとバケットを指定するために次のjsonを「入力」に追加します。
Destination, LogGroupName は適切なバリューにします。
From과 Toは Unixtime と計算し2023年 1月 1日 0時 〜 2123年 1月 1日 0時が範囲として指定されています。
参考

{
  "Destination": "{bucket name}",
  "DestinationPrefix": "<aws.scheduler.scheduled-time>",
  "From": 1672498800000,
  "LogGroupName": "{export log group name}",
  "To": 4828172400000
}

続いて DLQ, 暗号化 などを必要に応じて設定し「既存の役割を選択」は作成したロールを指定します。

問題なければバケットにログが保存されていることが確認できます。1

考慮事項

ログ保存期間とエクスポートの期間を適切に調整つする必要があります。
例えばCloudWatch ログの保存機関は最小30日から設定できますが、毎月1日目にエクスポートするように設定しますと31日がある月は1日分のログが抜けます。
逆にログを60日間保存するのに毎月1日目に実行するように設定しますと抜けは発生しませんが、1ヶ月分のログが重複されます。

また、エクスポートで S3バケットにログを保存する場合はバケットの prefix までは指定できますが、バケットないの詳細な設定まではできません。
例えば Kinesis Firehose を利用したログ移動は年・月・日 と分けて保存されますが、CloudWatchのログエクスポートはそこまで詳細な設定はできません。

AWS Lambda を利用して移動

Lambdaを利用して定義的にログを読み、S3に保存することも可能です。

Lambdaを利用して設定方法

上記の EventBridge を利用して一定の期間ごとにログエクスポートしたように Lambdaを利用した方法も基本的に EventBridge を利用してスケジュールごとに Lambda を実行させる方法です。
目的によってコードは変わりますのでコード作成に参考になる記事を紹介します。

上記の記事は1日単位で移動するように設定するコードですが、「from・from_ts、to・to_ts、today、yesterday」 などのパラメータと EventBridge のスケジュールを修正して希望するスケジュールで実行するよう変更することも可能です。

考慮事項

Lambda でログを移動するだいたいのコードが利用するAPIは非同期動作の create export を利用するためログの量によってタイムエラになる可能性もあります。
また、実行する期間が長くなるとログの量も増えますので、LambdaのLimit時間も変更する必要があります。

直接にコードを作成する方法であるため、バケットのprefixや移動期間などを30日じゃなくより小さい単位にするなど自由な設定ができます。

ですが、コードを作詞絵する必要がありこととコードによってメンテナンスが必要になる可能性があるデメリットもあります。
また、Lambdaを起動させるのでCloudWatchのエクスポートだけ利用する方法よりコストが高いです。

Kinesis Firehoseを利用して移動

Kinesisのサブスクリプションフィルター機能を利用して CloudWatch logs のデータロースなしにS3に移動する方法です。
設定方法は公式ドキュメントに記載されています。

考慮事項

Kinesis Firehoseがデータストリミングを目的にするサービスなので毎月1回起動するのが目的なら他の方法がいいと思います。

管理型サービスなのでLambdaよりは設定が楽です。
ですが、単純費用だけみると Lambda より少し高いのでコードの作成ができましたら、Lambdaを利用する方法がいいと思います。

その他トラブールシューティングは下記のドキュメントをご参照ください。

まとめ

以上でコストを節約するために CloudWatch Logs に保存されたログを移動する方法についてみてみました。
上記の[ログ保存費用の節約] で説明しました通りにログの移動だけではなくログへのアクセス頻度を考慮してS3のストレージタイプ変更もできれば、もっとコスト最適化することができます。

最後まで読んでいただきありがとうございました。
内容のフィードバックおよびタイプミスなどは must01940 gmail までお願いします。


  1. スケジュールを有効化した場合です。