Elastic MapReduceで解析した結果を、D3.jsを使ってグラフ化してみたお話
ふりかえり
前回「Elastic MapReduceを使って、FluentdでS3上に格納した、Ltsv形式のNginxのアクセスログを解析してみたお話。」URL -> http://shinofara.hateblo.jp/entry/2013/09/15/000202
では、複数台のサーバで稼働するNginxのアクセスログを、Fluentdを使って回収して、S3上に格納して、 EMR(Elastic MapReduce)を使って、ログ解析をするという簡単ながれを書きました。
今回なぜ、Elastic MapReduceでの解析結果を使ってD3.jsの調査をしたのか
前回の解析結果のデータだけではパッと見てわかりにくかったりするので、 パッと見てわかりやすくする為に 今回は、前回解析したデータを、グラフしてみました。 ※テストデータの内容レベルなら、グラフ化は不要なのですが、調査ということで.....
ちなみにD3.jsとは
D3.js とは、
HTML や SVG、 CSSを使ってデータに命を吹き込みます。D3は WEB 標準に重点を置いており、強力な視覚化コンポーネントとデータドリブン (データ駆動型)DOM 操作手法の組み合わせにより、特定のフレームワークに縛られることなく、モダンブラウザの性能をフルに 引き出すことができます。 まとめると、svg,cssを使ってブラウザの性能をフルに使って、グラフを作成する。かな?まとめ過ぎかもしれません
実際にやる
使うデータは前回作成した、データと言いたいところですが、少し変更します。
といっても前回の
hive> CREATE EXTERNAL TABLE IF NOT EXISTS archiveLog (status int, cnt int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' LOCATION 's3://<バケット名>/archives/${DATE}'; OK Time taken: 0.197 seconds
を
hive> CREATE EXTERNAL TABLE IF NOT EXISTS archiveLog (status int, cnt int) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' LOCATION 's3://<バケット名>/archives/${DATE}'; OK Time taken: 0.197 seconds
に変更するだけですが、、どこが変わったの???
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' と変更する事で、区切り文字を, 改行文字を\nにする事が出来ます。 これはcsv形式で出力する為の設定です。
そして前回と同じようにhiveで、queryを実行します。(詳しくは前回の記事参照でお願いします。)
INSERT OVERWRITE TABLE archiveLog SELECT status, count(*) as cnt FROM fluentLog LATERAL VIEW json_tuple(fluentLog.json, 'ua', 'status') j AS ua,status WHERE pt >='2013-09-09' GROUP BY status;
するとS3上に以下の内容のcsvが書きだされます。 ※グラフの見た目がわかりやすくなる様に数字は変更しています。
200,210 302,60 400,36 404,20 500,70
ここまでの準備が出来たら後は、HTML,CSS,Javascriptを少し書くだけです。あと少し。
土台となるHTML
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-8" /> <title>sample1</title> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> </head> <body> <div id="graph"></div> </body> </html>
気になるjsの処理
jsを書く場所は
<script> ここにjsを記述 </script> </body>
キャンバス、色、レイアウト関連の定義
グラフを書くsvgのサイズなど定義
var width = 400, height = 300, radius = Math.min(width, height) / 2; ```` グラフの形、色定義 var color = d3.scale.ordinal() .range(["#F8D870","#E57F75", "#BE7AC3", "#8A9BCB", "#5AB0D2", "#56C8BB"]); var arc = d3.svg.arc() .outerRadius(radius - 10) .innerRadius(radius - 70); var pie = d3.layout.pie() .sort(null) .value(function(d) { return d[1]; }); var svg = d3.select("#graph").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
…このあたりは省略します。
メインとなるのはここから、
csvからデータを取得して、表示
本来は、 https://s3-ap-northeast-1.amazonaws.com/<バケット名>/archives/c516867a-c387-4fd4-9b16-697e3e3c6fa9_000000 というURLになるのですが、今回はこのファイルをgithub上にrenameして説明していきます。(URLが変わるだけですので、動きは同じ)
var data = []; (function(){ d3.text("https://rawgithub.com/shinofara/work/master/emr/csv/01.csv", function(csvFile) { var csvData = d3.csv.parseRows(csvFile); csvData.forEach(function(line) { //グラフの値は数値型なので、変換 line[1] = +line[1]; }); var g = svg.selectAll(".arc") .data(pie(csvData)) .enter().append("g") .attr("class", "arc"); g.append("path") .attr("d", arc) .style("fill", function(d) { return color(d.data[0]);}); //項目ごとのテキスト g.append("text") .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; }) .attr("dy", ".35em") .style("text-anchor", "middle") .text(function(d) { return d.data[0]; }); }); })();
グラフの見た目も大事!
<style> .arc path { stroke: #fff; stroke-opacity: .2; } body { font-size:10px; } </style>
簡単にですが、色をつけました。
簡単な調査を終えて
思った事
EMR + S3 + D3.jsを使っての、ログの可視化の説明だったので、処理説明等々は省略させていただきました。 そして、今回メインとなったD3.jsのjavascriptの書き方が少しハードルが高いかなーと思いましたが、 このくらいのグラフなら慣れれば簡単になるのかな? 複雑なグラフは、もっと難しいのかな?とか と思いました。
最後に一言
最後に、jsfiddleで公開した物をペタっ ※最近こういった検証には、jsfiddleを使ってます。。