Google Data Studio で BigQuery ログを可視化してディレクターのデータ依頼から解き放たれる


この記事は「エムスリー Advent Calendar 2016」の 10日目の記事です

今年の5月に無償版が提供されている Google Data Studio ですが、使った人たちのコメントを見ているとドキュメントを読まなくても、いきなり使えるというメリットがあったものの、SQLを書けないというデメリットがあって、 他の無料ツールの Re:dash (無料だとサーバーが必要)の方がデータ分析的に使えるかなと思っていました。

しかし、最近この記事を読んでいて、逆に SQLクエリを書かなくて良い ということが (ディレクターに丸投げできるという意味で) 最大の魅力ということに気づきました。ということで、 Google Data Studio を使うことで、ディレクターがよく見たい指標ランキングTOPに挙がるであろうユーザーのアクセスログを可視化したので、ログ収集部分からまるっと解説します。

データの流れ

Web アプリサーバー (Heroku)のアクセスログ
-> fluentd サーバー (Heroku)
-> BigQuery
-> Google Data Studio

Web アプリサーバーのログ流し込み設定

※今回の例は Heroku で Rails アプリを運用しているパターンですが、ログを HTTP POST できば何でも大丈夫です。Heroku では log drains というものがあるのでそれで fluentd に流し込みます。
Log Drain| Heroku

今回は HTTP 通信で流し込む

# heroku で運用しているアプリから fluentd があるサーバーへログを転送
$ heroku drains:add https://my-fluentd-app.herokuapp.com/log -a myapp

これで、fluentd サーバーの /log へ POST してくれます。ログの内容は body の中にJSON形式で、message という key で入れられます。今回は Heroku にデフォルトである Heroku Router のログを使います。
body の中身はこんな感じ

{"message" : "262 <158>1 2016-12-06T23:00:32.420809+00:00 host heroku router - at=info method=POST path=\"/log?user_id=23&client=android\" host=myapp.herokuapp.com request_id=65e1bjkf-7le5-4a11-8236-ac24a3b71bb7 fwd=\"231.137.44.83\" dyno=web.1 connect=0ms service=8ms status=200 bytes=492\n"

本来は userid などのパラメータはクエリストリングではなく Http ヘッダーに入れて出力したかったのですが、Heroku Router に Http ヘッダーを出力する機能が見つからなかったので、今回はクエリストリングに入れました。。

BigQuery と GCP の登録

今回のストレージとなる BigQuery 及び Google Cloud Platform でのサービスアカウントの登録を事前に行っておきます。
※BigQuery はクエリのストレージとクエリ発行などが有料です
プラン
登録方法| Google

参考
データ分析基盤としての BigQuery 運用のベストプラクティス
FluentdでGoogle BigQueryにログを挿入してクエリを実行する

Fluentd サーバーを Heroku に立てる

流し込み先が Treasure Data だとこういったすごく便利なプラグインもあるのですが、今回はデータの送り先がBigQuery なので自前で fluentd 用のサーバーを Heroku に立てます

Fluentd プロジェクトを作成して Herokuに push

# Clone
$ git clone git://github.com/treasure-data/heroku-td-agent.git
$ cd heroku-td-agent
$ rm -fR .git
$ git init
$ git add .
$ git commit -m 'initial commit'

# Heroku 上にアプリ作成
$ heroku create --stack cedar 

$ git push heroku master

一旦これで heroku にアプリが立ち上がってるかを確認するとよいです。

次にBigQueryへログを流すために、以下のファイルを設定します。

Gemfile
gem 'fluentd', '~> 0.12.0'
gem 'fluent-plugin-td'
gem 'fluent-plugin-parser'
gem 'fluent-plugin-bigquery'
gem 'fluent-plugin-rewrite'
Procfile
# デフォルトだとここで fluentd への source 設定があるが td-agent.conf へ設定は寄せる
web: bundle exec fluentd --use-v1-config -c td-agent.conf
td-agent.conf
<source>
  @type http
  port "#{ENV['PORT']}" # herokuで自動設定される環境変数
  keepalive_timeout 10s
  format none # none にしないと heroku の router ログは読み取ってくれない
</source>

# heroku のログには「"」や「\\n」が混じっているので削除
<match access_log>
  @type rewrite
  add_prefix filetered
  <rule>
    key message
    pattern \"|\\n
    replace
  </rule>
</match> 

# ログをマッチパターンのみにフィルタ
<match filetered.access_log>
  @type parser
  key_name message
  tag bigquery
  format /\<.*\>\d (?<strtime>.+)\..* method=(?<method>.+) path=(?<path>.+)(\?|\&)user_id=(?<userid>.+)&client\=(?<client>.+) host=(?<host>.+) request_id=(?<request_id>.+) fwd=(?<fwd>.+) dyno=(?<dyno>.+) connect=(?<connect>.+) service=(?<service>.+) status=(?<status>.+) bytes=(?<bytes>.+)$/
</match>


# フィルタ後のログをBigQueryに送信
<match bigquery>
  @type bigquery

  method insert

  auth_method json_key
  # この値は GCP で使うservice account の値を入れる
  email [email protected]
  json_key ./yourprojectZZZZZZZ.json 

  # この値はBigQueryで設定した値を入れる
  project [YOUR_PROJECT]
  dataset [YOUR_DATASET]
  auto_create_table true
  table log%{time_slice} # 日付単位でテーブルはローテート

  time_field strtime
  field_string strtime,path,status,method,userid,client,fwd,service,bytes,host,request_id,dyno,connect

  buffer_path ./buffer/td
  buffer_chunk_limit 1m
  buffer_queue_limit 512
</match>

ローカルで Fluentd の挙動を試す

$ bundle
$ export PORT=8888
$ bundle exec fluentd -c td-agent.conf
$ curl -X POST -d "262 <158>1 2016-12-06T23:00:32.420809+00:00 host heroku router - at=info method=GET path=\"/my_page?user_id=23&client=android\" host=myapp.herokuapp.com request_id=65e1bdfa-72e5-4a11-8236-ac24a2b71bb7 fwd=123.137.16.73 dyno=web.1 connect=0ms service=8ms status=200 bytes=492"\
 http://localhost:8888/access_log

これで BigQuery 側にデータが挿入されていばOKです。

Google Data Studio で可視化する

ということでやっと Google Data Studio。ただしやることはあまりないです!
1. ログイン
2. レポートを新規作成

3.リソースを追加

4.ディメンションとメトリクスを選ぶ

5.完了

まとめ

ということであっという間にアクセスログを可視化し、あとはデータ分析をしたい人がガシガシ使えば良い環境をつくりました。
BigQuery はデータ量によっては多少お金がかかりますが(私の場合は3日使ったところでまだ0円) ほぼ無料でここまで簡単にアクセスログを可視化できるなんて感動ですね。