mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into mjmh
This commit is contained in:
commit
3dce782d5d
|
@ -8,7 +8,7 @@ What is ArangoDB? {#FirstStepsArangoDBIntro}
|
||||||
============================================
|
============================================
|
||||||
|
|
||||||
For installation instructions, please refer to the
|
For installation instructions, please refer to the
|
||||||
@S_EXTREF_S{InstallManual.html,installation manual}.
|
@S_EXTREF_S{InstallManual.html,installation manual}
|
||||||
|
|
||||||
ArangoDB is a multi-purpose open-source database with a flexible data
|
ArangoDB is a multi-purpose open-source database with a flexible data
|
||||||
model for documents, graphs, and key-values. You can easily build high
|
model for documents, graphs, and key-values. You can easily build high
|
||||||
|
@ -28,15 +28,15 @@ Key features include:
|
||||||
the performance power of NoSQL
|
the performance power of NoSQL
|
||||||
- *Application server*: Use ArangoDB as an application server and fuse your application and
|
- *Application server*: Use ArangoDB as an application server and fuse your application and
|
||||||
database together for maximal throughput
|
database together for maximal throughput
|
||||||
- *JavaScript for all:* No language zoo, you can use one language from your
|
- *JavaScript for all*: No language zoo, you can use one language from your
|
||||||
browser to your back-end
|
browser to your back-end
|
||||||
- *Flexible data modeling:* Model your data as combination of key-value pairs,
|
- *Flexible data modeling*: Model your data as combination of key-value pairs,
|
||||||
documents or graphs - perfect for social relations
|
documents or graphs - perfect for social relations
|
||||||
- *Free index choice:* Use the correct index for your problem, be it a skip
|
- *Free index choice*: Use the correct index for your problem, be it a skip
|
||||||
list or a fulltext search
|
list or a fulltext search
|
||||||
- *Configurable durability:* Let the application decide if it needs more
|
- *Configurable durability*: Let the application decide if it needs more
|
||||||
durability or more performance
|
durability or more performance
|
||||||
- *No-nonsense storage:* ArangoDB uses all of the power of modern storage
|
- *No-nonsense storage*: ArangoDB uses all of the power of modern storage
|
||||||
hardware, like SSD and large caches
|
hardware, like SSD and large caches
|
||||||
- *Powerful query language* (AQL) to retrieve data
|
- *Powerful query language* (AQL) to retrieve data
|
||||||
- *Transactions*: Run queries on multiple documents or collections with
|
- *Transactions*: Run queries on multiple documents or collections with
|
||||||
|
|
|
@ -73,7 +73,7 @@ Collection Methods {#HandlingCollectionsCollectionMethods}
|
||||||
@copydetails JS_PropertiesVocbaseCol
|
@copydetails JS_PropertiesVocbaseCol
|
||||||
|
|
||||||
@CLEARPAGE
|
@CLEARPAGE
|
||||||
|
@anchor HandlingCollectionsFigures
|
||||||
@copydetails JS_FiguresVocbaseCol
|
@copydetails JS_FiguresVocbaseCol
|
||||||
|
|
||||||
@CLEARPAGE
|
@CLEARPAGE
|
||||||
|
|
|
@ -332,7 +332,7 @@
|
||||||
|
|
||||||
api: function () {
|
api: function () {
|
||||||
if (!this.apiView) {
|
if (!this.apiView) {
|
||||||
this.apiView = new window.apiView();
|
this.apiView = new window.ApiView();
|
||||||
}
|
}
|
||||||
this.apiView.render();
|
this.apiView.render();
|
||||||
this.naviView.selectMenuItem('tools-menu');
|
this.naviView.selectMenuItem('tools-menu');
|
||||||
|
|
|
@ -1,42 +1,44 @@
|
||||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */
|
||||||
/*global window, document, Backbone, EJS, SwaggerUi, hljs, templateEngine, $ */
|
/*global window, document, Backbone, EJS, SwaggerUi, hljs, templateEngine, $ */
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
window.ApiView = Backbone.View.extend({
|
||||||
|
el: '#content',
|
||||||
|
|
||||||
window.apiView = Backbone.View.extend({
|
template: templateEngine.createTemplate("apiView.ejs"),
|
||||||
el: '#content',
|
|
||||||
init: function () {
|
|
||||||
},
|
|
||||||
|
|
||||||
template: templateEngine.createTemplate("apiView.ejs"),
|
initialize: function() {
|
||||||
|
this.swaggerUi = new SwaggerUi({
|
||||||
|
discoveryUrl: "api-docs.json",
|
||||||
|
apiKey: false,
|
||||||
|
dom_id:"swagger-ui-container",
|
||||||
|
supportHeaderParams: true,
|
||||||
|
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch', 'head'],
|
||||||
|
onComplete: function(){
|
||||||
|
$('pre code').each(function(i, e) {
|
||||||
|
hljs.highlightBlock(e);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onFailure: function(data) {
|
||||||
|
var div = document.createElement("div"),
|
||||||
|
strong = document.createElement("strong");
|
||||||
|
strong.appendChild(
|
||||||
|
document.createTextNode("Sorry the code is not documented properly")
|
||||||
|
);
|
||||||
|
div.appendChild(strong);
|
||||||
|
div.appendChild(document.createElement("br"));
|
||||||
|
div.appendChild(document.createTextNode(JSON.stringify(data)));
|
||||||
|
$("#swagger-ui-container").append(div);
|
||||||
|
},
|
||||||
|
docExpansion: "none"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function(){
|
||||||
|
$(this.el).html(this.template.render({}));
|
||||||
|
this.swaggerUi.load();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
initialize: function() {
|
});
|
||||||
this.swaggerUi = new SwaggerUi({
|
}());
|
||||||
discoveryUrl: "api-docs.json",
|
|
||||||
apiKey: false,
|
|
||||||
dom_id:"swagger-ui-container",
|
|
||||||
supportHeaderParams: true,
|
|
||||||
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch', 'head'],
|
|
||||||
onComplete: function(swaggerApi, swaggerUi){
|
|
||||||
$('pre code').each(function(i, e) {
|
|
||||||
hljs.highlightBlock(e);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onFailure: function(data) {
|
|
||||||
var div = document.createElement("div"),
|
|
||||||
strong = document.createElement("strong");
|
|
||||||
strong.appendChild(document.createTextNode("Sorry the code is not documented properly"));
|
|
||||||
div.appendChild(strong);
|
|
||||||
div.appendChild(document.createElement("br"));
|
|
||||||
div.appendChild(document.createTextNode(JSON.stringify(data)));
|
|
||||||
$("#swagger-ui-container").append(div);
|
|
||||||
},
|
|
||||||
docExpansion: "none"
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function(){
|
|
||||||
$(this.el).html(this.template.render({}));
|
|
||||||
this.swaggerUi.load();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
|
|
||||||
"controllers": {
|
"controllers": {
|
||||||
"/": "aardvark.js",
|
"/": "aardvark.js",
|
||||||
"/cluster": "cluster.js"
|
"/cluster": "cluster.js",
|
||||||
|
"/statistics": "statistics.js"
|
||||||
},
|
},
|
||||||
|
|
||||||
"assets": {
|
"assets": {
|
||||||
|
|
|
@ -0,0 +1,440 @@
|
||||||
|
/*jslint indent: 2, nomen: true, maxlen: 100, white: true, plusplus: true, unparam: true */
|
||||||
|
/*global require, applicationContext*/
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief A Foxx.Controller to handle the statistics
|
||||||
|
///
|
||||||
|
/// @file
|
||||||
|
///
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2014 triagens GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Dr. Frank Celler
|
||||||
|
/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var FoxxController = require("org/arangodb/foxx").Controller;
|
||||||
|
var controller = new FoxxController(applicationContext);
|
||||||
|
var db = require("org/arangodb").db;
|
||||||
|
var internal = require("internal");
|
||||||
|
var STATISTICS_INTERVALL = 10;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- private functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief avgPerSlice
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function avgPerSlice (now, last) {
|
||||||
|
var d = now.count - last.count;
|
||||||
|
|
||||||
|
if (d === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (now.sum - last.sum) / d;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief avgPerTimeSlice
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function avgPerTimeSlice (duration, now, last) {
|
||||||
|
if (duration === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (now.sum - last.sum) / duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief perTimeSlice
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function perTimeSlice (duration, now, last) {
|
||||||
|
if (duration === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (now - last) / duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief avgDistributon
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function avgPercentDistributon (now, last, cuts) {
|
||||||
|
var result = new Array(cuts.length - 1);
|
||||||
|
var count = 0;
|
||||||
|
var i;
|
||||||
|
|
||||||
|
if (last === null) {
|
||||||
|
count = now.count;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
count = now.count - last.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count === 0) {
|
||||||
|
for (i = 0; i < cuts.length; ++i) {
|
||||||
|
result[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (last === null) {
|
||||||
|
for (i = 0; i < cuts.length; ++i) {
|
||||||
|
result[i] = now.counts[i] / count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
for (i = 0; i < cuts.length; ++i) {
|
||||||
|
result[i] = (now.counts[i] - last.counts[i]) / count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { values: result, cuts: cuts };
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief computeStatisticsRaw
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function computeStatisticsRaw (start) {
|
||||||
|
var values;
|
||||||
|
|
||||||
|
if (start === null || start === undefined) {
|
||||||
|
values = db._query(
|
||||||
|
"FOR s IN _statistics "
|
||||||
|
+ " SORT s.time "
|
||||||
|
+ " return s");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
values = db._query(
|
||||||
|
"FOR s IN _statistics "
|
||||||
|
+ " FILTER s.time >= @start "
|
||||||
|
+ " SORT s.time "
|
||||||
|
+ " return s",
|
||||||
|
{ start: start });
|
||||||
|
}
|
||||||
|
|
||||||
|
var times = [];
|
||||||
|
var series = [];
|
||||||
|
|
||||||
|
var lastTime = null;
|
||||||
|
var lastRaw = null;
|
||||||
|
var lastLastRaw = null;
|
||||||
|
|
||||||
|
while (values.hasNext()) {
|
||||||
|
var raw = values.next();
|
||||||
|
var t = raw.time;
|
||||||
|
|
||||||
|
if (lastTime === null) {
|
||||||
|
lastTime = t;
|
||||||
|
lastLastRaw = null;
|
||||||
|
lastRaw = raw;
|
||||||
|
}
|
||||||
|
else if (lastTime + STATISTICS_INTERVALL * 1.5 < t
|
||||||
|
|| raw.server.uptime < lastRaw.server.uptime) {
|
||||||
|
while (lastTime + STATISTICS_INTERVALL * 1.1 < t) {
|
||||||
|
lastTime += STATISTICS_INTERVALL;
|
||||||
|
|
||||||
|
times.push(lastTime);
|
||||||
|
|
||||||
|
series.push({
|
||||||
|
totalTime: null,
|
||||||
|
requestTime: null,
|
||||||
|
queueTime: null,
|
||||||
|
ioTime: null,
|
||||||
|
bytesSent: null,
|
||||||
|
bytesReceived: null,
|
||||||
|
requestPerSecondOptions: null,
|
||||||
|
requestPerSecondPut: null,
|
||||||
|
requestPerSecondHead: null,
|
||||||
|
requestPerSecondPost: null,
|
||||||
|
requestPerSecondGet: null,
|
||||||
|
virtualSize: null,
|
||||||
|
majorPageFaults: null,
|
||||||
|
userTime: null,
|
||||||
|
systemTime: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTime = t;
|
||||||
|
lastLastRaw = null;
|
||||||
|
lastRaw = raw;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// x (aka time) axis
|
||||||
|
times.push(t);
|
||||||
|
|
||||||
|
// y axis
|
||||||
|
var data = {};
|
||||||
|
series.push(data);
|
||||||
|
|
||||||
|
// time figures
|
||||||
|
data.totalTime = avgPerSlice(
|
||||||
|
raw.client.totalTime,
|
||||||
|
lastRaw.client.totalTime);
|
||||||
|
|
||||||
|
data.requestTime = avgPerSlice(
|
||||||
|
raw.client.requestTime,
|
||||||
|
lastRaw.client.requestTime);
|
||||||
|
|
||||||
|
data.queueTime = avgPerSlice(
|
||||||
|
raw.client.queueTime,
|
||||||
|
lastRaw.client.queueTime);
|
||||||
|
|
||||||
|
data.ioTime = data.totalTime - data.requestTime - data.queueTime;
|
||||||
|
|
||||||
|
// data transfer figures
|
||||||
|
data.bytesSent = avgPerTimeSlice(
|
||||||
|
t - lastTime,
|
||||||
|
raw.client.bytesSent,
|
||||||
|
lastRaw.client.bytesSent);
|
||||||
|
|
||||||
|
data.bytesReceived = avgPerTimeSlice(
|
||||||
|
t - lastTime,
|
||||||
|
raw.client.bytesReceived,
|
||||||
|
lastRaw.client.bytesReceived);
|
||||||
|
|
||||||
|
// requests
|
||||||
|
data.optionsPerSecond = perTimeSlice(
|
||||||
|
t - lastTime,
|
||||||
|
raw.http.requestsOptions,
|
||||||
|
lastRaw.http.requestsOptions);
|
||||||
|
|
||||||
|
data.putsPerSecond = perTimeSlice(
|
||||||
|
t - lastTime,
|
||||||
|
raw.http.requestsPut,
|
||||||
|
lastRaw.http.requestsPut);
|
||||||
|
|
||||||
|
data.headsPerSecond = perTimeSlice(
|
||||||
|
t - lastTime,
|
||||||
|
raw.http.requestsHead,
|
||||||
|
lastRaw.http.requestsHead);
|
||||||
|
|
||||||
|
data.postsPerSecond = perTimeSlice(
|
||||||
|
t - lastTime,
|
||||||
|
raw.http.requestsPost,
|
||||||
|
lastRaw.http.requestsPost);
|
||||||
|
|
||||||
|
data.getsPerSecond = perTimeSlice(
|
||||||
|
t - lastTime,
|
||||||
|
raw.http.requestsGet,
|
||||||
|
lastRaw.http.requestsGet);
|
||||||
|
|
||||||
|
// memory size
|
||||||
|
data.virtualSize = raw.system.virtualSize;
|
||||||
|
data.residentSize = raw.system.residentSize;
|
||||||
|
data.residentSizePercent = raw.system.residentSizePercent;
|
||||||
|
|
||||||
|
// page faults
|
||||||
|
data.majorPageFaultsPerSecond = perTimeSlice(
|
||||||
|
t - lastTime,
|
||||||
|
raw.system.majorPageFaults,
|
||||||
|
lastRaw.system.majorPageFaults);
|
||||||
|
|
||||||
|
// cpu time
|
||||||
|
data.userTime = raw.system.userTime;
|
||||||
|
data.systemTime = raw.system.systemTime;
|
||||||
|
|
||||||
|
// update last
|
||||||
|
lastTime = t;
|
||||||
|
lastLastRaw = lastRaw;
|
||||||
|
lastRaw = raw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var distribution;
|
||||||
|
|
||||||
|
if (lastRaw === null) {
|
||||||
|
distribution = {
|
||||||
|
bytesSent: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (lastLastRaw === null) {
|
||||||
|
distribution = {
|
||||||
|
bytesSentPercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.bytesSent,
|
||||||
|
null,
|
||||||
|
internal.bytesSentDistribution),
|
||||||
|
|
||||||
|
bytesReceivedPercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.bytesReceived,
|
||||||
|
null,
|
||||||
|
internal.bytesReceivedDistribution),
|
||||||
|
|
||||||
|
totalTimePercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.totalTime,
|
||||||
|
null,
|
||||||
|
internal.requestTimeDistribution),
|
||||||
|
|
||||||
|
requestTimePercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.requestTime,
|
||||||
|
null,
|
||||||
|
internal.requestTimeDistribution),
|
||||||
|
|
||||||
|
queueTimePercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.queueTime,
|
||||||
|
null,
|
||||||
|
internal.requestTimeDistribution)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
distribution = {
|
||||||
|
bytesSentPercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.bytesSent,
|
||||||
|
lastLastRaw.client.bytesSent,
|
||||||
|
internal.bytesSentDistribution),
|
||||||
|
|
||||||
|
bytesReceivedPercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.bytesReceived,
|
||||||
|
lastLastRaw.client.bytesReceived,
|
||||||
|
internal.bytesReceivedDistribution),
|
||||||
|
|
||||||
|
totalTimePercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.totalTime,
|
||||||
|
lastLastRaw.client.totalTime,
|
||||||
|
internal.requestTimeDistribution),
|
||||||
|
|
||||||
|
requestTimePercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.requestTime,
|
||||||
|
lastLastRaw.client.requestTime,
|
||||||
|
internal.requestTimeDistribution),
|
||||||
|
|
||||||
|
queueTimePercent: avgPercentDistributon(
|
||||||
|
lastRaw.client.queueTime,
|
||||||
|
lastLastRaw.client.queueTime,
|
||||||
|
internal.requestTimeDistribution)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
next: lastTime,
|
||||||
|
times: times,
|
||||||
|
series: series,
|
||||||
|
distribution: distribution
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief convertSeries
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function convertSeries (series, name) {
|
||||||
|
var result = [];
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for (i = 0; i < series.length; ++i) {
|
||||||
|
result.push(series[i][name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief computeStatisticsSeries
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function computeStatisticsSeries (start) {
|
||||||
|
var result = {};
|
||||||
|
var raw = computeStatisticsRaw(start);
|
||||||
|
|
||||||
|
result.nextStart = raw.next;
|
||||||
|
result.waitFor = (raw.next + STATISTICS_INTERVALL) - internal.time();
|
||||||
|
result.times = raw.times;
|
||||||
|
|
||||||
|
result.avgTotalTime = convertSeries(raw.series, "totalTime");
|
||||||
|
result.totalTimeDistributionPercent = raw.distribution.totalTimePercent;
|
||||||
|
|
||||||
|
result.avgRequestTime = convertSeries(raw.series, "requestTime");
|
||||||
|
result.requestTimeDistributionPercent = raw.distribution.requestTimePercent;
|
||||||
|
|
||||||
|
result.avgQueueTime = convertSeries(raw.series, "queueTime");
|
||||||
|
result.queueTimeDistributionPercent = raw.distribution.queueTimePercent;
|
||||||
|
|
||||||
|
result.avgIoTime = convertSeries(raw.series, "ioTime");
|
||||||
|
|
||||||
|
result.bytesSentPerSecond = convertSeries(raw.series, "bytesSent");
|
||||||
|
result.bytesSentDistributionPercent = raw.distribution.bytesSentPercent;
|
||||||
|
|
||||||
|
result.bytesReceivedPerSecond = convertSeries(raw.series, "bytesReceived");
|
||||||
|
result.bytesReceivedDistributionPercent = raw.distribution.bytesReceivedPercent;
|
||||||
|
|
||||||
|
result.optionsPerSecond = convertSeries(raw.series, "optionsPerSecond");
|
||||||
|
result.putsPerSecond = convertSeries(raw.series, "putsPerSecond");
|
||||||
|
result.headsPerSecond = convertSeries(raw.series, "headsPerSecond");
|
||||||
|
result.postsPerSecond = convertSeries(raw.series, "postsPerSecond");
|
||||||
|
result.getsPerSecond = convertSeries(raw.series, "getsPerSecond");
|
||||||
|
|
||||||
|
// result.asyncRequestsCurrent = computeAsyncRequestsCurrent(raw);
|
||||||
|
// result.asyncRequests15M = computeAsyncRequests15M(raw);
|
||||||
|
|
||||||
|
// result.clientConnectionsCurrent = computeClientConnectionsCurrent(raw);
|
||||||
|
// result.clientConnections15M = computeClientConnections15M(raw);
|
||||||
|
|
||||||
|
// result.numberThreadsCurrent = computeNumberThreadsCurrent(raw);
|
||||||
|
// result.numberThreads15M = computeNumberThreads15M(raw);
|
||||||
|
|
||||||
|
result.residentSize = convertSeries(raw.series, "residentSize");
|
||||||
|
result.residentSizePercent = convertSeries(raw.series, "residentSizePercent");
|
||||||
|
|
||||||
|
result.virtualSize = convertSeries(raw.series, "virtualSize");
|
||||||
|
// result.virtualSize15M = computeVirtualSize15M(raw);
|
||||||
|
|
||||||
|
result.majorPageFaultsPerSecond = convertSeries(raw.series, "majorPageFaultsPerSecond");
|
||||||
|
// result.cpuTime = computeCpuTime(raw);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public routes
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief full statistics history
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
controller.get("full", function (req, res) {
|
||||||
|
var start = req.params("start");
|
||||||
|
|
||||||
|
if (start !== null && start !== undefined) {
|
||||||
|
start = parseInt(start, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
var series = computeStatisticsSeries(start);
|
||||||
|
|
||||||
|
res.json(series);
|
||||||
|
}).summary("Returns the complete or partial history")
|
||||||
|
.notes("This function is just to get the complete or partial statistics history");
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- END-OF-FILE
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// mode: outline-minor
|
||||||
|
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}"
|
||||||
|
// End:
|
|
@ -248,6 +248,8 @@
|
||||||
"test/specs/collections/ClusterStatisticsCollectionSpec.js",
|
"test/specs/collections/ClusterStatisticsCollectionSpec.js",
|
||||||
|
|
||||||
|
|
||||||
|
"test/specs/views/apiViewSpec.js",
|
||||||
|
"test/specs/views/appDocumentationViewSpec.js",
|
||||||
"test/specs/views/modalViewSpec.js",
|
"test/specs/views/modalViewSpec.js",
|
||||||
"test/specs/views/editListEntryViewSpec.js",
|
"test/specs/views/editListEntryViewSpec.js",
|
||||||
"test/specs/views/collectionViewSpec.js",
|
"test/specs/views/collectionViewSpec.js",
|
||||||
|
|
|
@ -31,7 +31,7 @@ module.exports = function(karma) {
|
||||||
'frontend/js/arango/**.js': ['coverage'],
|
'frontend/js/arango/**.js': ['coverage'],
|
||||||
'frontend/js/collections/**.js': ['coverage'],
|
'frontend/js/collections/**.js': ['coverage'],
|
||||||
'frontend/js/config/**.js': ['coverage'],
|
'frontend/js/config/**.js': ['coverage'],
|
||||||
'frontend/js/graphViewer/**.js': ['coverage'],
|
'frontend/js/graphViewer/**/**.js': ['coverage'],
|
||||||
'frontend/js/models/**.js': ['coverage'],
|
'frontend/js/models/**.js': ['coverage'],
|
||||||
'frontend/js/routers/**.js': ['coverage'],
|
'frontend/js/routers/**.js': ['coverage'],
|
||||||
'frontend/js/views/**.js': ['coverage']
|
'frontend/js/views/**.js': ['coverage']
|
||||||
|
|
|
@ -29,7 +29,7 @@ module.exports = function(karma) {
|
||||||
'frontend/js/arango/**.js': ['coverage'],
|
'frontend/js/arango/**.js': ['coverage'],
|
||||||
'frontend/js/collections/**.js': ['coverage'],
|
'frontend/js/collections/**.js': ['coverage'],
|
||||||
'frontend/js/config/**.js': ['coverage'],
|
'frontend/js/config/**.js': ['coverage'],
|
||||||
'frontend/js/graphViewer/**.js': ['coverage'],
|
'frontend/js/graphViewer/**/**.js': ['coverage'],
|
||||||
'frontend/js/models/**.js': ['coverage'],
|
'frontend/js/models/**.js': ['coverage'],
|
||||||
'frontend/js/routers/**.js': ['coverage'],
|
'frontend/js/routers/**.js': ['coverage'],
|
||||||
'frontend/js/views/**.js': ['coverage']
|
'frontend/js/views/**.js': ['coverage']
|
||||||
|
|
|
@ -743,7 +743,7 @@
|
||||||
it("should route to the api tab", function () {
|
it("should route to the api tab", function () {
|
||||||
simpleNavigationCheck(
|
simpleNavigationCheck(
|
||||||
"api",
|
"api",
|
||||||
"apiView",
|
"ApiView",
|
||||||
"tools-menu"
|
"tools-menu"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true*/
|
||||||
|
/*global describe, beforeEach, afterEach, it, spyOn, expect, jasmine*/
|
||||||
|
/*global window, document, hljs, $*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("The API view", function() {
|
||||||
|
var div;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
div = document.createElement("div");
|
||||||
|
div.id = "content";
|
||||||
|
document.body.appendChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
document.body.removeChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should define the swagger UI on create", function() {
|
||||||
|
spyOn(window, "SwaggerUi");
|
||||||
|
var view = new window.ApiView();
|
||||||
|
expect(window.SwaggerUi).toHaveBeenCalledWith({
|
||||||
|
discoveryUrl: "api-docs.json",
|
||||||
|
apiKey: false,
|
||||||
|
dom_id:"swagger-ui-container",
|
||||||
|
supportHeaderParams: true,
|
||||||
|
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch', 'head'],
|
||||||
|
onComplete: jasmine.any(Function),
|
||||||
|
onFailure: jasmine.any(Function),
|
||||||
|
docExpansion: "none"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("after initialize", function() {
|
||||||
|
var view, swaggerDummy;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
swaggerDummy = {
|
||||||
|
load: function() {
|
||||||
|
throw "should always be spied upon";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
spyOn(window, "SwaggerUi").andCallFake(function(opts) {
|
||||||
|
swaggerDummy.onComplete = opts.onComplete;
|
||||||
|
swaggerDummy.onFailure = opts.onFailure;
|
||||||
|
return swaggerDummy;
|
||||||
|
});
|
||||||
|
view = new window.ApiView();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("swagger onComplete should highlight blocks", function() {
|
||||||
|
spyOn(hljs, "highlightBlock");
|
||||||
|
var pre = document.createElement("pre"),
|
||||||
|
code = document.createElement("code");
|
||||||
|
document.body.appendChild(pre);
|
||||||
|
pre.appendChild(code);
|
||||||
|
swaggerDummy.onComplete();
|
||||||
|
expect(hljs.highlightBlock).toHaveBeenCalledWith($(code)[0]);
|
||||||
|
expect(hljs.highlightBlock.callCount).toEqual(1);
|
||||||
|
document.body.removeChild(pre);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create appropriate onFailure info", function() {
|
||||||
|
var dummyDiv = document.createElement("div"),
|
||||||
|
dummyStrong = document.createElement("strong"),
|
||||||
|
dummyBr = document.createElement("br"),
|
||||||
|
dummyText = document.createTextNode("dummy"),
|
||||||
|
fakeData = {fake: "data"};
|
||||||
|
spyOn(document, "createElement").andCallFake(function(name) {
|
||||||
|
switch (name) {
|
||||||
|
case "div":
|
||||||
|
return dummyDiv;
|
||||||
|
case "strong":
|
||||||
|
return dummyStrong;
|
||||||
|
case "br":
|
||||||
|
return dummyBr;
|
||||||
|
default:
|
||||||
|
throw "creating unwanted element";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
spyOn(document, "createTextNode").andReturn(dummyText);
|
||||||
|
spyOn(dummyDiv, "appendChild");
|
||||||
|
spyOn(dummyStrong, "appendChild");
|
||||||
|
swaggerDummy.onFailure(fakeData);
|
||||||
|
expect(dummyDiv.appendChild).toHaveBeenCalledWith(dummyStrong);
|
||||||
|
expect(dummyDiv.appendChild).toHaveBeenCalledWith(dummyBr);
|
||||||
|
expect(dummyDiv.appendChild).toHaveBeenCalledWith(dummyText);
|
||||||
|
expect(dummyStrong.appendChild).toHaveBeenCalledWith(dummyText);
|
||||||
|
expect(document.createTextNode)
|
||||||
|
.toHaveBeenCalledWith("Sorry the code is not documented properly");
|
||||||
|
expect(document.createTextNode).toHaveBeenCalledWith(JSON.stringify(fakeData));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should load the SwaggerUI on render", function() {
|
||||||
|
spyOn(swaggerDummy, "load");
|
||||||
|
view.render();
|
||||||
|
expect(swaggerDummy.load).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true*/
|
||||||
|
/*global describe, beforeEach, afterEach, it, spyOn, expect, jasmine*/
|
||||||
|
/*global window, document, hljs, $, internal*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("The App documentation view", function() {
|
||||||
|
var div;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
div = document.createElement("div");
|
||||||
|
div.id = "content";
|
||||||
|
document.body.appendChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
document.body.removeChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should define the swagger UI on create", function() {
|
||||||
|
var fakeURL = "/fake/url",
|
||||||
|
fakeKey = "fakeKey";
|
||||||
|
spyOn(internal.arango, "databasePrefix").andReturn(fakeURL);
|
||||||
|
spyOn(window, "SwaggerUi");
|
||||||
|
var view = new window.AppDocumentationView({
|
||||||
|
key: fakeKey
|
||||||
|
});
|
||||||
|
expect(internal.arango.databasePrefix).toHaveBeenCalledWith(
|
||||||
|
"/_admin/aardvark/docu/" + fakeKey
|
||||||
|
);
|
||||||
|
expect(window.SwaggerUi).toHaveBeenCalledWith({
|
||||||
|
discoveryUrl: fakeURL,
|
||||||
|
apiKey: false,
|
||||||
|
dom_id:"swagger-ui-container",
|
||||||
|
supportHeaderParams: true,
|
||||||
|
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch', 'head'],
|
||||||
|
onComplete: jasmine.any(Function),
|
||||||
|
onFailure: jasmine.any(Function),
|
||||||
|
docExpansion: "none"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("after initialize", function() {
|
||||||
|
var view, swaggerDummy;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
swaggerDummy = {
|
||||||
|
load: function() {
|
||||||
|
throw "should always be spied upon";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
spyOn(window, "SwaggerUi").andCallFake(function(opts) {
|
||||||
|
swaggerDummy.onComplete = opts.onComplete;
|
||||||
|
swaggerDummy.onFailure = opts.onFailure;
|
||||||
|
return swaggerDummy;
|
||||||
|
});
|
||||||
|
view = new window.AppDocumentationView();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("swagger onComplete should highlight blocks", function() {
|
||||||
|
spyOn(hljs, "highlightBlock");
|
||||||
|
var pre = document.createElement("pre"),
|
||||||
|
code = document.createElement("code");
|
||||||
|
document.body.appendChild(pre);
|
||||||
|
pre.appendChild(code);
|
||||||
|
swaggerDummy.onComplete();
|
||||||
|
expect(hljs.highlightBlock).toHaveBeenCalledWith($(code)[0]);
|
||||||
|
expect(hljs.highlightBlock.callCount).toEqual(1);
|
||||||
|
document.body.removeChild(pre);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create appropriate onFailure info", function() {
|
||||||
|
var dummyDiv = document.createElement("div"),
|
||||||
|
dummyStrong = document.createElement("strong"),
|
||||||
|
dummyBr = document.createElement("br"),
|
||||||
|
dummyText = document.createTextNode("dummy"),
|
||||||
|
fakeData = {fake: "data"};
|
||||||
|
spyOn(document, "createElement").andCallFake(function(name) {
|
||||||
|
switch (name) {
|
||||||
|
case "div":
|
||||||
|
return dummyDiv;
|
||||||
|
case "strong":
|
||||||
|
return dummyStrong;
|
||||||
|
case "br":
|
||||||
|
return dummyBr;
|
||||||
|
default:
|
||||||
|
throw "creating unwanted element";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
spyOn(document, "createTextNode").andReturn(dummyText);
|
||||||
|
spyOn(dummyDiv, "appendChild");
|
||||||
|
spyOn(dummyStrong, "appendChild");
|
||||||
|
swaggerDummy.onFailure(fakeData);
|
||||||
|
expect(dummyDiv.appendChild).toHaveBeenCalledWith(dummyStrong);
|
||||||
|
expect(dummyDiv.appendChild).toHaveBeenCalledWith(dummyBr);
|
||||||
|
expect(dummyDiv.appendChild).toHaveBeenCalledWith(dummyText);
|
||||||
|
expect(dummyStrong.appendChild).toHaveBeenCalledWith(dummyText);
|
||||||
|
expect(document.createTextNode)
|
||||||
|
.toHaveBeenCalledWith("Sorry the code is not documented properly");
|
||||||
|
expect(document.createTextNode).toHaveBeenCalledWith(JSON.stringify(fakeData));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should load the SwaggerUI on render", function() {
|
||||||
|
spyOn(swaggerDummy, "load");
|
||||||
|
view.render();
|
||||||
|
expect(swaggerDummy.load).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
Loading…
Reference in New Issue