Fluentdでログ集約して、TitaniumMobile使ってiPhone上でグラフ表示
この前Fluentdの勉強会参加してお話を聞いたその翌日に
Fluentd→MongoDBでログ集約&加工してSinatraでJSONなデータ生成。 @goando さんが作ったグラフモジュール( bit.ly/MtoNau )使ってTitanium MobileでそのJSONデータをグラフ化するとか妄想してみた
— hiroshi oyamada (@h5y1m141) May 19, 2012
ということをつぶやいていました。折角妄想したので、ひとまず作ってみました。
サーバ側でJSON生成
Fluentdの設定はこんな感じにしました。
<source> type tail path /var/log/apache2/access.log tag apache.access format apache </source> <source> type tail path /var/log/auth.log tag syslog.access format syslog </source> <match **.access> # plugin type type mongo # mongodb db + collection database apache collection access # mongodb host + port host localhost port 27017 # interval flush_interval 10s </match>
上記設定で、MongoDBにログが集約されたので、JSONを生成するSinatraアプリをこんな具合にしました。
require 'sinatra' require 'mongo' require 'json' def connect_mongo(db,collection) db = Mongo::Connection.new("localhost", 27017).db(db) entries = db.collection(collection) return entries end def convert_to_json(items) items.each_with_index do |item,i| content_type :json body.push(item.to_json) end result = '[' + body.join(',') + ']' return result end get '/mongo' do access = connect_mongo('apache','access') items = access.find() return convert_to_json(items) end
Titanium Mobile+グラフモジュール使ってiPhone側でグラフ表示
以下2つをポイントに作成しました
- @goando さんが作成されたグラフモジュール(詳しくはこちら)があるのでそれを活用
出来たソースはこんな感じ
var win = Ti.UI.createWindow({backgroundColor:"#CCC"}); var _ = require('lib/underscore'); var Charts = require('com.gnddesign.prettycharts'); httpClient('http://website/mongo',function(result){ var statusCode200 = _.chain(result) .filter(function(item){return item.code ==='200';}).value(); var statusCode404 = _.chain(result) .filter(function(item){return item.code ==='404';}).value(); var statusCode500 = _.chain(result) .filter(function(item){return item.code ==='500';}).value(); var chartData = Charts.createChart({ leftChartType:0, leftChartColor:2, leftDataTitle:"status code", leftDataUnit:'件', leftDataArray:[statusCode200.length,statusCode404.length,statusCode500.length], width:320, height:480, top:0, left:0 }); win.add(chartData); win.open(); }); function httpClient(url,callback){ if(Titanium.Network.online===true){ var xhr = Ti.Network.createHTTPClient(); xhr.open('GET',url); xhr.onload = function(){ var result = JSON.parse(this.responseText); callback(result); }; xhr.error = function(){ var dialog = Ti.UI.createAlertDialog({ title: "ネットワーク接続エラー", message: "ネットワーク接続が確立されていません。再度お試しください" }); dialog.show(); myApps.ui.actInd.hide(); }; xhr.send(); }else{ var dialog = Ti.UI.createAlertDialog({ title: "ネットワーク接続できていません" }); dialog.show(); myApps.ui.actInd.hide(); } }
作ってみた感想とか課題
- あまり細かい条件抽出してないのでここまでは意外と簡単に出来た
- 時間帯別でログの表示をしたいので、MongoDB側でdb.apache.find({time:{$gt:xxx}})みたいな処理を考えないとダメ
- グラフをタッチした時に、関連の詳細情報を表示するView/TableViewへ画面遷移というようなことがprettychartsだと出来なそう?(間違っていたらゴメンナサイ)
- MarketPlaceにCharts Moduleがあって、15日間試用出来るけど、$29.99 /Seat /Month となんとなく高く感じる
当面やらないといけないことが多いけど、気が向いたら続きのエントリ書くかも