1
0
Fork 0
arangodb/js/actions/_admin/app.js

526 lines
16 KiB
JavaScript

/* jshint strict: false */
// //////////////////////////////////////////////////////////////////////////////
// / @brief administration actions
// /
// / @file
// /
// / DISCLAIMER
// /
// / Copyright 2014-2015 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
// /
// / @author Dr. Frank Celler
// / @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
// / @author Copyright 2012-2014, triAGENS GmbH, Cologne, Germany
// //////////////////////////////////////////////////////////////////////////////
var internal = require('internal');
var console = require('console');
var actions = require('@arangodb/actions');
var arangodb = require('@arangodb');
// var queue = Foxx.queues.create("internal-demo-queue")
// //////////////////////////////////////////////////////////////////////////////
// / @brief was docuBlock JSF_get_admin_time
// //////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: '_admin/time',
prefix: false,
callback: function (req, res) {
actions.resultOk(req, res, actions.HTTP_OK, { time: internal.time() });
}
});
// //////////////////////////////////////////////////////////////////////////////
// / @brief was docuBlock JSF_get_admin_sleep
// //////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: '_admin/sleep',
prefix: false,
callback: function (req, res) {
var time = parseFloat(req.parameters.duration);
if (isNaN(time)) {
time = 3.0;
}
internal.wait(time);
actions.resultOk(req, res, actions.HTTP_OK, { duration: time });
}
});
// //////////////////////////////////////////////////////////////////////////////
// / @brief was docuBlock JSF_get_admin_echo
// //////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: '_admin/echo',
prefix: true,
callback: function (req, res) {
res.responseCode = actions.HTTP_OK;
res.contentType = 'application/json; charset=utf-8';
req.rawRequestBody = require('internal').rawRequestBody(req);
res.body = JSON.stringify(req);
}
});
// //////////////////////////////////////////////////////////////////////////////
// / @brief was docuBlock JSF_get_admin_long_echo
// //////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: '_admin/long_echo',
prefix: true,
callback: function (req, res) {
require('console').log('long polling request from client %s', req.client.id);
res.responseCode = actions.HTTP_OK;
res.contentType = 'application/json; charset=utf-8';
res.headers = { 'transfer-encoding': 'chunked' };
res.body = JSON.stringify(req);
}
});
// //////////////////////////////////////////////////////////////////////////////
// / @brief was docuBlock JSF_get_admin_statistics
// //////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: '_admin/statistics',
prefix: false,
callback: function (req, res) {
var result;
try {
result = {};
result.time = internal.time();
result.enabled = internal.enabledStatistics();
result.system = internal.processStatistics();
result.client = internal.clientStatistics();
result.http = internal.httpStatistics();
result.server = internal.serverStatistics();
actions.resultOk(req, res, actions.HTTP_OK, result);
} catch (err) {
actions.resultException(req, res, err, undefined, false);
}
}
});
// //////////////////////////////////////////////////////////////////////////////
// / @brief was docuBlock JSF_get_admin_statistics_description
// //////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: '_admin/statistics-description',
prefix: false,
callback: function (req, res) {
var result;
try {
result = {
groups: [
{
group: 'system',
name: 'Process Statistics',
description: 'Statistics about the ArangoDB process'
},
{
group: 'client',
name: 'Client Connection Statistics',
description: 'Statistics about the connections.'
},
{
group: 'http',
name: 'HTTP Request Statistics',
description: 'Statistics about the HTTP requests.'
},
{
group: 'server',
name: 'Server Statistics',
description: 'Statistics about the ArangoDB server'
}
],
figures: [
// .............................................................................
// system statistics
// .............................................................................
{
group: 'system',
identifier: 'userTime',
name: 'User Time',
description: 'Amount of time that this process has been scheduled in user mode, ' +
'measured in seconds.',
type: 'accumulated',
units: 'seconds'
},
{
group: 'system',
identifier: 'systemTime',
name: 'System Time',
description: 'Amount of time that this process has been scheduled in kernel mode, ' +
'measured in seconds.',
type: 'accumulated',
units: 'seconds'
},
{
group: 'system',
identifier: 'numberOfThreads',
name: 'Number of Threads',
description: 'Number of threads in the arangod process.',
type: 'current',
units: 'number'
},
{
group: 'system',
identifier: 'residentSize',
name: 'Resident Set Size',
description: 'The total size of the number of pages the process has in real memory. ' +
'This is just the pages which count toward text, data, or stack space. ' +
'This does not include pages which have not been demand-loaded in, ' +
'or which are swapped out. The resident set size is reported in bytes.',
type: 'current',
units: 'bytes'
},
{
group: 'system',
identifier: 'residentSizePercent',
name: 'Resident Set Size',
description: 'The percentage of physical memory used by the process as resident ' +
'set size.',
type: 'current',
units: 'percent'
},
{
group: 'system',
identifier: 'virtualSize',
name: 'Virtual Memory Size',
description: 'On Windows, this figure contains the total amount of memory that the ' +
'memory manager has committed for the arangod process. On other ' +
'systems, this figure contains The size of the virtual memory the ' +
'process is using.',
type: 'current',
units: 'bytes'
},
{
group: 'system',
identifier: 'minorPageFaults',
name: 'Minor Page Faults',
description: 'The number of minor faults the process has made which have ' +
'not required loading a memory page from disk. This figure is ' +
'not reported on Windows.',
type: 'accumulated',
units: 'number'
},
{
group: 'system',
identifier: 'majorPageFaults',
name: 'Major Page Faults',
description: 'On Windows, this figure contains the total number of page faults. ' +
'On other system, this figure contains the number of major faults the ' +
'process has made which have required loading a memory page from disk.',
type: 'accumulated',
units: 'number'
},
// .............................................................................
// client statistics
// .............................................................................
{
group: 'client',
identifier: 'httpConnections',
name: 'Client Connections',
description: 'The number of connections that are currently open.',
type: 'current',
units: 'number'
},
{
group: 'client',
identifier: 'totalTime',
name: 'Total Time',
description: 'Total time needed to answer a request.',
type: 'distribution',
cuts: internal.requestTimeDistribution,
units: 'seconds'
},
{
group: 'client',
identifier: 'requestTime',
name: 'Request Time',
description: 'Request time needed to answer a request.',
type: 'distribution',
cuts: internal.requestTimeDistribution,
units: 'seconds'
},
{
group: 'client',
identifier: 'queueTime',
name: 'Queue Time',
description: 'Queue time needed to answer a request.',
type: 'distribution',
cuts: internal.requestTimeDistribution,
units: 'seconds'
},
{
group: 'client',
identifier: 'bytesSent',
name: 'Bytes Sent',
description: 'Bytes sents for a request.',
type: 'distribution',
cuts: internal.bytesSentDistribution,
units: 'bytes'
},
{
group: 'client',
identifier: 'bytesReceived',
name: 'Bytes Received',
description: 'Bytes receiveds for a request.',
type: 'distribution',
cuts: internal.bytesReceivedDistribution,
units: 'bytes'
},
{
group: 'client',
identifier: 'connectionTime',
name: 'Connection Time',
description: 'Total connection time of a client.',
type: 'distribution',
cuts: internal.connectionTimeDistribution,
units: 'seconds'
},
{
group: 'http',
identifier: 'requestsTotal',
name: 'Total requests',
description: 'Total number of HTTP requests.',
type: 'accumulated',
units: 'number'
},
{
group: 'http',
identifier: 'requestsAsync',
name: 'Async requests',
description: 'Number of asynchronously executed HTTP requests.',
type: 'accumulated',
units: 'number'
},
{
group: 'http',
identifier: 'requestsGet',
name: 'HTTP GET requests',
description: 'Number of HTTP GET requests.',
type: 'accumulated',
units: 'number'
},
{
group: 'http',
identifier: 'requestsHead',
name: 'HTTP HEAD requests',
description: 'Number of HTTP HEAD requests.',
type: 'accumulated',
units: 'number'
},
{
group: 'http',
identifier: 'requestsPost',
name: 'HTTP POST requests',
description: 'Number of HTTP POST requests.',
type: 'accumulated',
units: 'number'
},
{
group: 'http',
identifier: 'requestsPut',
name: 'HTTP PUT requests',
description: 'Number of HTTP PUT requests.',
type: 'accumulated',
units: 'number'
},
{
group: 'http',
identifier: 'requestsPatch',
name: 'HTTP PATCH requests',
description: 'Number of HTTP PATCH requests.',
type: 'accumulated',
units: 'number'
},
{
group: 'http',
identifier: 'requestsDelete',
name: 'HTTP DELETE requests',
description: 'Number of HTTP DELETE requests.',
type: 'accumulated',
units: 'number'
},
{
group: 'http',
identifier: 'requestsOptions',
name: 'HTTP OPTIONS requests',
description: 'Number of HTTP OPTIONS requests.',
type: 'accumulated',
units: 'number'
},
{
group: 'http',
identifier: 'requestsOther',
name: 'other HTTP requests',
description: 'Number of other HTTP requests.',
type: 'accumulated',
units: 'number'
},
// .............................................................................
// server statistics
// .............................................................................
{
group: 'server',
identifier: 'uptime',
name: 'Server Uptime',
description: 'Number of seconds elapsed since server start.',
type: 'current',
units: 'seconds'
},
{
group: 'server',
identifier: 'physicalMemory',
name: 'Physical Memory',
description: 'Physical memory in bytes.',
type: 'current',
units: 'bytes'
}
]
};
actions.resultOk(req, res, actions.HTTP_OK, result);
} catch (err) {
actions.resultException(req, res, err, undefined, false);
}
}
});
// //////////////////////////////////////////////////////////////////////////////
// / @brief was docuBlock JSF_post_admin_test
// //////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: '_admin/test',
prefix: false,
callback: function (req, res) {
var body = actions.getJsonBody(req, res);
if (body === undefined) {
return;
}
var tests = body.tests;
if (!Array.isArray(tests)) {
actions.resultError(req, res,
actions.HTTP_BAD, arangodb.ERROR_HTTP_BAD_PARAMETER,
"expected attribute 'tests' is missing");
return;
}
var jsUnity = require('jsunity');
var testResults = { passed: { }, error: false };
tests.forEach(function (test) {
var result = false;
try {
result = jsUnity.runTest(test);
} catch (err) {}
testResults.passed[test] = result;
if (!result) {
testResults.error = true;
}
});
actions.resultOk(req, res, actions.HTTP_OK, testResults);
}
});
// //////////////////////////////////////////////////////////////////////////////
// / @brief was docuBlock JSF_post_admin_execute
// //////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: '_admin/execute',
prefix: false,
callback: function (req, res) {
/* jshint evil: true */
var body = req.requestBody;
var result;
console.warn("about to execute: '%s'", body);
if (body !== '') {
result = eval('(function() {' + body + '}());');
}
if (req.parameters.hasOwnProperty('returnAsJSON') &&
req.parameters.returnAsJSON === 'true') {
actions.resultOk(req, res, actions.HTTP_OK, result);
} else {
actions.resultOk(req, res, actions.HTTP_OK, JSON.stringify(result));
}
}
});