JavaScript
MongoDB
JSON
PowerShell
c3.js

MongoDBのデータをPowerShellでJsonにし、C3.jsでグラフ化

More than 1 year has passed since last update.

MongoDBのデータをPowerShellでJsonにし、C3.jsでグラフ表示する。

色々な方法で溜めたMongoDBのデータを手っ取り早く見るため、C3.jsでグラフ化を試します。
たぶん世の中の流行的にはWebサーバ側はNode.jsなんかだと思いますが、Windowsが主な戦場の私は、とりあえずIIS上のPoweShellでJsonにします。
そのままPowerShellでデータと一緒にC3.js使っても表示可能なはずですが、仕組みを改良していく事を考えると、データ抽出と表示は分けておきたい。
なんだか結果的に全然手っ取り早くない気もしますが、客先のサーバはインストールが制限されるので、標準で使えるPowerShellが便利なんです。
(Webサーバの環境については、Windows2016TP4のIISでPowerShellをCGIとして動かす。参照方。)

ソフト等 バージョン 備考
Windows Server 2016 Technical Preview 4(Build 10586) 2012R2のHyper-V上で動作
PowerShell 5.0 2016TP4標準のまま
MongoDB 3.2.1 Windows 64-bit 2008 R2+ legacy
MongoDB .NET Driver 1.11.0
D3.js 3.5.14
C3.js 0.4.10

Jsonの出力を作る。

条件として、クエリーにマシン名を直接指定します。
(PoweShellでは、$ENV:QUERY_STRINGで取得可能。)
検索後、C3.jsで扱えるJsonにして出力します。

machineLog.ps1
##### 指定マシンのログをMongoDBからJsonで取り出し #####
# マシン名はクエリーで指定。
# ex: machuneLog.ps1?V3

write-host "Conten-type:application/json"
write-host ""

# ドライバ読み込み
$DRIVER_PATH = "C:\MongoDB\CSharpDriver-1.11.0";
Add-Type -Path "$DRIVER_PATH\MongoDB.Bson.dll";
Add-Type -Path "$DRIVER_PATH\MongoDB.Driver.dll";

# MongoDBの、logsデータベースの、osコレクションに接続
$client = New-Object MongoDB.Driver.MongoClient("mongodb://S2016TP4");
$server = $client.GetServer();
$db = $server.GetDatabase("logs");
$coll = $db.GetCollection("os");

# クエリーを作成して検索
$Q = [MongoDB.Driver.Builders.Query];
$query = $Q::EQ("ComputerName",$ENV:QUERY_STRING);
$mc = $coll.Find($query);

# 要素毎に格納する配列を用意
$TimeStamp = @();
$Processor_per = @();
$Network_byte = @();
$Disk_byte = @();

# ドキュメント毎に整形して格納
foreach($d in $mc) {
  $TimeStamp += ($d["TimeStamp"].ToLocalTime() | Get-date -UFormat "%Y-%m-%d %R");
  $Processor_per += $d["Processor_per"].ToInt32();
  $Network_byte += $d["Network_byte"].ToInt32();
  $Disk_byte += $d["Disk_byte"].ToInt32();
}

# まとめて、Jsonに変換して出力
@{
  TimeStamp = $TimeStamp;
  Processor_per = $Processor_per;
  Network_byte = $Network_byte;
  Disk_byte = $Disk_byte;
} | ConvertTo-json -Compress;

整形している辺りが納得いかないのですが、今はc3.jsの使い方もあまり分かっていないので、c3.jsに合わせる方向で整形しています。
出来れば整形せずに、c3.jsの設定とかで対応させたいところ。

machineLog.png

直接アクセスして表示されるのを確認できました。

C3.js(とD3.js)を配置。

あんまりこの手のライブラリ使った経験がないんですが、C3.jsは簡単そうなので、とりあえず使ってみます。
(仕事で高機能なの使う必要がありそうなんで、そうなったら切り替えていこうかな、と。)
c3.jsv0.4.10を、D3.jsv3.5.14を落としてきて、IISのwwwrootの下にlibフォルダを作って、必要なファイルだけ配置します。

表示してみる。

一部問題がありますが、表示そのものは簡単に出来たので、ここまででまとめ。

c3-graph.html
<!DOCTYPE html>
<html lang="ja">
<head>
<title>C3.js Graph</title>
<link href="/lib/c3.min.css" rel="stylesheet" type="text/css">
<script src="/lib/d3.min.js"></script>
<script src="/lib/c3.min.js"></script>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript">
var chart = c3.generate({
  data: {
//    x: 'x',
//    xFormat: '%Y-%m-%d %H:%M',
    url: '/cgi/machineLog.ps1?S2016TP4',
    mimeType: 'json',
    axes: {
        'Processor_per': 'y',
        'Network_byte': 'y2',
        'Disk_byte': 'y2'
    },
    hide: 'TimeStamp'
  },
  axis: {
//    x: {
//      type: 'timeseries'
//    },
    y: {
      label: 'processor(%)'
    },
    y2: {
      label: 'Network/Disk(byte)',
      show: true
    }
  }
});
</script>
</body>
</html>

このソースで、以下のようにグラフ表示できました。

c3.png

これだけでも、動的に表示を切り替えたりできるので、それっぽくは動くのですが、x軸の日時が日時として設定できていません。(ソース上コメントにしてある辺り。このコメントを外すとエラー。)
今後はマシン名を切り替えて表示したり色々出来るようにしていきたいので、それまでには目途を付けておきたいところ。