Skip to content

Commit

Permalink
Create health_check rpc
Browse files Browse the repository at this point in the history
* Gives a summary of the health of the node:
  Healthy, Warning, or Critical

* Last validated ledger age:
  <7s is Healthy,
  7s to 20s is Warning
  > 20s is Critcal

* If amendment blocked, Critical

* Number of peers:
  > 7 is Healthy
  1 to 7 is Warning
  0 is Critical

* server state:
  One of full, validating or proposing is Healthy
  One of syncing, tracking or connected is Warning
  All other states are Critical

* load factor:
  <= 100 is Healthy
  101 to 999 is Warning
  >= 1000 is Critical

* If not Healthy, info field contains data that is considered not
  Healthy.

Fixes: XRPLF#2809
  • Loading branch information
HowardHinnant committed Apr 16, 2020
1 parent 4f422f6 commit 08f51a6
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 0 deletions.
1 change: 1 addition & 0 deletions Builds/CMake/RippledCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@ target_sources (rippled PRIVATE
src/ripple/rpc/handlers/FetchInfo.cpp
src/ripple/rpc/handlers/GatewayBalances.cpp
src/ripple/rpc/handlers/GetCounts.cpp
src/ripple/rpc/handlers/HealthCheck.cpp
src/ripple/rpc/handlers/LedgerAccept.cpp
src/ripple/rpc/handlers/LedgerCleanerHandler.cpp
src/ripple/rpc/handlers/LedgerClosed.cpp
Expand Down
1 change: 1 addition & 0 deletions src/ripple/app/main/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ void printHelp (const po::options_description& desc)
" fetch_info [clear]\n"
" gateway_balances [<ledger>] <issuer_account> [ <hotwallet> [ <hotwallet> ]]\n"
" get_counts\n"
" health_check\n"
" json <method> <json>\n"
" ledger [<id>|current|closed|validated] [full]\n"
" ledger_accept\n"
Expand Down
1 change: 1 addition & 0 deletions src/ripple/net/impl/RPCCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,7 @@ class RPCParser
{ "fetch_info", &RPCParser::parseFetchInfo, 0, 1 },
{ "gateway_balances", &RPCParser::parseGatewayBalances, 1, -1 },
{ "get_counts", &RPCParser::parseGetCounts, 0, 1 },
{ "health_check", &RPCParser::parseAsIs, 0, 0 },
{ "json", &RPCParser::parseJson, 2, 2 },
{ "json2", &RPCParser::parseJson2, 1, 1 },
{ "ledger", &RPCParser::parseLedger, 0, 2 },
Expand Down
1 change: 1 addition & 0 deletions src/ripple/rpc/handlers/Handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Json::Value doFee (RPC::JsonContext&);
Json::Value doFetchInfo (RPC::JsonContext&);
Json::Value doGatewayBalances (RPC::JsonContext&);
Json::Value doGetCounts (RPC::JsonContext&);
Json::Value doHealthCheck (RPC::JsonContext&);
Json::Value doLedgerAccept (RPC::JsonContext&);
Json::Value doLedgerCleaner (RPC::JsonContext&);
Json::Value doLedgerClosed (RPC::JsonContext&);
Expand Down
119 changes: 119 additions & 0 deletions src/ripple/rpc/handlers/HealthCheck.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================

#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/json/json_value.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/jss.h>
#include <ripple/rpc/Context.h>
#include <ripple/rpc/impl/TransactionSign.h>
#include <ripple/rpc/Role.h>

namespace ripple {

Json::Value
doHealthCheck(RPC::JsonContext& context)
{
bool constexpr humanReadable = true;
bool constexpr noAdmin = false;
bool constexpr noCounters = false;
auto info = context.netOps.getServerInfo(
humanReadable, noAdmin, noCounters);

int last_validated_ledger_age = std::numeric_limits<int>::max();
if (info.isMember("validated_ledger"))
last_validated_ledger_age = info["validated_ledger"]["age"].asInt();
bool amendment_blocked = false;
if (info.isMember("amendment_blocked"))
amendment_blocked = true;
int number_peers = info["peers"].asInt();
std::string server_state = info["server_state"].asString();
auto load_factor = info["load_factor"].asDouble();

Json::Value ret = Json::objectValue;
enum {healthy, warning, critical};
int health = healthy;
auto set_health = [&health](int state)
{
if (health < state)
health = state;
};

if (last_validated_ledger_age >= 7)
{
ret[jss::info]["validated_ledger"] = last_validated_ledger_age;
if (last_validated_ledger_age < 20)
set_health(warning);
else
set_health(critical);
}

if (amendment_blocked)
{
ret[jss::info]["amendment_blocked"] = true;
set_health(critical);
}

if (number_peers <= 7)
{
ret[jss::info]["peers"] = number_peers;
if (number_peers != 0)
set_health(warning);
else
set_health(critical);
}

if (!(server_state == "full" || server_state == "validating" ||
server_state == "proposing"))
{
ret[jss::info]["server_state"] = server_state;
if (server_state == "syncing" || server_state == "tracking" ||
server_state == "connected")
{
set_health(warning);
}
else
set_health(critical);
}

if (load_factor > 100)
{
ret[jss::info]["load_factor"] = load_factor;
if (load_factor < 1000)
set_health(warning);
else
set_health(critical);
}

switch (health)
{
case healthy:
ret["health"] = "Healthy";
break;
case warning:
ret["health"] = "Warning";
break;
default:
ret["health"] = "Critical";
break;
}
return ret;
}

} // ripple
1 change: 1 addition & 0 deletions src/ripple/rpc/impl/Handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Handler const handlerArray[] {
{ "feature", byRef (&doFeature), Role::ADMIN, NO_CONDITION },
{ "fee", byRef (&doFee), Role::USER, NEEDS_CURRENT_LEDGER },
{ "fetch_info", byRef (&doFetchInfo), Role::ADMIN, NO_CONDITION },
{ "health_check", byRef (&doHealthCheck), Role::USER, NO_CONDITION },
{ "ledger_accept", byRef (&doLedgerAccept), Role::ADMIN, NEEDS_CURRENT_LEDGER },
{ "ledger_cleaner", byRef (&doLedgerCleaner), Role::ADMIN, NEEDS_NETWORK_CONNECTION },
{ "ledger_closed", byRef (&doLedgerClosed), Role::USER, NO_CONDITION },
Expand Down

0 comments on commit 08f51a6

Please sign in to comment.