mirror of https://gitee.com/bigwinds/arangodb
added HTTP REST APIs for online loglevel adjustments:
- GET `/_admin/log/level` returns the current loglevel settings - PUT `/_admin/log/level` modifies the current loglevel settings
This commit is contained in:
parent
2df53c92ce
commit
504b102268
|
@ -1,6 +1,11 @@
|
|||
devel
|
||||
-----
|
||||
|
||||
* added HTTP REST APIs for online loglevel adjustments:
|
||||
|
||||
- GET `/_admin/log/level` returns the current loglevel settings
|
||||
- PUT `/_admin/log/level` modifies the current loglevel settings
|
||||
|
||||
* changed default for keepNull of modifyVertex/modifyEdge to true in Gharial
|
||||
|
||||
* renamed `maximalSize` attribute in parameter.json files to `journalSize`
|
||||
|
|
|
@ -6,7 +6,11 @@ monitoring of the server.
|
|||
|
||||
<!-- lib/Admin/RestAdminLogHandler.cpp -->
|
||||
|
||||
@startDocuBlock JSF_get_admin_modules_flush
|
||||
@startDocuBlock JSF_get_admin_log
|
||||
|
||||
@startDocuBlock JSF_get_admin_loglevel
|
||||
|
||||
@startDocuBlock JSF_put_admin_loglevel
|
||||
|
||||
|
||||
<!-- js/actions/api-system.js -->
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
@startDocuBlock JSF_get_admin_modules_flush
|
||||
@brief returns the log files
|
||||
@startDocuBlock JSF_get_admin_log
|
||||
@brief returns the server logs
|
||||
|
||||
@RESTHEADER{GET /_admin/log, Read global logs from the server}
|
||||
|
||||
|
@ -65,3 +65,54 @@ is returned if the server cannot generate the result due to an out-of-memory
|
|||
error.
|
||||
@endDocuBlock
|
||||
|
||||
|
||||
@startDocuBlock JSF_get_admin_loglevel
|
||||
@brief returns the current loglevel settings
|
||||
|
||||
@RESTHEADER{GET /_admin/log/level, Return the current server loglevel}
|
||||
|
||||
@RESTDESCRIPTION
|
||||
Returns the server's current loglevel settings.
|
||||
The result is a JSON object with the log topics being the object keys, and
|
||||
the log levels being the object values.
|
||||
|
||||
@RESTRETURNCODES
|
||||
|
||||
@RESTRETURNCODE{200}
|
||||
is returned if the request is valid
|
||||
|
||||
@RESTRETURNCODE{500}
|
||||
is returned if the server cannot generate the result due to an out-of-memory
|
||||
error.
|
||||
@endDocuBlock
|
||||
|
||||
|
||||
@startDocuBlock JSF_put_admin_loglevel
|
||||
@brief modifies the current loglevel settings
|
||||
|
||||
@RESTHEADER{PUT /_admin/log/level, Modify and return the current server loglevel}
|
||||
|
||||
@RESTDESCRIPTION
|
||||
Modifies and returns the server's current loglevel settings.
|
||||
The request body must be a JSON object with the log topics being the object keys
|
||||
and the log levels being the object values.
|
||||
|
||||
The result is a JSON object with the adjusted log topics being the object keys, and
|
||||
the adjusted log levels being the object values.
|
||||
|
||||
@RESTRETURNCODES
|
||||
|
||||
@RESTRETURNCODE{200}
|
||||
is returned if the request is valid
|
||||
|
||||
@RESTRETURNCODE{400}
|
||||
is returned when the request body contains invalid JSON.
|
||||
|
||||
@RESTRETURNCODE{405}
|
||||
is returned when an invalid HTTP method is used.
|
||||
|
||||
@RESTRETURNCODE{500}
|
||||
is returned if the server cannot generate the result due to an out-of-memory
|
||||
error.
|
||||
@endDocuBlock
|
||||
|
||||
|
|
|
@ -521,7 +521,7 @@ void GeneralServerFeature::defineHandlers() {
|
|||
"/_admin/version", RestHandlerCreator<RestVersionHandler>::createNoData);
|
||||
|
||||
// further admin handlers
|
||||
_handlerFactory->addHandler(
|
||||
_handlerFactory->addPrefixHandler(
|
||||
"/_admin/log",
|
||||
RestHandlerCreator<arangodb::RestAdminLogHandler>::createNoData);
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "Logger/Logger.h"
|
||||
#include "Rest/GeneralRequest.h"
|
||||
|
||||
#include <velocypack/Exception.h>
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::basics;
|
||||
using namespace arangodb::rest;
|
||||
|
@ -72,6 +74,10 @@ RestHandler::status RestHandler::executeFull() {
|
|||
} catch (Exception const& ex) {
|
||||
requestStatisticsAgentSetExecuteError();
|
||||
handleError(ex);
|
||||
} catch (arangodb::velocypack::Exception const& ex) {
|
||||
requestStatisticsAgentSetExecuteError();
|
||||
Exception err(TRI_ERROR_INTERNAL, std::string("VPack error: ") + ex.what(), __FILE__, __LINE__);
|
||||
handleError(err);
|
||||
} catch (std::bad_alloc const& ex) {
|
||||
requestStatisticsAgentSetExecuteError();
|
||||
Exception err(TRI_ERROR_OUT_OF_MEMORY, ex.what(), __FILE__, __LINE__);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "RestAdminLogHandler.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Iterator.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include "Basics/StringUtils.h"
|
||||
|
@ -41,11 +42,18 @@ RestAdminLogHandler::RestAdminLogHandler(GeneralRequest* request,
|
|||
|
||||
bool RestAdminLogHandler::isDirect() const { return true; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief was docuBlock JSF_get_admin_modules_flush
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RestHandler::status RestAdminLogHandler::execute() {
|
||||
size_t const len = _request->suffix().size();
|
||||
|
||||
if (len == 0) {
|
||||
reportLogs();
|
||||
} else {
|
||||
setLogLevel();
|
||||
}
|
||||
return status::DONE;
|
||||
}
|
||||
|
||||
void RestAdminLogHandler::reportLogs() {
|
||||
// check the maximal log level to report
|
||||
bool found1;
|
||||
std::string const& upto =
|
||||
|
@ -86,7 +94,7 @@ RestHandler::status RestAdminLogHandler::execute() {
|
|||
TRI_ERROR_HTTP_BAD_PARAMETER,
|
||||
std::string("unknown '") + (found2 ? "level" : "upto") +
|
||||
"' log level: '" + logLevel + "'");
|
||||
return status::DONE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,6 +254,67 @@ RestHandler::status RestAdminLogHandler::execute() {
|
|||
// Has been ignored thus far
|
||||
// So ignore again
|
||||
}
|
||||
|
||||
return status::DONE;
|
||||
}
|
||||
|
||||
void RestAdminLogHandler::setLogLevel() {
|
||||
std::vector<std::string> const& suffix = _request->suffix();
|
||||
|
||||
// was validated earlier
|
||||
TRI_ASSERT(suffix.size() > 0);
|
||||
|
||||
if (suffix[0] != "level") {
|
||||
generateError(rest::ResponseCode::BAD,
|
||||
TRI_ERROR_HTTP_SUPERFLUOUS_SUFFICES,
|
||||
"superfluous suffix, expecting /_admin/log/level");
|
||||
return;
|
||||
}
|
||||
|
||||
auto const type = _request->requestType();
|
||||
|
||||
if (type == rest::RequestType::GET) {
|
||||
// report loglevel
|
||||
VPackBuilder builder;
|
||||
builder.openObject();
|
||||
auto const& levels = Logger::logLevelTopics();
|
||||
for (auto const& level : levels) {
|
||||
builder.add(level.first, VPackValue(Logger::translateLogLevel(level.second)));
|
||||
}
|
||||
builder.close();
|
||||
|
||||
generateResult(rest::ResponseCode::OK, builder.slice());
|
||||
} else if (type == rest::RequestType::PUT) {
|
||||
// set loglevel
|
||||
bool parseSuccess = true;
|
||||
std::shared_ptr<VPackBuilder> parsedBody = parseVelocyPackBody(&VPackOptions::Defaults, parseSuccess);
|
||||
if (!parseSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
VPackSlice slice = parsedBody->slice();
|
||||
if (slice.isString()) {
|
||||
Logger::setLogLevel(slice.copyString());
|
||||
} else if (slice.isObject()) {
|
||||
for (auto const& it : VPackObjectIterator(slice)) {
|
||||
if (it.value.isString()) {
|
||||
std::string const l = it.key.copyString() + "=" + it.value.copyString();
|
||||
Logger::setLogLevel(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now report current loglevel
|
||||
VPackBuilder builder;
|
||||
builder.openObject();
|
||||
auto const& levels = Logger::logLevelTopics();
|
||||
for (auto const& level : levels) {
|
||||
builder.add(level.first, VPackValue(Logger::translateLogLevel(level.second)));
|
||||
}
|
||||
builder.close();
|
||||
|
||||
generateResult(rest::ResponseCode::OK, builder.slice());
|
||||
} else {
|
||||
// invalid method
|
||||
generateError(rest::ResponseCode::METHOD_NOT_ALLOWED,
|
||||
TRI_ERROR_HTTP_METHOD_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,10 @@ class RestAdminLogHandler : public RestBaseHandler {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
status execute() override;
|
||||
|
||||
private:
|
||||
void reportLogs();
|
||||
void setLogLevel();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,25 @@ RestBaseHandler::RestBaseHandler(GeneralRequest* request,
|
|||
GeneralResponse* response)
|
||||
: RestHandler(request, response) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parses the body as VelocyPack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::shared_ptr<VPackBuilder> RestBaseHandler::parseVelocyPackBody(
|
||||
VPackOptions const* options, bool& success) {
|
||||
try {
|
||||
success = true;
|
||||
return _request->toVelocyPackBuilderPtr(options);
|
||||
} catch (VPackException const& e) {
|
||||
std::string errmsg("VPackError error: ");
|
||||
errmsg.append(e.what());
|
||||
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_CORRUPTED_JSON,
|
||||
errmsg);
|
||||
}
|
||||
success = false;
|
||||
return std::make_shared<VPackBuilder>();
|
||||
}
|
||||
|
||||
void RestBaseHandler::handleError(Exception const& ex) {
|
||||
generateError(GeneralResponse::responseCode(ex.code()), ex.code(), ex.what());
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace arangodb {
|
|||
class TransactionContext;
|
||||
|
||||
namespace velocypack {
|
||||
class Builder;
|
||||
struct Options;
|
||||
class Slice;
|
||||
}
|
||||
|
@ -66,6 +67,9 @@ class RestBaseHandler : public rest::RestHandler {
|
|||
void generateCanceled();
|
||||
|
||||
protected:
|
||||
/// @brief parses the body as VelocyPack
|
||||
std::shared_ptr<arangodb::velocypack::Builder> parseVelocyPackBody(arangodb::velocypack::Options const*, bool&);
|
||||
|
||||
template <typename Payload>
|
||||
void writeResult(Payload&&, arangodb::velocypack::Options const& options);
|
||||
};
|
||||
|
|
|
@ -636,25 +636,6 @@ bool RestVocbaseBaseHandler::extractBooleanParameter(char const* name,
|
|||
return def;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parses the body as VelocyPack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::shared_ptr<VPackBuilder> RestVocbaseBaseHandler::parseVelocyPackBody(
|
||||
VPackOptions const* options, bool& success) {
|
||||
try {
|
||||
success = true;
|
||||
return _request->toVelocyPackBuilderPtr(options);
|
||||
} catch (VPackException const& e) {
|
||||
std::string errmsg("VpackError error: ");
|
||||
errmsg.append(e.what());
|
||||
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_CORRUPTED_JSON,
|
||||
errmsg);
|
||||
}
|
||||
success = false;
|
||||
return std::make_shared<VPackBuilder>();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prepareExecute, to react to X-Arango-Nolock header
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -266,12 +266,6 @@ class RestVocbaseBaseHandler : public RestBaseHandler {
|
|||
|
||||
bool extractBooleanParameter(char const* name, bool def) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parses the body as VelocyPack
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::shared_ptr<VPackBuilder> parseVelocyPackBody(VPackOptions const*, bool&);
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief request context
|
||||
|
|
Loading…
Reference in New Issue