Skip to content

Commit

Permalink
[CE-44] Add analytics functions for user dashboard
Browse files Browse the repository at this point in the history
Include chaincode, fabric and infrastructure analytics functions.

Change-Id: Iacb15c14cd373bb7e47ea77b126ca05c42700365
Signed-off-by: lixucheng <lixucheng@aliyun.com>
  • Loading branch information
xuchengli committed May 15, 2017
1 parent 0aabffd commit da38561
Show file tree
Hide file tree
Showing 35 changed files with 2,245 additions and 0 deletions.
1 change: 1 addition & 0 deletions user-dashboard/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ app.use("/dashboard", require("./routes/dashboard/filter"));
app.use("/dashboard", require("./routes/dashboard/home"));
app.use("/dashboard", require("./routes/dashboard/chain"));
app.use("/dashboard", require("./routes/dashboard/contract"));
app.use("/dashboard", require("./routes/dashboard/analytics"));
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.send(err.message);
Expand Down
171 changes: 171 additions & 0 deletions user-dashboard/modules/analytics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/**
* Created by lixuc on 2017/5/12.
*/
var rp = require("request-promise");
var config = require("./configuration");
var dt = require("../kit/date-tool");

function analytics(chainId) {
this.chainId = chainId;
}
analytics.prototype = {
BaseURL: "http://" + config.RESTful_Server + config.RESTful_BaseURL,
overview: function() {
return new Promise(function(resolve, reject) {
rp({
uri: this.BaseURL + "analytics/overview?cluster_id=" + this.chainId,
json: true
}).then(function(response) {
if (response.success) {
resolve({
success: true,
statistic: {
health: response.result.health,
chaincodes: response.result.chaincode_number,
blocks: response.result.block_number,
runTime: dt.parse(response.result.run_time)
}
});
} else {
var e = new Error(response.message);
e.status = 503;
throw e;
}
}).catch(function(err) {
reject({
success: false,
message: (err.status == 503 && err.message) || "System maintenance, please try again later!"
});
});
}.bind(this));
},
chaincodeList: function() {
return new Promise(function(resolve, reject) {
rp({
uri: this.BaseURL + "analytics/chaincode/list?cluster_id=" + this.chainId,
json: true
}).then(function(response) {
if (response.success) {
var chaincodes = response.result.chaincodes;
resolve({
success: true,
chaincodes: chaincodes
});
} else {
var e = new Error(response.message);
e.status = 503;
throw e;
}
}).catch(function(err) {
reject({
success: false,
message: (err.status == 503 && err.message) || "System maintenance, please try again later!"
});
});
}.bind(this));
},
chaincodeOperations: function(id, timestamp) {
return new Promise(function(resolve, reject) {
var api = "analytics/chaincode/operations?cluster_id=" + this.chainId + "&chaincode_id=" + id;
if (timestamp) api += "&since_ts=" + timestamp;
rp({
uri: this.BaseURL + api,
json: true
}).then(function(response) {
if (response.success) {
var operations = response.result.operations;
for (var i in operations) {
operations[i]["formattedTime"] = dt.format(Math.round(operations[i].timestamp * 1000), 0);
}
resolve({
success: true,
operations: operations
});
} else {
var e = new Error(response.message);
e.status = 503;
throw e;
}
}).catch(function(err) {
reject({
success: false,
message: (err.status == 503 && err.message) || "System maintenance, please try again later!"
});
});
}.bind(this));
},
fabric: function(timestamp) {
return new Promise(function(resolve, reject) {
var api = "analytics/fabric?cluster_id=" + this.chainId;
if (timestamp) api += "&since_ts=" + timestamp;
rp({
uri: this.BaseURL + api,
json: true
}).then(function(response) {
if (response.success) {
var blocks = response.result.blocks;
for (var i in blocks) {
blocks[i]["formattedTime"] = dt.format(Math.round(blocks[i].timestamp * 1000), 0);
blocks[i]["parsedTime"] = dt.parse2Str(blocks[i].block_time);
}
resolve({
success: true,
health: response.result.health,
blocks: blocks
});
} else {
var e = new Error(response.message);
e.status = 503;
throw e;
}
}).catch(function(err) {
reject({
success: false,
message: (err.status == 503 && err.message) || "System maintenance, please try again later!"
});
});
}.bind(this));
},
infrastructure: function(size) {
return new Promise(function(resolve, reject) {
rp({
uri: this.BaseURL + "analytics/infrastructure?cluster_id=" + this.chainId + "&size=" + (size || 1),
json: true
}).then(function(response) {
if (response.success) {
var statis = [];
var statistics = response.result.statistics;
for (var i in statistics) {
statis.push({
cpu_percentage: statistics[i]["cpu_percentage"],
memory_usage: statistics[i]["memory_usage"],
memory_limit: statistics[i]["memory_limit"],
memory_percentage: statistics[i]["memory_percentage"],
block_read: statistics[i]["block_read"],
block_write: statistics[i]["block_write"],
network_rx: statistics[i]["network_rx"],
network_tx: statistics[i]["network_tx"],
avg_latency: statistics[i]["avg_latency"],
timestamp: statistics[i]["timestamp"].substr(11)
});
}
resolve({
success: true,
health: response.result.health,
statistics: statis
});
} else {
var e = new Error(response.message);
e.status = 503;
throw e;
}
}).catch(function(err) {
reject({
success: false,
message: (err.status == 503 && err.message) || "System maintenance, please try again later!"
});
});
}.bind(this));
}
};
module.exports = analytics;
25 changes: 25 additions & 0 deletions user-dashboard/public/css/dashboard/analytics.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@CHARSET "UTF-8";
.ds-analytics{margin-top:20px;font-family:"Helvetica Neue",Arial,sans-serif;}
.dropdown-button{background:#fff none repeat scroll 0 0;border:1px solid rgba(0, 0, 0, 0.1);}
.warning_link{color:#2d7091;border-bottom:1px dotted;}
.warning_link:hover{color:#2d7091;}
.perfect-health-circle{width:155px;height:155px;border:8px solid rgb(76, 175, 80);border-radius:50%;}
.good-health-circle{width:155px;height:155px;border:8px solid rgb(139, 195, 74);border-radius:50%;}
.attention-health-circle{width:155px;height:155px;border:8px solid rgb(255, 152, 0);border-radius:50%;}
.perfect-health-square{width:145px;height:140px;border:1px solid rgb(76, 175, 80);border-top-width:5px;padding:5px;}
.good-health-square{width:145px;height:140px;border:1px solid rgb(139, 195, 74);border-top-width:5px;padding:5px;}
.attention-health-square{width:145px;height:140px;border:1px solid rgb(255, 152, 0);border-top-width:5px;padding:5px;}
.perfect-label{color:rgb(76, 175, 80);font-size:35px;font-style:normal;font-weight:bold;}
.good-label{color:rgb(139, 195, 74);font-size:40px;font-style:normal;font-weight:bold;}
.attention-label{color:rgb(255, 152, 0);font-size:30px;font-style:normal;font-weight:bold;}
.vertical-line{width:1px;height:130px;border-right:1px solid #ccc;}
.font-size-15{font-size:15px;}
.font-size-20{font-size:20px;}
.font-size-50{font-size:50px;}
.health-label-box{width:100%;height:100%;margin-top:-15px;}
.invokeTimes, .responseTime{position:absolute;}
.empty{color:#b2b2b2;line-height:80px;font-style:italic;font-size:25px;}
.iconrefresh{position:absolute;width:20px;height:20px;top:50%;left:50%;margin-top:-10px;margin-left:-10px;}
.td-top-border{border-bottom:0;border-top:1px solid #ddd;}
.animation-td-div{position:relative;opacity:0;bottom:36px;}
.avgBlockTime, .minBlockTime, .maxBlockTime{margin-top:15px;}
Loading

0 comments on commit da38561

Please sign in to comment.