ソフトウェア

リアルタイムアクセス可視化ツール「Hummingbird」を使ってみた


自分のウェブページやウェブサイトを持っている場合には、閲覧しているユーザーの動向をリアルタイムに知りたいと思うものです。GIGAZINEでもアクセスをリアルタイムに表示できないものかということで、最近公開されたツールの「Hummingbird」を使ってみました。

詳細は以下から。
mnutt/hummingbird @ GitHub

実際に使用してブラウザ上で棒グラフが表示されているムービーはこちら。横軸が時間で、縦軸がアクセス数を示しています。HTML5の技術であるWeb Socketを使用することで、50ミリ秒というきわめて短い間隔でのアクセス情報を表示することが可能です。

YouTube - リアルタイムアクセス可視化ツール「Hummingbird」


MITライセンスで配布されているHummingbirdではGoogle Chromeに搭載されているJavaScriptエンジンV8を用いたイベント駆動型サーバであるnode.jsキー・バリュー・ストア関係データベースの中間にあたるとされるドキュメント指向データベースであるMongoDBを用いて作成されています。

なお、ブラウザ上での表示にはWebSocketに対応しているGoogle ChromeかSafariが必要です。

■CentOSでの導入方法
1.まず、MongoDBをインストールします。/etc/yum.repos.dに次のような内容の10gen.repoというファイルを作成します。

[10gen]
name=10gen Repository
baseurl=http://downloads.mongodb.org/distros/centos/5.4/os/i386/
gpgcheck=0

そして、次のようにしてパッケージをインストールしてサービスを起動します。

yum --enablerepo=10gen install mongo-stable-server
service mongod start

2.続いて、Node.jsをインストールします。

wget http://nodejs.org/dist/node-v0.1.100.tar.gz
tar zxvf node-v0.1.100.tar.gz
cd node-v0.1.100
./configure
make
make install

3.gitでHummingbirdを取得します。

git clone git://github.com/mnutt/hummingbird
cd hummingbird
git submodule update --init
cd deps/express
git submodule update --init

4.configディレクトリにある設定ファイルapp.json.sampleをapp.jsonに改名します。なお、app.json.sampleは次のようなテキストファイルです。

{
  "name" : "Hummingbird",

  "monitor_port" : 8888,
  "tracking_port" : 8000,
  "websocket_port" : 8080,

  "username" : "admin",
  "password" : "change_this",

  "capistrano" : {
    "repository" : "git://github.com/mnutt/hummingbird.git",
    "hummingbird_host" : "hummingbird.your-host.com"
  }
}

5.「no method replace」エラーに対処するためにhummingbird/deps/express/lib/support/ejs/lib/ejs.jsを次のように変更します。

--- ejs.js.orig 2010-07-05 12:19:02.000000000 +0900
+++ ejs.js 2010-07-05 12:19:14.000000000 +0900
@@ -11,7 +11,7 @@
    new Function("locals",
      "var p=[],print=function(){p.push.apply(p,arguments);};" +
      "with(locals){p.push('" +
-       str
+       str.toString()
        .replace(/[\r\t\n]/g, " ")
        .split("<%").join("\t")
        .replace(/((^|%>)[^\t]*)'/g, "$1\r")

6.「no method queryString.parseQuery」エラーに対処するためにhummingbird/deps/express/lib/express/plugins/body-decoder.jsを次のように変更します。

--- body-decoder.js.orig 2010-07-09 13:49:32.000000000 +0900
+++ body-decoder.js 2010-07-09 13:49:54.000000000 +0900
@@ -22,7 +22,7 @@
      var request = event.request
      if (request.header('Content-Type') &&
          request.header('Content-Type').includes('application/x-www-form-urlencoded'))
-           request.params.post = queryString.parseQuery(request.body)
+           request.params.post = queryString.parse(request.body)
    }
  }
})


■実行
1.ローカルマシン上でHummingbirdを実行します。

node server.js &> log/hummingbird.log &
node monitor.js &> log/hummingbird_monitor.log &>

2.ブラウザから「http://Hummingbirdをインストールしたマシン:8888/」にアクセスすると、次のような画面が表示されるので、「USERNAME」に「admin」、「PASSWORD」に「edit_this」を入力してから「Login」をクリック。


3.次のようなアクセス情報表示ページが表示されます。左から右にアクセス数情報が流れていきます。グラフ上の少し明るめの灰色になっている区間が1秒です。


4.別のタブを開いて「http://Hummingbirdをインストールしたマシン:8000/」にアクセスします。トラッキング用にもちいる画像サイズが1×1の黒いドットが表示されます。このタブ上でリロードを繰り返します。Chromeなら1、2秒の間Ctrlを押したままRを押してください。


5.アクセス情報表示ページを再び見るとアクセスがあったことを示す縦棒が表示されます。画面を見て分かるとおり4秒程度の内容しか表示されませんので注意。なお、縦軸のスケールによって色が変化します。


■動作概要
動作概要を示したものが下の図です。アクセスを監視したサイトのHTMLファイルにトラッキング用のタグ<img src="http://Hummingbirdをインストールしたマシン:8000/">を埋め込んでおくと、このページを表示したときにHummingbirdがアクセスがあったことがわかります。Hummingbirdはそのアクセス情報を持っており、アクセス情報ページでこれをリアルタイム情報として閲覧することができます。


■パケットダンプ
ブラウザとサーバーとのWebSocketを用いたアクセスの様子を見るためにtcpick: a tcp stream sniffer, tracker and capturerを用いてパケットの内容を見てみました。用いたコマンドは次の通りです。

tcpick -t -h -yU -i lo 'port 8080'

結果は次のようになりました。今回はローカルマシン上でテストを行いましたので、127.0.0.1:42020がブラウザ側、127.0.0.1:http-altがWebSocket側となります。なお、出力は見やすいよう整形してあり、出力にはパケットサイズ0のものも実際には表示されていますがここでは省略しました。

Starting tcpick 0.2.1 at 2010-07-06 16:20 JST
Timeout for connections is 600
tcpick: listening on lo
setting filter: "port 8080"
16:20:34.826348 127.0.0.1:42020 S > 127.0.0.1:http-alt (0)
16:20:34.826949 1 SYN-SENT 127.0.0.1:42020 > 127.0.0.1:http-alt
16:20:34.827175 127.0.0.1:http-alt AS > 127.0.0.1:42020 (0)
16:20:34.827412 1 SYN-RECEIVED 127.0.0.1:42020 > 127.0.0.1:http-alt
16:20:34.828004 1 ESTABLISHED 127.0.0.1:42020 > 127.0.0.1:http-alt
16:20:34.828541 127.0.0.1:42020 AP > 127.0.0.1:http-alt (138)
GET / HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: 127.0.0.1:8080
Origin: http://127.0.0.1:8888
Cookie: not_secret=admin

16:20:34.830126 127.0.0.1:http-alt AP > 127.0.0.1:42020 (166) HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Origin: http://127.0.0.1:8888
WebSocket-Location: ws://127.0.0.1:8080/
16:20:34.831182 127.0.0.1:http-alt AP > 127.0.0.1:42020 (4)

16:20:34.847295 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:34.847844 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":0,"cartAdds":0}
16:20:34.848290 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:34.899853 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:34.900962 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":0,"cartAdds":0}
16:20:34.901875 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:34.943358 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:34.944887 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":0,"cartAdds":0}
16:20:34.945713 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:34.995478 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:34.996123 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":0,"cartAdds":0}
16:20:34.996935 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:35.043314 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:35.044116 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":0,"cartAdds":0}
16:20:35.044900 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:35.096556 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:35.096980 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":0,"cartAdds":0}
16:20:35.097295 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:35.143296 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:35.143700 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":2,"cartAdds":0}
16:20:35.144029 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:35.195554 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:35.196201 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":3,"cartAdds":0}
16:20:35.196581 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:35.244891 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:35.245252 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":3,"cartAdds":0}
16:20:35.245481 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:35.251985 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:35.252324 127.0.0.1:http-alt AP > 127.0.0.1:42020 (12) {"sales":{}}
16:20:35.252773 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:35.295527 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:35.296066 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":6,"cartAdds":0}
16:20:35.296353 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff>
 (中略)

16:20:39.443752 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:39.444226 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":2,"cartAdds":0}
16:20:39.444561 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:39.495396 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <00> 16:20:39.496518 127.0.0.1:http-alt AP > 127.0.0.1:42020 (24) {"total":1,"cartAdds":0}
16:20:39.496986 127.0.0.1:http-alt AP > 127.0.0.1:42020 (1) <ff> 16:20:39.499702 127.0.0.1:42020 AF > 127.0.0.1:http-alt (0)
16:20:39.500109 1 FIN-WAIT-1 127.0.0.1:42020 > 127.0.0.1:http-alt
16:20:39.539440 127.0.0.1:http-alt A > 127.0.0.1:42020 (0)
16:20:39.539860 1 FIN-WAIT-2 127.0.0.1:42020 > 127.0.0.1:http-alt

460 packets captured
1 tcp sessions detected

出力結果から、ブラウザ側からWebSocket側へコネクションを張った直後にWebSocket側からブラウザ側へコネクションを張っていることがわかります。

また、HummingBirdが送信するデータはWebSocketのプロトコル(データフレームの開始を0x00、終了を0xFFとし、その間にUTF-8のテキストが含まれる形式)に沿ったものであり、JSON形式でデータを送信していることが分かります。

HummingBirdはプレアルファ版ということで、手元の環境ではChrome上での閲覧中にタブが次のように表示されてしまいました。


また、インストール時にいくつかの修正が必要ということもあり、まだまだ発展途上ですがこれからに期待できるアプリケーションです。

この記事のタイトルとURLをコピーする

・関連記事
福岡で開催されたHTML5カンファレンスに参加してwebの新しい世界を体験してきました - GIGAZINE

モバイルページ向けの画像をリアルタイムで作成するために「lsyncd」を使ってみた - GIGAZINE

MRTGよりお手軽に負荷やトラフィックをグラフ化できる「Munin」 - GIGAZINE

Linuxのディレクトリ構造の一覧 - GIGAZINE

ブラウザシェアの移り変わりが一目で分かる図 - GIGAZINE

in ソフトウェア,   ネットサービス, Posted by darkhorse_log

You can read the machine translated English article here.