Treasure Data を使って開発者向けチャットアプリ AsakusaSatellite メッセージログの解析をしてみた

HerokuからTreasure Dataに標準出力でデータインポートできるようになって多幸感がすごい - ハードコイルド・ワンダーランド というエントリを見て、Treasure Data が導入の手間をこれだけ下げてくれているのに使わないのは失礼にあたる、ということで使ってみました。
また前提として、プロダクションコードには一切手を入れないということも意識しました。

構成

今回の構成は、すでに Heroku 上で動作している AsakusaSatellite に対して、Heroku 上に立てた bot (as-treasure-data-logger) が AsakusaSatellite API を定期的にキックして、データを JSON で標準出力に吐き続ける、という形にしました。

AsakusaSatellite の裏にいる MongoDB (MongoLab) を直接触ってもよかったのですが、API の使い勝手のテストも兼ねて API 経由にしています。

as-treasure-data-logger

as-treasure-data-logger は Heroku 上で動く bot として実装されています。
Treasure Data HadoopRedis To Go の2つの Heroku アドオンを追加しています。
Redis は最後に取得したメッセージの ID を覚えておくためだけに使っています。
この bot が定期的に AsakusaSatellite にメッセージ一覧を取得しに行き、標準出力に JSON を吐きます。
Treasure Data アドオンが有効になっていれば、標準出力が拾われてどんどんデータが溜まっていくという形です。

bot のコードが短いので貼っておきます。

#! /user/bin/env ruby
# -*- mode:ruby; coding:utf-8 -*-

require 'json'
require 'open-uri'
require 'redis'

$: << "."

ASAKUSA_SATELLITE_ENTRY_POINT = ENV["ASAKUSA_SATELLITE_ENTRY_POINT"]
ASAKUSA_SATELLITE_API_KEY = ENV["ASAKUSA_SATELLITE_API_KEY"]
ASAKUSA_SATELLITE_ROOM_ID = ENV["ASAKUSA_SATELLITE_ROOM_ID"]
REDIS_URL = ENV["REDISTOGO_URL"]
COUNT = 50

uri = URI.parse(REDIS_URL)
redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)

loop do

  since_id = redis.get("since_id")

  url = "#{ASAKUSA_SATELLITE_ENTRY_POINT}/message/list.json"
  url += "?api_key=#{ASAKUSA_SATELLITE_API_KEY}"
  url += "&room_id=#{ASAKUSA_SATELLITE_ROOM_ID}"
  url += "&count=#{COUNT}"
  url += "&since_id=#{since_id}" if since_id

  messages = []
  begin
    open(url) do |f|
      messages = JSON.load(f).map { |m| m["view"] = nil; m }
    end
  rescue => e
    warn e
  end

  messages.shift

  messages.each do |m|
    puts "@[heroku.message] " + m.to_json.gsub("\n", "")
    since_id = m["id"]
  end

  redis.set("since_id", since_id)

  sleep 300

end

必要な下準備などは README.md を参照してください。

Treasure Data でクエリを実行してみる

heroku td コマンドを使ってもいいのですが、
Heroku のアドオンページから Web インタフェースが使えるのでそちらを使ってみます。

アドオンページの 「Treasure Data」をクリックします。(コストが $0.00 なのも注目です。)
Heroku アドオンから Treasure Data を使った場合は、本家の Pricing よりかなりお得に使えます。
Treasure Data 社に感謝です。

ログインした直後の画面です。

Query をクリックして、クエリを打ち込み、Submit ボタンをクリックします。

クエリの実行には時間がかかるので、しばらく待ちます。

結果は TXT をクリックします。


banjun,8
suer,101
shimomura1004,64
mzp,68
atsumin,1
mallowlabs,107

Heroku 好きが誰かが一目瞭然です。
簡単ですね。

アクティビティ解析

AsakusaSatellite は開発者向けチャットアプリなので、開発のアクティビティが保存されています。
例えば Jenkins AsakusaSatellite Plugin を使っていれば、Jenkins のビルド結果がメッセージログに残っているはずです。

時間ごとのビルド回数を解析してみましょう。

Jenkins のビルド結果を拾うクエリを実行します。

SELECT
    SUBSTRING( v[ 'created_at' ] ,12 ,2 )
    ,COUNT( 1 )
  FROM
    message
  WHERE
    v[ 'body' ] LIKE '%SUCCESS%'
    OR v[ 'body' ] LIKE '%FAILURE%'
    OR v[ 'body' ] LIKE '%ABORTED%'
    OR v[ 'body' ] LIKE '%UNSTABLE%'
  GROUP BY
    SUBSTRING( v[ 'created_at' ] ,12 ,2 )

結果はこうなりました。

00,33
15,12
01,44
16,10
02,16
17,13
20,9
03,10
18,16
21,41
04,3
19,7
22,53
23,40
06,2
07,15
10,12
08,10
11,15
09,16
12,7
13,8
14,13

ソートして整形したものが以下です。

ビルド回数
00 33
01 44
02 16
03 10
04 3
06 2
07 15
08 10
09 16
10 12
11 15
12 7
13 8
14 13
15 12
16 10
17 13
18 16
19 7
20 9
21 41
22 53
23 40

深夜に偏った非常に不健康なチームであることがわかりましたねw
(言い訳をしておくと、メンバは全員本職が別にあるのです)

時間ごとだけでなく、曜日ごとに分析してみたり、
ビルドの結果ごとに分析してみても面白いかもしれません。

まとめ

Treasure Data の Heroku アドオンがとにかく手軽です。
今回は約 60,000 レコードと、Treasure Data 社さんには申し訳ないくらいの小さなデータで試しましたが、
データ件数が増えても実行時間がほとんど変わらないのを見ると、その威力に驚きます。
また、AsakusaSatellite に通知していたビルド結果も、使い方によっては面白いことが出来そうだということがわかって、夢が広がります。
AsakusaSatellite と Treasure Data はどちらも面白いことができるアプリですので、ぜひ試してみてください。