「Applibot Advent Calendar 2020」 7日目の記事になります。
前日は @kaz2ngt さんの goでデータの循環参照をチェックする(gonumパッケージ グラフ入門) という記事でした!
今回は、弊社のログ基盤「Dive」を使った分析要件の話になります。
Diveについて簡単に説明すると、Diveとはデータレイクという考え方を取り入れたログ基盤です。DiveのインフラはAWSを採用しているため、S3をデータレイクとして用いています。様々なプロジェクトから吐き出される行動ログはKinesisを経てこのデータレイクに流れ着きます。そしてアナリストやCS対応者などは、Redash,TableauといったBIツールを通してこのデータレイクにアクセスすることで目的の情報を得られるようになっています。
弊社のログ基盤の詳細については下記記事をご覧ください。
背景
新規開発において、ログから得られるデータの集計値が正しいかどうかを保証したいという課題がありました。BIツールなどでデータを参照して集計値をビジュアライズしたところ、それらしい数値は出てきたが本当にこれが正しいデータなのかどうかが分かりません。毎度プロジェクトのサーバーアプリケーションからログを吐き出して集計の確認をすることはかなり手間がかかるため、それを解決すべくログ吐き出しバッチを作成するに至ったというものです。
何をしたか
全API網羅シナリオをかけて1ユーザーの行動ログテンプレートを作成する
幸いにもこの課題に取り組むときに全てAPIを網羅するシナリオがあったのでこの選択肢を選ぶことができました。全てのAPIが叩かれることでほとんどの行動ログを出力することができました。仮にもしそれが選択できない状況下であれば、全てのAPIを網羅するようなユーザー行動シナリオを設計してそれを実行するという選択肢を取っていたと思います。
その際に流れたログをデータレイクであるS3から抽出してローカルに落とす
S3のAWSコンソールではディレクトリを丸ごとダウンロードすることはできないかつログの種類が数十あったため、aws s3コマンドを用いたスクリプトを作成することで簡単にダウンロードできるようになります。aws s3コマンドのサブコマンドであるcpやrmはかなり危険なコマンドなので実行前に--dryrun
オプションをつけて確認することがおすすめです。
前項で得たログの集合を1ユーザーの行動ログテンプレートとしてそれを複製するバッチプログラムを作成する
ユーザーIDや行動時日付などを適切に割り振ってテンプレートからログを複製します。
このバッチプログラムの作成にgolangを用いました。s3にアップロードする処理をgoroutineを用いて並列化することによって、バッチ処理時間を短くすることができました。
バッチをDockerイメージ化してAWS Batchにデプロイし、AWS Batchインスタンス上で複製した大量のログをS3にアップロードする
AWS Batchとはその名の通り、EC2インスタンス上でバッチを実行してくれるサービスです。使用したいDockerイメージと実行するコマンドを指定することで、バッチジョブを実行してくれます。これを用いることでAWSネットワーク内でログ転送が完結させることができます。
Dive集計バッチをAWS Batch上で走らせて集計データの確認をする
バッチから流した行動ログから得られる集計値と想定値が一致するかどうかを確認します。
何がよかったか
- 集計処理の速度計測ができるようになった
- バッチで吐き出すログ量を大量にすることでログ基盤アプリケーションの実行速度テストに使える
- アナリストのクエリのチェックに役立った
- Golangの知見を得ることができた
- Kotlinは多くの言語機能を持っているがgolangは比較的シンプルなイメージ
- ライブラリ周りのエコシステムがとても充実している
- 今回の場合、sirupsen/logrus, google/uuidが素敵でした!
- goroutineによる並列化で処理効率がアップすることを実感できた
まとめ
行動ログ吐き出しバッチを作成することによって、ビッグデータから得られる集計値の精度向上に役立ちそうです。
今回作ったところまででは全てのAPIを叩くようなシナリオに対して集計値が想定値と一致するかどうかのチェックができるようになりましたが、さらに精度向上を目指す場合は精度を向上させたい集計値が如実に現れるようなシナリオを考えて、そのシナリオに対する想定値を仮定し、バッチを実行してテストをするとよいのではと考えています。今後の展望として、このような様々なシナリオが存在する場合の汎用的な設計を目指しています。