S3にエクスポートされたCloudWatch LogsのファイルをGlueのCrawlerでETLしようとして轟沈した話

S3にエクスポートされたCloudWatch LogsのファイルをGlueのCrawlerでETLしようとして轟沈した話
目次

S3にエクスポートした CloudWatch Logs のログストリームをAWS GlueでETLしようと挑戦してみました。 結論から言うと、GlueのCrawlerでログをいい感じにパースできなかったので、失敗しました、という話です。

モチベーション

S3のファイルをETLしたい

Step FunctionsでCloudWatch LogsのロググループをS3へエクスポートする 」 の記事にて、 CloudWatch LogsのログストリームをS3へエクスポートしました。

次のステップとしては、データ分析しやすいようにETLしようというわけです。

ETLといえばGlue

AWS上でETL処理を行うのであれば、聞いたことがあるのはやはり AWS Glue でしょう。

Apache Sparkをベースとしており、せっかくだから使ってみたかったわけです。

やってみよう

以下のような構成で処理させようと考えていました。

architecture

基データのログフォーマット

CloudWatch LogsはログデータがJSONフォーマットになっていると、 JSON pathのような検索ができたり、ログを展開したときにpretty printしてくれるのでよく使ってしまいます。

cloudwatch_logs

今回処理させたいデータも、この JSONフォーマットのログをCloudWatch Logsのエクスポート機能でS3にファイル出力したもの です。

Crawlerの設定でつまずく

AWS Glue と Amazon S3 を使用してデータレイクの基礎を構築する にも記載がありますが、 Glueには Crawler という設定があり、指定したデータソースの更新を確認し、データカタログを よしなに作ってくれる機能 があります。

ただ、どう「よしなに」作ってくれるかというと、 公式ドキュメント 記載の通り、テキストのフォーマット毎に指定のロジックがあり、それに準じて処理するデータ形式を判断しているようです。

これを見て 「よっしゃ、いい感じにJSONになるのね」 と早合点して、ポチポチ設定を進めていったのが問題でした。

ログフォーマットが変わっている?

Crawlerが S3バケットのファイルからデータカタログを作成してくれたわけですが、以下のように 「ion でした」 という結果が出てきました。

ion

「あれ?jsonではないの?」

そう思って、S3上の .gz ファイルの中身を見てみると以下のような形式になっていました。

12018-05-27T00:00:00.107Z {ログのJSON文字列}
22018-05-27T00:01:36.107Z {ログのJSON文字列}
3(以下略)

CloudWatch Logsからログデータをエクスポートすると、タイムスタンプ情報も出力されてしまい、 JSON形式でなくなっていた わけですね。

Grokも模索してみたが。。

Crawlerがログファイルを分類するために、自前の カスタム分類子 を設定することもできます。

crawler_classifier

  • Grok
  • XML
  • JSON

の3つが定義されているのですが、XMLとJSONはすでにテキスト形式がそのフォーマットに加工されている必要があるので、使えそうにありません。 よく Log Stash などで使われる Grok形式 が一番カスタマイズ性が高いのですが、この設定を用いても 要素が可変になるJSONを処理することはできませんでした。

サポートにも相談してみたが。。

「私のGlueの設定が悪いのかも」と一縷の望みを託して、AWSのサポートにも聞いてみたのですが、「Glue単体で今回のログフォーマットは処理できない」と回答をいただきました。

まとめ

GlueのCrawlerでいい感じにデータカタログを作るのに失敗しました。

デフォルトの分類子、または、自前で定義したカスタム分類子によってGlueのCrawlerはデータカタログを作成してくれます。 しかし、すべてのフォーマットに対して柔軟に処理できるわけではないので、フォーマットによってはGlueが処理しやすいように前段で自前ETLを挟んであげる必要がありそうです。

特に今回のような、 CloudWatch LogsのログがJSON形式で、エクスポート機能でS3に外出ししたファイル(ログの一部がJSON形式) の場合には相性が悪いということがわかりました。

参考にさせていただいたサイト