CloudWatchLogsからAthena向けにS3にデータを保存する時に改行を追加してあげないといけない
前回は、自分のミスでハマった話でしたが、その後、別の仕様にハマったのでそのメモです。以下あたりを参考に、CloudWatchLogsのログをAthenaで解析する流れを検証していました。
CloudWatchLogs -(Subscription Filter)->Firehose -(delivery stream)-> S3 <-Athena
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/partitions.html *1
無事S3までログを保存することはできたものの、Athenaでパーティションにデータをロードした後、selectしたら以下のエラーが出ました。
HIVE_CURSOR_ERROR: Row is not a valid JSON Object - JSONException: Expected a ':' after a key at 6 [character 7 line 1]
何だろうと思って色々調べていくと、どうやらJSONのログは1objectごとに改行されている必要があるとちらほら。
以下のように1つ1つのobjectが改行されている必要があるため1個のobjectだけを送る場合は末端に改行コードを入れる必要がある。
さらに調べると、2017年のBlackBeltのQAにそのままの答えがありました。 QA部分抜粋
Q8. Amazon Kinesis Firehose を利用してCloudWatch LogsをS3に転送してそれをAthena で分析したいのですが、Kinesis Firehoseを通すと{json}{json}のように1行に複数のJSONオブジェクトが保存されるようです。このデータを効率的にAthenaで分析するにはどういった方法がありますか?? A8. Amazon Kinesis FirehoseにはData TransformationをAWS Lambdaで行う機能がございますので,こちらを使って所望の形式に変換すると良いです.
どうやら、CloudWatchLogsから出すと、JSON Objectが改行なしで出力されるため、Athenaで解析するには、Lambdaを作って改行を追加してあげないといけないとのこと。ただ改行入れるためだけにLambda作らなければならないのは、とても面倒ですが、現状はこうするしかないようです。この辺りは、マイクロサービス同士で組み合わさっているゆえの噛み合わせの悪さなんでしょうか。せっかくマネージドで組み合わせられるので*2、この改行は自分でLambda作らなくてもできるようにはして欲しいところです。
参考
- Amazon Athenaのパーティションを理解する #reinvent | Developers.IO
- https://docs.aws.amazon.com/ja_jp/athena/latest/ug/partitions.html
- Kinesis Firehose & s3 & Athenaでビッグデータ処理! - Qiita
- CloudWatch LogsのログをRedshiftやAthenaで分析する - Qiita
- AWS Solutions Architect ブログ: AWS Black Belt Online Seminar「Amazon Athena」の資料およびQA公開