リモート開発メインのソフトウェア開発企業のエンジニアブログです

CloudWatch Logs を S3 にエクスポートする際オブジェクトのイベント通知が発生しない場合がある

CloudWatch Logs にはログを S3 にエクスポートする機能があるのですが、この機能を使ってログを S3 にアップロードした際、S3 バケットの s3:ObjectCreated:PUT イベント通知が発生しない場合があります。この様なケースでは、ログのエクスポートと同時に何らかの処理をそのログに行いたい場合に問題が起きます。

結論から書くと、(CloudWatch Logs のエクスポートに関わらず) S3 のオブジェクトアップロードを起点に当該のオブジェクトに処理を行う場合、設定するイベントは基本的には s3:ObjectCreated:* を設定したほうが良いです。

イベント通知の設定画面

S3 バケットにオブジェクトをアップロードする際、ファイルサイズによってアップロード方式が変わり、その結果実行されるイベント通知の種類も変わるからです。

以下、経緯と、アップロード方式の仕様を調査した結果をメモしますので興味のある方はご覧ください。

経緯

冒頭で話したとおり、 CloudWatch Logs に保存されているログを定期的に S3 バケットに移して、ついでにログの内容を加工すると言う仕組みを作っていた所、開発用の環境で検証していた時は動作したのですが、実際の運用環境では動かなかったと言う物になります。

この時、対象のバケットではオブジェクト作成時に処理用の Lambda 関数を実行する様にしており、イベントは 最低限の物のみ有効にしようと、当初 s3:ObjectCreated:Put だけを有効にしていました。

その後、一時的に s3:ObjectCreated:* を設定して Lambda との疎通確認等のデバッグを経て、アップロードされたオブジェクトのファイルサイズが一定以上であると、 s3:ObjectCreated:CompleteMultipartUpload イベントが通知されると言う事実にたどり着く事ができました。

開発様環境ではログのサイズが小さい為これでも問題がなく、よくある運用環境だけ動かない問題にハマり、気づくのに時間を要しました。

結局、今回のアーキテクチャの特性上、どの様なイベントであろうと当該バケットの指定した prefix 以下に作成されたオブジェクトは全て処理しても問題ないだろうと言う事で、先程の画像の通り s3:ObjectCreated:* を選択して、作成時は全てイベント通知する設定にしました。

実際にアップロード方式が変わるしきい値

では実際どのくらいの大きさのファイルをアップロードすると、イベントが s3:ObjectCreated:Put から s3:ObjectCreated:CompleteMultipartUpload になるのでしょうか?

興味が湧いたので調べてみたのですが、 SDK の実装言語によって違うみたいです。個人的によく使う AWS CLI のバックエンドになっている boto と、Ruby/Java/PHP での現時点でのサイズ (デフォルト値。変更可能) を比較してみました:

ライブラリmultipart になるしきい値 (デフォルト)
boto/s3manager (aws s3 cp コマンドのバックエンド)8MiB
aws/aws-sdk-ruby100MiB
aws/aws-sdk-java16MiB
aws/aws-sdk-php16MiB

肝心の CloudWatch Logs の ExportTask はどの様な設定になっているか分かりませんが、いずれにせよドキュメントでも明言されていなさそうなので、やはり素直に s3:ObjectCreated:* を指定しておくのが無難そうですね。

← 前の投稿

How to setup Scala and SBT on Docker?

次の投稿 →

Raspberry Pi は自宅ネットワークのゲートウェイにちょうど良い

コメントを残す