背景
ブラウザからデータを受け取り、それをS3に保存するアプリケーションの構築をAWS ECS Fargateで行いました。
フロントはnginx + nodejsを利用しています。フロントはブラウザから受けとったデータを加工して標準出力に出力するだけの役割です。
データはログルーターのFireLensを経由して、Kinesis Data Firehoseに送られ、LambdaをS3に保存するようにしました。
構成は上記の画像のようになります。
実際にデータを送ってみると、S3に保存された1つのJSONが途中で分割され2行になってしまっていました。
原因の調査
Lambdaでの調査
Kinesis Data Firehoseから起動しているLambdaでは、FireLensから送られてくるデータの必要な箇所(logというキーで取得できるログ本体)のみを取得し、改行をつけるだけの処理を行なっていました。(Kinesisからのデータなので、Base64デコードエンコードは行なっています)
なぜ分割されるのかがわからないのですが、なにか法則性がないかを調査したところ、分割されたデータの前半の長さは必ず16384バイト(16K)ということがわかりました。
しかも、Kinesis Data Firehoseに送られてくるデータには、データ本体のlog
以外にも、partial_id
、partial_message
、partial_last
などのキーが含まれていました。
つまり、Kinesis Data Firehoseに入ってくる前にデータは分割されていたということです。
コンテナの調査
ECS Fargateで出力したデータを調査しました。nodejsアプリケーションから出力するデータをCLoudWatchで見てみると、その段階ですでに分割されていました。
ということはFireLensが原因ではないようです。
原因はDockerのロギングドライバの制限
調査の結果、原因はDockerロギングドライバの制限でした。1行あたり16Kが上限になっていて、現時点では変更できないようです。
https://github.com/moby/moby/issues/32923
まとめと次回予告
Dockerのロギングドライバの制限によってデータが16Kを超えると分割されてしまうということがわかりました。調べても意外と載っていないので、原因がわかるまで時間がかかりました。
次回はこの問題についてどう対応したかを記載したいと思います。