mirror of https://gitee.com/bigwinds/arangodb
Replacing statistics handler with c++ (#4653)
This commit is contained in:
parent
d841b56c77
commit
11a7bbf321
|
@ -3,6 +3,8 @@ devel
|
||||||
|
|
||||||
* fix issue #4583 - add AQL ASSERT and AQL WARN
|
* fix issue #4583 - add AQL ASSERT and AQL WARN
|
||||||
|
|
||||||
|
* remove _admin/echo handler
|
||||||
|
|
||||||
* remove long disfunctional admin/long_echo handler
|
* remove long disfunctional admin/long_echo handler
|
||||||
|
|
||||||
* fixed Foxx API:
|
* fixed Foxx API:
|
||||||
|
|
|
@ -24,9 +24,6 @@ This is an overview of ArangoDB's HTTP interface for miscellaneous functions.
|
||||||
<!-- js/actions/api-system.js -->
|
<!-- js/actions/api-system.js -->
|
||||||
@startDocuBlock JSF_get_admin_time
|
@startDocuBlock JSF_get_admin_time
|
||||||
|
|
||||||
<!-- js/actions/api-system.js -->
|
|
||||||
@startDocuBlock JSF_get_admin_echo
|
|
||||||
|
|
||||||
@startDocuBlock JSF_get_admin_database_version
|
@startDocuBlock JSF_get_admin_database_version
|
||||||
|
|
||||||
<!-- lib/Admin/RestShutdownHandler.cpp -->
|
<!-- lib/Admin/RestShutdownHandler.cpp -->
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
|
|
||||||
@startDocuBlock JSF_get_admin_echo
|
|
||||||
@brief Send back what was sent in, headers, post body etc.
|
|
||||||
|
|
||||||
@RESTHEADER{GET /_admin/echo, Return current request}
|
|
||||||
|
|
||||||
@RESTDESCRIPTION
|
|
||||||
|
|
||||||
The call returns an object with the following attributes:
|
|
||||||
|
|
||||||
- *headers*: object with HTTP headers received
|
|
||||||
|
|
||||||
- *requestType*: the HTTP request method (e.g. GET)
|
|
||||||
|
|
||||||
- *parameters*: object with query parameters received
|
|
||||||
|
|
||||||
@RESTRETURNCODES
|
|
||||||
|
|
||||||
@RESTRETURNCODE{200}
|
|
||||||
Echo was returned successfully.
|
|
||||||
@endDocuBlock
|
|
||||||
|
|
|
@ -53,65 +53,6 @@ describe ArangoDB do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
################################################################################
|
|
||||||
## /_admin/echo
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
context "checks /_admin/echo" do
|
|
||||||
|
|
||||||
prefix = "api-system"
|
|
||||||
|
|
||||||
it "using GET" do
|
|
||||||
cmd = "/_admin/echo"
|
|
||||||
doc = ArangoDB.log_get("#{prefix}-echo", cmd)
|
|
||||||
|
|
||||||
doc.code.should eq(200)
|
|
||||||
doc.parsed_response['url'].should eq("/_admin/echo")
|
|
||||||
doc.parsed_response['path'].should eq("/")
|
|
||||||
doc.parsed_response['parameters'].should eq({})
|
|
||||||
doc.parsed_response['requestType'].should eq("GET")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "using GET, with query parameter" do
|
|
||||||
cmd = "/_admin/echo?a=1"
|
|
||||||
doc = ArangoDB.log_get("#{prefix}-echo", cmd)
|
|
||||||
|
|
||||||
doc.code.should eq(200)
|
|
||||||
doc.parsed_response['url'].should eq("/_admin/echo?a=1")
|
|
||||||
doc.parsed_response['path'].should eq("/")
|
|
||||||
doc.parsed_response['parameters'].should eq({ "a" => "1" })
|
|
||||||
doc.parsed_response['requestType'].should eq("GET")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "using POST, with query parameters" do
|
|
||||||
cmd = "/_admin/echo?a=1&b=2&foo[]=bar&foo[]=baz"
|
|
||||||
body = "{\"foo\": \"bar\", \"baz\": { \"bump\": true, \"moo\": [ ] } }"
|
|
||||||
doc = ArangoDB.log_post("#{prefix}-echo", cmd, :body => body)
|
|
||||||
|
|
||||||
doc.code.should eq(200)
|
|
||||||
doc.parsed_response['url'].should eq("/_admin/echo?a=1&b=2&foo[]=bar&foo[]=baz")
|
|
||||||
doc.parsed_response['path'].should eq("/")
|
|
||||||
doc.parsed_response['parameters'].should eq( { "a"=>"1", "b"=>"2", "foo"=>["bar", "baz"] } )
|
|
||||||
doc.parsed_response['requestType'].should eq("POST")
|
|
||||||
doc.parsed_response['requestBody'].should eq("{\"foo\": \"bar\", \"baz\": { \"bump\": true, \"moo\": [ ] } }")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "using PUT, with headers" do
|
|
||||||
cmd = "/_admin/echo?"
|
|
||||||
body = "{ }"
|
|
||||||
headers = { "X-Foo" => "Bar", "x-meow" => "mOO" }
|
|
||||||
doc = ArangoDB.log_put("#{prefix}-echo", cmd, :body => body, :headers => headers)
|
|
||||||
|
|
||||||
doc.code.should eq(200)
|
|
||||||
doc.parsed_response['url'].should eq("/_admin/echo?")
|
|
||||||
doc.parsed_response['path'].should eq("/")
|
|
||||||
doc.parsed_response['parameters'].should eq({ })
|
|
||||||
doc.parsed_response['requestType'].should eq("PUT")
|
|
||||||
doc.parsed_response['requestBody'].should eq("{ }")
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
## check whether admin interface is accessible
|
## check whether admin interface is accessible
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
|
@ -363,6 +363,7 @@ SET(ARANGOD_SOURCES
|
||||||
RestHandler/RestAdminLogHandler.cpp
|
RestHandler/RestAdminLogHandler.cpp
|
||||||
RestHandler/RestAdminRoutingHandler.cpp
|
RestHandler/RestAdminRoutingHandler.cpp
|
||||||
RestHandler/RestAdminServerHandler.cpp
|
RestHandler/RestAdminServerHandler.cpp
|
||||||
|
RestHandler/RestAdminStatisticsHandler.cpp
|
||||||
RestHandler/RestAqlFunctionsHandler.cpp
|
RestHandler/RestAqlFunctionsHandler.cpp
|
||||||
RestHandler/RestAqlUserFunctionsHandler.cpp
|
RestHandler/RestAqlUserFunctionsHandler.cpp
|
||||||
RestHandler/RestAuthHandler.cpp
|
RestHandler/RestAuthHandler.cpp
|
||||||
|
@ -374,7 +375,6 @@ SET(ARANGOD_SOURCES
|
||||||
RestHandler/RestDebugHandler.cpp
|
RestHandler/RestDebugHandler.cpp
|
||||||
RestHandler/RestDemoHandler.cpp
|
RestHandler/RestDemoHandler.cpp
|
||||||
RestHandler/RestDocumentHandler.cpp
|
RestHandler/RestDocumentHandler.cpp
|
||||||
RestHandler/RestEchoHandler.cpp
|
|
||||||
RestHandler/RestEdgesHandler.cpp
|
RestHandler/RestEdgesHandler.cpp
|
||||||
RestHandler/RestEndpointHandler.cpp
|
RestHandler/RestEndpointHandler.cpp
|
||||||
RestHandler/RestEngineHandler.cpp
|
RestHandler/RestEngineHandler.cpp
|
||||||
|
@ -436,6 +436,7 @@ SET(ARANGOD_SOURCES
|
||||||
Scheduler/SocketTcp.cpp
|
Scheduler/SocketTcp.cpp
|
||||||
Scheduler/Task.cpp
|
Scheduler/Task.cpp
|
||||||
Statistics/ConnectionStatistics.cpp
|
Statistics/ConnectionStatistics.cpp
|
||||||
|
Statistics/Descriptions.cpp
|
||||||
Statistics/RequestStatistics.cpp
|
Statistics/RequestStatistics.cpp
|
||||||
Statistics/ServerStatistics.cpp
|
Statistics/ServerStatistics.cpp
|
||||||
Statistics/StatisticsFeature.cpp
|
Statistics/StatisticsFeature.cpp
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "RestHandler/RestAdminLogHandler.h"
|
#include "RestHandler/RestAdminLogHandler.h"
|
||||||
#include "RestHandler/RestAdminRoutingHandler.h"
|
#include "RestHandler/RestAdminRoutingHandler.h"
|
||||||
#include "RestHandler/RestAdminServerHandler.h"
|
#include "RestHandler/RestAdminServerHandler.h"
|
||||||
|
#include "RestHandler/RestAdminStatisticsHandler.h"
|
||||||
#include "RestHandler/RestAqlFunctionsHandler.h"
|
#include "RestHandler/RestAqlFunctionsHandler.h"
|
||||||
#include "RestHandler/RestAqlUserFunctionsHandler.h"
|
#include "RestHandler/RestAqlUserFunctionsHandler.h"
|
||||||
#include "RestHandler/RestAuthHandler.h"
|
#include "RestHandler/RestAuthHandler.h"
|
||||||
|
@ -55,7 +56,6 @@
|
||||||
#include "RestHandler/RestDebugHandler.h"
|
#include "RestHandler/RestDebugHandler.h"
|
||||||
#include "RestHandler/RestDemoHandler.h"
|
#include "RestHandler/RestDemoHandler.h"
|
||||||
#include "RestHandler/RestDocumentHandler.h"
|
#include "RestHandler/RestDocumentHandler.h"
|
||||||
#include "RestHandler/RestEchoHandler.h"
|
|
||||||
#include "RestHandler/RestEdgesHandler.h"
|
#include "RestHandler/RestEdgesHandler.h"
|
||||||
#include "RestHandler/RestEndpointHandler.h"
|
#include "RestHandler/RestEndpointHandler.h"
|
||||||
#include "RestHandler/RestEngineHandler.h"
|
#include "RestHandler/RestEngineHandler.h"
|
||||||
|
@ -526,9 +526,6 @@ void GeneralServerFeature::defineHandlers() {
|
||||||
"/_admin/work-monitor",
|
"/_admin/work-monitor",
|
||||||
RestHandlerCreator<WorkMonitorHandler>::createNoData);
|
RestHandlerCreator<WorkMonitorHandler>::createNoData);
|
||||||
|
|
||||||
_handlerFactory->addHandler(
|
|
||||||
"/_admin/json-echo", RestHandlerCreator<RestEchoHandler>::createNoData);
|
|
||||||
|
|
||||||
#ifdef ARANGODB_ENABLE_FAILURE_TESTS
|
#ifdef ARANGODB_ENABLE_FAILURE_TESTS
|
||||||
// This handler is to activate SYS_DEBUG_FAILAT on DB servers
|
// This handler is to activate SYS_DEBUG_FAILAT on DB servers
|
||||||
_handlerFactory->addPrefixHandler(
|
_handlerFactory->addPrefixHandler(
|
||||||
|
@ -548,6 +545,14 @@ void GeneralServerFeature::defineHandlers() {
|
||||||
_handlerFactory->addPrefixHandler(
|
_handlerFactory->addPrefixHandler(
|
||||||
"/_admin/server",
|
"/_admin/server",
|
||||||
RestHandlerCreator<arangodb::RestAdminServerHandler>::createNoData);
|
RestHandlerCreator<arangodb::RestAdminServerHandler>::createNoData);
|
||||||
|
|
||||||
|
_handlerFactory->addHandler(
|
||||||
|
"/_admin/statistics",
|
||||||
|
RestHandlerCreator<arangodb::RestAdminStatisticsHandler>::createNoData);
|
||||||
|
|
||||||
|
_handlerFactory->addHandler(
|
||||||
|
"/_admin/statistics-description",
|
||||||
|
RestHandlerCreator<arangodb::RestAdminStatisticsHandler>::createNoData);
|
||||||
|
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
// actions defined in v8
|
// actions defined in v8
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2018 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 Simon Grätzer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "RestAdminStatisticsHandler.h"
|
||||||
|
#include "Statistics/Descriptions.h"
|
||||||
|
#include "Statistics/StatisticsFeature.h"
|
||||||
|
|
||||||
|
using namespace arangodb;
|
||||||
|
using namespace arangodb::basics;
|
||||||
|
using namespace arangodb::rest;
|
||||||
|
|
||||||
|
RestAdminStatisticsHandler::RestAdminStatisticsHandler(GeneralRequest* request,
|
||||||
|
GeneralResponse* response)
|
||||||
|
: RestBaseHandler(request, response) {}
|
||||||
|
|
||||||
|
RestStatus RestAdminStatisticsHandler::execute() {
|
||||||
|
if (_request->requestType() != rest::RequestType::GET) {
|
||||||
|
generateError(rest::ResponseCode::METHOD_NOT_ALLOWED,
|
||||||
|
TRI_ERROR_HTTP_METHOD_NOT_ALLOWED);
|
||||||
|
return RestStatus::DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_request->requestPath() == "/_admin/statistics") {
|
||||||
|
getStatistics();
|
||||||
|
} else if (_request->requestPath() == "/_admin/statistics-description") {
|
||||||
|
getStatisticsDescription();
|
||||||
|
} else {
|
||||||
|
generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_HTTP_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this handler is done
|
||||||
|
return RestStatus::DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestAdminStatisticsHandler::getStatistics() {
|
||||||
|
stats::Descriptions const* desc = StatisticsFeature::descriptions();
|
||||||
|
if (!desc) {
|
||||||
|
generateError(rest::ResponseCode::SERVICE_UNAVAILABLE,
|
||||||
|
TRI_ERROR_SHUTTING_DOWN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VPackBuffer<uint8_t> buffer;
|
||||||
|
VPackBuilder tmp(buffer);
|
||||||
|
tmp.add(VPackValue(VPackValueType::Object, true));
|
||||||
|
|
||||||
|
tmp.add("time", VPackValue(TRI_microtime()));
|
||||||
|
tmp.add("enabled", VPackValue(StatisticsFeature::enabled()));
|
||||||
|
|
||||||
|
tmp.add("system", VPackValue(VPackValueType::Object, true));
|
||||||
|
desc->processStatistics(tmp);
|
||||||
|
tmp.close(); // system
|
||||||
|
|
||||||
|
tmp.add("client", VPackValue(VPackValueType::Object, true));
|
||||||
|
desc->clientStatistics(tmp);
|
||||||
|
tmp.close(); // client
|
||||||
|
|
||||||
|
tmp.add("http", VPackValue(VPackValueType::Object, true));
|
||||||
|
desc->httpStatistics(tmp);
|
||||||
|
tmp.close(); // http
|
||||||
|
|
||||||
|
tmp.add("server", VPackValue(VPackValueType::Object, true));
|
||||||
|
desc->serverStatistics(tmp);
|
||||||
|
tmp.close(); // server
|
||||||
|
|
||||||
|
tmp.add(StaticStrings::Error, VPackValue(false));
|
||||||
|
tmp.add(StaticStrings::Code, VPackValue(static_cast<int>(ResponseCode::OK)));
|
||||||
|
tmp.close(); // outer
|
||||||
|
generateResult(ResponseCode::OK, std::move(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestAdminStatisticsHandler::getStatisticsDescription() {
|
||||||
|
stats::Descriptions const* desc = StatisticsFeature::descriptions();
|
||||||
|
if (!desc) {
|
||||||
|
generateError(rest::ResponseCode::SERVICE_UNAVAILABLE,
|
||||||
|
TRI_ERROR_SHUTTING_DOWN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VPackBuffer<uint8_t> buffer;
|
||||||
|
VPackBuilder tmp(buffer);
|
||||||
|
tmp.add(VPackValue(VPackValueType::Object));
|
||||||
|
|
||||||
|
tmp.add("groups", VPackValue(VPackValueType::Array, true));
|
||||||
|
for (stats::Group const& group : desc->groups()) {
|
||||||
|
tmp.openObject();
|
||||||
|
group.toVPack(tmp);
|
||||||
|
tmp.close();
|
||||||
|
}
|
||||||
|
tmp.close(); // groups
|
||||||
|
|
||||||
|
tmp.add("figures", VPackValue(VPackValueType::Array, true));
|
||||||
|
for (stats::Figure const& figure : desc->figures()) {
|
||||||
|
tmp.openObject();
|
||||||
|
figure.toVPack(tmp);
|
||||||
|
tmp.close();
|
||||||
|
}
|
||||||
|
tmp.close(); // figures
|
||||||
|
|
||||||
|
tmp.add(StaticStrings::Error, VPackValue(false));
|
||||||
|
tmp.add(StaticStrings::Code, VPackValue(static_cast<int>(ResponseCode::OK)));
|
||||||
|
tmp.close(); // outer
|
||||||
|
generateResult(ResponseCode::OK, std::move(buffer));
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// DISCLAIMER
|
/// DISCLAIMER
|
||||||
///
|
///
|
||||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
/// Copyright 2018 ArangoDB GmbH, Cologne, Germany
|
||||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
|
||||||
///
|
///
|
||||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
/// you may not use this file except in compliance with the License.
|
/// you may not use this file except in compliance with the License.
|
||||||
|
@ -18,23 +17,28 @@
|
||||||
///
|
///
|
||||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||||
///
|
///
|
||||||
/// @author Achim Brandt
|
/// @author Simon Grätzer
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef ARANGOD_REST_HANDLER_REST_ECHO_HANDLER_H
|
#ifndef ARANGOD_REST_HANDLER_REST_ADMIN_STATISTICS_HANDLER_H
|
||||||
#define ARANGOD_REST_HANDLER_REST_ECHO_HANDLER_H 1
|
#define ARANGOD_REST_HANDLER_REST_ADMIN_STATISTICS_HANDLER_H 1
|
||||||
|
|
||||||
#include "RestHandler/RestVocbaseBaseHandler.h"
|
#include "Basics/Common.h"
|
||||||
|
#include "RestHandler/RestBaseHandler.h"
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
class RestEchoHandler : public arangodb::RestVocbaseBaseHandler {
|
class RestAdminStatisticsHandler : public RestBaseHandler {
|
||||||
public:
|
public:
|
||||||
RestEchoHandler(GeneralRequest*, GeneralResponse*);
|
RestAdminStatisticsHandler(GeneralRequest*, GeneralResponse*);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
char const* name() const override final { return "RestEchoHandler"; }
|
char const* name() const override final { return "RestAdminStatisticsHandler"; }
|
||||||
bool isDirect() const override { return true; }
|
bool isDirect() const override final { return false; }
|
||||||
RestStatus execute() override;
|
RestStatus execute() override final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void getStatistics();
|
||||||
|
void getStatisticsDescription();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ void RestBaseHandler::generateOk(rest::ResponseCode code,
|
||||||
try {
|
try {
|
||||||
VPackBuffer<uint8_t> buffer;
|
VPackBuffer<uint8_t> buffer;
|
||||||
VPackBuilder tmp(buffer);
|
VPackBuilder tmp(buffer);
|
||||||
tmp.add(VPackValue(VPackValueType::Object));
|
tmp.add(VPackValue(VPackValueType::Object, true));
|
||||||
tmp.add(StaticStrings::Error, VPackValue(false));
|
tmp.add(StaticStrings::Error, VPackValue(false));
|
||||||
tmp.add(StaticStrings::Code, VPackValue(static_cast<int>(code)));
|
tmp.add(StaticStrings::Code, VPackValue(static_cast<int>(code)));
|
||||||
tmp.add("result", payload);
|
tmp.add("result", payload);
|
||||||
|
@ -127,7 +127,7 @@ void RestBaseHandler::generateOk(rest::ResponseCode code,
|
||||||
|
|
||||||
try {
|
try {
|
||||||
VPackBuilder tmp;
|
VPackBuilder tmp;
|
||||||
tmp.add(VPackValue(VPackValueType::Object));
|
tmp.add(VPackValue(VPackValueType::Object, true));
|
||||||
tmp.add(StaticStrings::Error, VPackValue(false));
|
tmp.add(StaticStrings::Error, VPackValue(false));
|
||||||
tmp.add(StaticStrings::Code, VPackValue(static_cast<int>(code)));
|
tmp.add(StaticStrings::Code, VPackValue(static_cast<int>(code)));
|
||||||
tmp.close();
|
tmp.close();
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// DISCLAIMER
|
|
||||||
///
|
|
||||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
|
||||||
/// Copyright 2004-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 ArangoDB GmbH, Cologne, Germany
|
|
||||||
///
|
|
||||||
/// @author Achim Brandt
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "RestEchoHandler.h"
|
|
||||||
|
|
||||||
#include "ApplicationFeatures/ApplicationServer.h"
|
|
||||||
#include "Rest/HttpRequest.h"
|
|
||||||
|
|
||||||
#include <velocypack/Builder.h>
|
|
||||||
#include <velocypack/velocypack-aliases.h>
|
|
||||||
|
|
||||||
using namespace arangodb;
|
|
||||||
using namespace arangodb::basics;
|
|
||||||
using namespace arangodb::rest;
|
|
||||||
|
|
||||||
RestEchoHandler::RestEchoHandler(GeneralRequest* request, GeneralResponse* response)
|
|
||||||
: RestVocbaseBaseHandler(request, response) {}
|
|
||||||
|
|
||||||
RestStatus RestEchoHandler::execute() {
|
|
||||||
bool parseSuccess = true;
|
|
||||||
std::shared_ptr<VPackBuilder> parsedBody =
|
|
||||||
parseVelocyPackBody(parseSuccess);
|
|
||||||
|
|
||||||
if (parseSuccess) {
|
|
||||||
VPackBuilder result;
|
|
||||||
generateResult(rest::ResponseCode::OK, parsedBody->slice());
|
|
||||||
}
|
|
||||||
|
|
||||||
return RestStatus::DONE;
|
|
||||||
}
|
|
|
@ -0,0 +1,468 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2018 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 Simon Grätzer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "Descriptions.h"
|
||||||
|
#include "Basics/Common.h"
|
||||||
|
#include "Basics/process-utils.h"
|
||||||
|
#include "Statistics/ConnectionStatistics.h"
|
||||||
|
#include "Statistics/RequestStatistics.h"
|
||||||
|
#include "Statistics/ServerStatistics.h"
|
||||||
|
#include "Statistics/StatisticsFeature.h"
|
||||||
|
#include "Scheduler/Scheduler.h"
|
||||||
|
#include "Scheduler/SchedulerFeature.h"
|
||||||
|
#include "V8Server/V8DealerFeature.h"
|
||||||
|
|
||||||
|
#include <velocypack/Builder.h>
|
||||||
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
|
||||||
|
using namespace arangodb;
|
||||||
|
|
||||||
|
std::string stats::fromGroupType(stats::GroupType gt) {
|
||||||
|
switch (gt) {
|
||||||
|
case stats::GroupType::System:
|
||||||
|
return "system";
|
||||||
|
case stats::GroupType::Client:
|
||||||
|
return "client";
|
||||||
|
case stats::GroupType::Http:
|
||||||
|
return "http";
|
||||||
|
case stats::GroupType::Vst:
|
||||||
|
return "vst";
|
||||||
|
case stats::GroupType::Server:
|
||||||
|
return "server";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stats::Group::toVPack(velocypack::Builder& b) const {
|
||||||
|
b.add("group", VPackValue(stats::fromGroupType(type)));
|
||||||
|
b.add("name", VPackValue(name));
|
||||||
|
b.add("description", VPackValue(description));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string stats::fromFigureType(stats::FigureType t) {
|
||||||
|
switch (t) {
|
||||||
|
case stats::FigureType::Current:
|
||||||
|
return "current";
|
||||||
|
case stats::FigureType::Accumulated:
|
||||||
|
return "accumulated";
|
||||||
|
case stats::FigureType::Distribution:
|
||||||
|
return "distribution";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string stats::fromUnit(stats::Unit u) {
|
||||||
|
switch (u) {
|
||||||
|
case stats::Unit::Seconds:
|
||||||
|
return "seconds";
|
||||||
|
case stats::Unit::Bytes:
|
||||||
|
return "bytes";
|
||||||
|
case stats::Unit::Percent:
|
||||||
|
return "percent";
|
||||||
|
case stats::Unit::Number:
|
||||||
|
return "number";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stats::Figure::toVPack(velocypack::Builder& b) const {
|
||||||
|
b.add("group", VPackValue(stats::fromGroupType(groupType)));
|
||||||
|
b.add("identifier", VPackValue(identifier));
|
||||||
|
b.add("name", VPackValue(name));
|
||||||
|
b.add("description", VPackValue(description));
|
||||||
|
b.add("type", VPackValue(stats::fromFigureType(type)));
|
||||||
|
if (type == stats::FigureType::Distribution) {
|
||||||
|
TRI_ASSERT(!cuts.empty());
|
||||||
|
b.add("cuts", VPackValue(VPackValueType::Array, true));
|
||||||
|
for (double cut : cuts) {
|
||||||
|
b.add(VPackValue(cut));
|
||||||
|
}
|
||||||
|
b.close();
|
||||||
|
}
|
||||||
|
b.add("units", VPackValue(stats::fromUnit(units)));
|
||||||
|
}
|
||||||
|
|
||||||
|
stats::Descriptions::Descriptions()
|
||||||
|
: _requestTimeCuts({0.01, 0.05, 0.1, 0.2, 0.5, 1.0}),
|
||||||
|
_connectionTimeCuts({0.1, 1.0, 60.0}),
|
||||||
|
_bytesSendCuts({250, 1000, 2 * 1000, 5 * 1000, 10 * 1000}),
|
||||||
|
_bytesReceivedCuts({250, 1000, 2 * 1000, 5 * 1000, 10 * 1000}) {
|
||||||
|
_groups.emplace_back(Group{stats::GroupType::System, "Process Statistics",
|
||||||
|
"Statistics about the ArangoDB process"});
|
||||||
|
_groups.emplace_back(Group{stats::GroupType::Client,
|
||||||
|
"Client Connection Statistics",
|
||||||
|
"Statistics about the connections."});
|
||||||
|
_groups.emplace_back(Group{stats::GroupType::Http, "HTTP Request Statistics",
|
||||||
|
"Statistics about the HTTP requests."});
|
||||||
|
_groups.emplace_back(Group{stats::GroupType::Server, "Server Statistics",
|
||||||
|
"Statistics about the ArangoDB server"});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::System,
|
||||||
|
"userTime",
|
||||||
|
"User Time",
|
||||||
|
"Amount of time that this process has been "
|
||||||
|
"scheduled in user mode, measured in seconds.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Seconds,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::System,
|
||||||
|
"systemTime",
|
||||||
|
"System Time",
|
||||||
|
"Amount of time that this process has been "
|
||||||
|
"scheduled in kernel mode, measured in seconds.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Seconds,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::System,
|
||||||
|
"numberOfThreads",
|
||||||
|
"Number of Threads",
|
||||||
|
"Number of threads in the arangod process.",
|
||||||
|
stats::FigureType::Current,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{
|
||||||
|
stats::GroupType::System,
|
||||||
|
"residentSize",
|
||||||
|
"Resident Set Size",
|
||||||
|
"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.",
|
||||||
|
stats::FigureType::Current,
|
||||||
|
stats::Unit::Bytes,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::System,
|
||||||
|
"residentSizePercent",
|
||||||
|
"Resident Set Size",
|
||||||
|
"The percentage of physical memory used by the "
|
||||||
|
"process as resident set size.",
|
||||||
|
stats::FigureType::Current,
|
||||||
|
stats::Unit::Percent,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::System,
|
||||||
|
"virtualSize",
|
||||||
|
"Virtual Memory Size",
|
||||||
|
"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.",
|
||||||
|
stats::FigureType::Current,
|
||||||
|
stats::Unit::Bytes,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::System,
|
||||||
|
"minorPageFaults",
|
||||||
|
"Minor Page Faults",
|
||||||
|
"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.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{
|
||||||
|
stats::GroupType::System,
|
||||||
|
"majorPageFaults",
|
||||||
|
"Major Page Faults",
|
||||||
|
"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.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
// .............................................................................
|
||||||
|
// client statistics
|
||||||
|
// .............................................................................
|
||||||
|
|
||||||
|
_figures.emplace_back(
|
||||||
|
Figure{stats::GroupType::Client,
|
||||||
|
"httpConnections",
|
||||||
|
"Client Connections",
|
||||||
|
"The number of connections that are currently open.",
|
||||||
|
stats::FigureType::Current,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{
|
||||||
|
stats::GroupType::Client, "totalTime", "Total Time",
|
||||||
|
"Total time needed to answer a request.", stats::FigureType::Distribution,
|
||||||
|
// cuts: internal.requestTimeDistribution,
|
||||||
|
stats::Unit::Seconds, _requestTimeCuts});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Client, "requestTime",
|
||||||
|
"Request Time",
|
||||||
|
"Request time needed to answer a request.",
|
||||||
|
stats::FigureType::Distribution,
|
||||||
|
// cuts: internal.requestTimeDistribution,
|
||||||
|
stats::Unit::Seconds, _requestTimeCuts});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{
|
||||||
|
stats::GroupType::Client, "queueTime", "Queue Time",
|
||||||
|
"Queue time needed to answer a request.", stats::FigureType::Distribution,
|
||||||
|
// cuts: internal.requestTimeDistribution,
|
||||||
|
stats::Unit::Seconds, _requestTimeCuts});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Client, "bytesSent",
|
||||||
|
"Bytes Sent", "Bytes sents for a request.",
|
||||||
|
stats::FigureType::Distribution,
|
||||||
|
// cuts: internal.bytesSentDistribution,
|
||||||
|
stats::Unit::Bytes, _bytesSendCuts});
|
||||||
|
|
||||||
|
_figures.emplace_back(
|
||||||
|
Figure{stats::GroupType::Client, "bytesReceived", "Bytes Received",
|
||||||
|
"Bytes receiveds for a request.", stats::FigureType::Distribution,
|
||||||
|
// cuts: internal.bytesReceivedDistribution,
|
||||||
|
stats::Unit::Bytes, _bytesReceivedCuts});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{
|
||||||
|
stats::GroupType::Client, "connectionTime", "Connection Time",
|
||||||
|
"Total connection time of a client.", stats::FigureType::Distribution,
|
||||||
|
// cuts: internal.connectionTimeDistribution,
|
||||||
|
stats::Unit::Seconds, _connectionTimeCuts});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Http,
|
||||||
|
"requestsTotal",
|
||||||
|
"Total requests",
|
||||||
|
"Total number of HTTP requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(
|
||||||
|
Figure{stats::GroupType::Http,
|
||||||
|
"requestsAsync",
|
||||||
|
"Async requests",
|
||||||
|
"Number of asynchronously executed HTTP requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Http,
|
||||||
|
"requestsGet",
|
||||||
|
"HTTP GET requests",
|
||||||
|
"Number of HTTP GET requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Http,
|
||||||
|
"requestsHead",
|
||||||
|
"HTTP HEAD requests",
|
||||||
|
"Number of HTTP HEAD requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Http,
|
||||||
|
"requestsPost",
|
||||||
|
"HTTP POST requests",
|
||||||
|
"Number of HTTP POST requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Http,
|
||||||
|
"requestsPut",
|
||||||
|
"HTTP PUT requests",
|
||||||
|
"Number of HTTP PUT requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Http,
|
||||||
|
"requestsPatch",
|
||||||
|
"HTTP PATCH requests",
|
||||||
|
"Number of HTTP PATCH requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Http,
|
||||||
|
"requestsDelete",
|
||||||
|
"HTTP DELETE requests",
|
||||||
|
"Number of HTTP DELETE requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Http,
|
||||||
|
"requestsOptions",
|
||||||
|
"HTTP OPTIONS requests",
|
||||||
|
"Number of HTTP OPTIONS requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Http,
|
||||||
|
"requestsOther",
|
||||||
|
"other HTTP requests",
|
||||||
|
"Number of other HTTP requests.",
|
||||||
|
stats::FigureType::Accumulated,
|
||||||
|
stats::Unit::Number,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
// .............................................................................
|
||||||
|
// server statistics
|
||||||
|
// .............................................................................
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Server,
|
||||||
|
"uptime",
|
||||||
|
"Server Uptime",
|
||||||
|
"Number of seconds elapsed since server start.",
|
||||||
|
stats::FigureType::Current,
|
||||||
|
stats::Unit::Seconds,
|
||||||
|
{}});
|
||||||
|
|
||||||
|
_figures.emplace_back(Figure{stats::GroupType::Server,
|
||||||
|
"physicalMemory",
|
||||||
|
"Physical Memory",
|
||||||
|
"Physical memory in bytes.",
|
||||||
|
stats::FigureType::Current,
|
||||||
|
stats::Unit::Bytes,
|
||||||
|
{}});
|
||||||
|
}
|
||||||
|
|
||||||
|
void stats::Descriptions::serverStatistics(velocypack::Builder& b) const {
|
||||||
|
ServerStatistics info = ServerStatistics::statistics();
|
||||||
|
b.add("uptime", VPackValue(info._uptime));
|
||||||
|
b.add("physicalMemory", VPackValue((double)TRI_PhysicalMemory));
|
||||||
|
|
||||||
|
V8DealerFeature* dealer =
|
||||||
|
application_features::ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
|
||||||
|
|
||||||
|
b.add("v8Context", VPackValue(VPackValueType::Object, true));
|
||||||
|
auto v8Counters = dealer->getCurrentContextNumbers();
|
||||||
|
b.add( "available", VPackValue(static_cast<int32_t>(v8Counters.available)));
|
||||||
|
b.add( "busy", VPackValue(static_cast<int32_t>(v8Counters.busy)));
|
||||||
|
b.add( "dirty", VPackValue(static_cast<int32_t>(v8Counters.dirty)));
|
||||||
|
b.add( "free", VPackValue(static_cast<int32_t>(v8Counters.free)));
|
||||||
|
b.add( "max", VPackValue(static_cast<int32_t>(v8Counters.max)));
|
||||||
|
b.close();
|
||||||
|
|
||||||
|
b.add("threads", VPackValue(VPackValueType::Object, true));
|
||||||
|
|
||||||
|
auto countersRaw = SchedulerFeature::SCHEDULER->getCounters();
|
||||||
|
b.add("running", VPackValue(static_cast<int32_t>(rest::Scheduler::numRunning(countersRaw))));
|
||||||
|
b.add("working", VPackValue(static_cast<int32_t>(rest::Scheduler::numWorking(countersRaw))));
|
||||||
|
b.add("blocked", VPackValue(static_cast<int32_t>(rest::Scheduler::numBlocked(countersRaw))));
|
||||||
|
b.add("queued", VPackValue(static_cast<int32_t>(SchedulerFeature::SCHEDULER->numQueued())));
|
||||||
|
b.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief fills the distribution
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void FillDistribution(VPackBuilder& b, std::string const& name,
|
||||||
|
basics::StatisticsDistribution const& dist) {
|
||||||
|
b.add(name, VPackValue(VPackValueType::Object, true));
|
||||||
|
b.add("sum", VPackValue(dist._total));
|
||||||
|
b.add("count", VPackValue((double)dist._count));
|
||||||
|
b.add("counts", VPackValue(VPackValueType::Array, true));
|
||||||
|
for (std::vector<uint64_t>::const_iterator i = dist._counts.begin();
|
||||||
|
i != dist._counts.end(); ++i) {
|
||||||
|
b.add(VPackValue(*i));
|
||||||
|
}
|
||||||
|
b.close();
|
||||||
|
b.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stats::Descriptions::clientStatistics(velocypack::Builder& b) const {
|
||||||
|
basics::StatisticsCounter httpConnections;
|
||||||
|
basics::StatisticsCounter totalRequests;
|
||||||
|
std::vector<basics::StatisticsCounter> methodRequests;
|
||||||
|
basics::StatisticsCounter asyncRequests;
|
||||||
|
basics::StatisticsDistribution connectionTime;
|
||||||
|
|
||||||
|
// FIXME why are httpConnections in here ?
|
||||||
|
ConnectionStatistics::fill(httpConnections, totalRequests, methodRequests,
|
||||||
|
asyncRequests, connectionTime);
|
||||||
|
|
||||||
|
b.add("httpConnections", VPackValue((double)httpConnections._count));
|
||||||
|
FillDistribution(b, "connectionTime", connectionTime);
|
||||||
|
|
||||||
|
basics::StatisticsDistribution totalTime;
|
||||||
|
basics::StatisticsDistribution requestTime;
|
||||||
|
basics::StatisticsDistribution queueTime;
|
||||||
|
basics::StatisticsDistribution ioTime;
|
||||||
|
basics::StatisticsDistribution bytesSent;
|
||||||
|
basics::StatisticsDistribution bytesReceived;
|
||||||
|
|
||||||
|
RequestStatistics::fill(totalTime, requestTime, queueTime, ioTime, bytesSent,
|
||||||
|
bytesReceived);
|
||||||
|
|
||||||
|
FillDistribution(b, "totalTime", totalTime);
|
||||||
|
FillDistribution(b, "requestTime", requestTime);
|
||||||
|
FillDistribution(b, "queueTime", queueTime);
|
||||||
|
FillDistribution(b, "ioTime", ioTime);
|
||||||
|
FillDistribution(b, "bytesSent", bytesSent);
|
||||||
|
FillDistribution(b, "bytesReceived", bytesReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stats::Descriptions::httpStatistics(velocypack::Builder& b) const {
|
||||||
|
basics::StatisticsCounter httpConnections;
|
||||||
|
basics::StatisticsCounter totalRequests;
|
||||||
|
std::vector<basics::StatisticsCounter> methodRequests;
|
||||||
|
basics::StatisticsCounter asyncRequests;
|
||||||
|
basics::StatisticsDistribution connectionTime;
|
||||||
|
|
||||||
|
ConnectionStatistics::fill(httpConnections, totalRequests, methodRequests,
|
||||||
|
asyncRequests, connectionTime);
|
||||||
|
|
||||||
|
// request counters
|
||||||
|
b.add("requestsTotal", VPackValue((double)totalRequests._count));
|
||||||
|
b.add("requestsAsync", VPackValue((double)asyncRequests._count));
|
||||||
|
b.add("requestsGet", VPackValue((double)methodRequests[(int)rest::RequestType::GET]._count));
|
||||||
|
b.add("requestsHead", VPackValue((double)methodRequests[(int)rest::RequestType::HEAD]._count));
|
||||||
|
b.add("requestsPost", VPackValue((double)methodRequests[(int)rest::RequestType::POST]._count));
|
||||||
|
b.add("requestsPut", VPackValue((double)methodRequests[(int)rest::RequestType::PUT]._count));
|
||||||
|
b.add("requestsPatch", VPackValue((double)methodRequests[(int)rest::RequestType::PATCH]._count));
|
||||||
|
b.add("requestsDelete", VPackValue((double)methodRequests[(int)rest::RequestType::DELETE_REQ]._count));
|
||||||
|
b.add("requestsOptions", VPackValue((double)methodRequests[(int)rest::RequestType::OPTIONS]._count));
|
||||||
|
b.add("requestsOther", VPackValue((double)methodRequests[(int)rest::RequestType::ILLEGAL]._count));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void stats::Descriptions::processStatistics(VPackBuilder& b) const {
|
||||||
|
ProcessInfo info = TRI_ProcessInfoSelf();
|
||||||
|
double rss = (double)info._residentSize;
|
||||||
|
double rssp = 0;
|
||||||
|
|
||||||
|
if (TRI_PhysicalMemory != 0) {
|
||||||
|
rssp = rss / TRI_PhysicalMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
b.add("minorPageFaults", VPackValue((double)info._minorPageFaults));
|
||||||
|
b.add("majorPageFaults", VPackValue((double)info._majorPageFaults));
|
||||||
|
b.add("userTime", VPackValue((double)info._userTime / (double)info._scClkTck));
|
||||||
|
b.add("systemTime", VPackValue((double)info._systemTime / (double)info._scClkTck));
|
||||||
|
b.add("numberOfThreads", VPackValue((double)info._numberThreads));
|
||||||
|
b.add("residentSize", VPackValue(rss));
|
||||||
|
b.add("residentSizePercent", VPackValue(rssp));
|
||||||
|
b.add("virtualSize", VPackValue((double)info._virtualSize));
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2018 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 Simon Grätzer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef ARANGOD_STATISTICS_DESCRIPTIONS_H
|
||||||
|
#define ARANGOD_STATISTICS_DESCRIPTIONS_H 1
|
||||||
|
|
||||||
|
#include <velocypack/Builder.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace arangodb {
|
||||||
|
namespace stats {
|
||||||
|
|
||||||
|
enum class GroupType { System, Client, Http, Vst, Server };
|
||||||
|
|
||||||
|
std::string fromGroupType(stats::GroupType);
|
||||||
|
|
||||||
|
struct Group {
|
||||||
|
stats::GroupType type;
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void toVPack(velocypack::Builder&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class FigureType : char { Current, Accumulated, Distribution };
|
||||||
|
|
||||||
|
std::string fromFigureType(stats::FigureType);
|
||||||
|
|
||||||
|
enum class Unit : char { Seconds, Bytes, Percent, Number };
|
||||||
|
|
||||||
|
std::string fromUnit(stats::Unit);
|
||||||
|
|
||||||
|
struct Figure {
|
||||||
|
stats::GroupType groupType;
|
||||||
|
std::string identifier;
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
stats::FigureType type;
|
||||||
|
stats::Unit units;
|
||||||
|
|
||||||
|
std::vector<double> cuts;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void toVPack(velocypack::Builder&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Descriptions final {
|
||||||
|
|
||||||
|
public:
|
||||||
|
Descriptions();
|
||||||
|
|
||||||
|
std::vector<stats::Group> const& groups() const { return _groups; }
|
||||||
|
|
||||||
|
std::vector<stats::Figure> const& figures() const {
|
||||||
|
return _figures;
|
||||||
|
}
|
||||||
|
|
||||||
|
void serverStatistics(velocypack::Builder&) const;
|
||||||
|
void clientStatistics(velocypack::Builder&) const;
|
||||||
|
void httpStatistics(velocypack::Builder&) const;
|
||||||
|
void processStatistics(velocypack::Builder&) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<double> _requestTimeCuts;
|
||||||
|
std::vector<double> _connectionTimeCuts;
|
||||||
|
std::vector<double> _bytesSendCuts;
|
||||||
|
std::vector<double> _bytesReceivedCuts;
|
||||||
|
|
||||||
|
std::vector<stats::Group> _groups;
|
||||||
|
std::vector<stats::Figure> _figures;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -25,6 +25,7 @@
|
||||||
#include "ProgramOptions/ProgramOptions.h"
|
#include "ProgramOptions/ProgramOptions.h"
|
||||||
#include "ProgramOptions/Section.h"
|
#include "ProgramOptions/Section.h"
|
||||||
#include "Statistics/ConnectionStatistics.h"
|
#include "Statistics/ConnectionStatistics.h"
|
||||||
|
#include "Statistics/Descriptions.h"
|
||||||
#include "Statistics/RequestStatistics.h"
|
#include "Statistics/RequestStatistics.h"
|
||||||
#include "Statistics/ServerStatistics.h"
|
#include "Statistics/ServerStatistics.h"
|
||||||
#include "Statistics/StatisticsWorker.h"
|
#include "Statistics/StatisticsWorker.h"
|
||||||
|
@ -117,7 +118,9 @@ StatisticsFeature* StatisticsFeature::STATISTICS = nullptr;
|
||||||
|
|
||||||
StatisticsFeature::StatisticsFeature(
|
StatisticsFeature::StatisticsFeature(
|
||||||
application_features::ApplicationServer* server)
|
application_features::ApplicationServer* server)
|
||||||
: ApplicationFeature(server, "Statistics"), _statistics(true) {
|
: ApplicationFeature(server, "Statistics"),
|
||||||
|
_statistics(true),
|
||||||
|
_descriptions(new stats::Descriptions()) {
|
||||||
startsAfter("Logger");
|
startsAfter("Logger");
|
||||||
startsAfter("Aql");
|
startsAfter("Aql");
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,9 @@ extern StatisticsVector TRI_ConnectionTimeDistributionVectorStatistics;
|
||||||
extern StatisticsVector TRI_RequestTimeDistributionVectorStatistics;
|
extern StatisticsVector TRI_RequestTimeDistributionVectorStatistics;
|
||||||
extern std::vector<StatisticsCounter> TRI_MethodRequestsStatistics;
|
extern std::vector<StatisticsCounter> TRI_MethodRequestsStatistics;
|
||||||
}
|
}
|
||||||
|
namespace stats{
|
||||||
|
class Descriptions;
|
||||||
|
}
|
||||||
|
|
||||||
class StatisticsThread;
|
class StatisticsThread;
|
||||||
class StatisticsWorker;
|
class StatisticsWorker;
|
||||||
|
@ -70,12 +73,20 @@ class StatisticsFeature final
|
||||||
void start() override final;
|
void start() override final;
|
||||||
void unprepare() override final;
|
void unprepare() override final;
|
||||||
|
|
||||||
|
static stats::Descriptions const* descriptions() {
|
||||||
|
if (STATISTICS != nullptr) {
|
||||||
|
return STATISTICS->_descriptions.get();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void disableStatistics() { _statistics = false; }
|
void disableStatistics() { _statistics = false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _statistics;
|
bool _statistics;
|
||||||
|
|
||||||
|
std::unique_ptr<stats::Descriptions> _descriptions;
|
||||||
std::unique_ptr<StatisticsThread> _statisticsThread;
|
std::unique_ptr<StatisticsThread> _statisticsThread;
|
||||||
std::unique_ptr<StatisticsWorker> _statisticsWorker;
|
std::unique_ptr<StatisticsWorker> _statisticsWorker;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,6 @@ var internal = require('internal');
|
||||||
var console = require('console');
|
var console = require('console');
|
||||||
|
|
||||||
var actions = require('@arangodb/actions');
|
var actions = require('@arangodb/actions');
|
||||||
var arangodb = require('@arangodb');
|
|
||||||
|
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////////////////
|
||||||
// / @brief was docuBlock JSF_get_admin_time
|
// / @brief was docuBlock JSF_get_admin_time
|
||||||
|
@ -47,375 +46,6 @@ actions.defineHttp({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
|
||||||
// / @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_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_execute
|
// / @brief was docuBlock JSF_post_admin_execute
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in New Issue