[rpc] Add logging RPC

Adds an RPC to get and set currently active logging categories.
This commit is contained in:
John Newbery 2017-04-03 13:39:11 -04:00
parent 4d9950d3bc
commit 5255aca3f4
4 changed files with 83 additions and 3 deletions

View file

@ -113,6 +113,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "getmempoolancestors", 1, "verbose" }, { "getmempoolancestors", 1, "verbose" },
{ "getmempooldescendants", 1, "verbose" }, { "getmempooldescendants", 1, "verbose" },
{ "bumpfee", 1, "options" }, { "bumpfee", 1, "options" },
{ "logging", 0, "include" },
{ "logging", 1, "exclude" },
// Echo with conversion (For testing only) // Echo with conversion (For testing only)
{ "echojson", 0, "arg0" }, { "echojson", 0, "arg0" },
{ "echojson", 1, "arg1" }, { "echojson", 1, "arg1" },

View file

@ -555,6 +555,59 @@ UniValue getmemoryinfo(const JSONRPCRequest& request)
} }
} }
uint32_t getCategoryMask(UniValue cats) {
cats = cats.get_array();
uint32_t mask = 0;
for (unsigned int i = 0; i < cats.size(); ++i) {
uint32_t flag = 0;
std::string cat = cats[i].get_str();
if (!GetLogCategory(&flag, &cat)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown logging category " + cat);
}
mask |= flag;
}
return mask;
}
UniValue logging(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() > 2) {
throw std::runtime_error(
"logging [include,...] <exclude>\n"
"Gets and sets the logging configuration.\n"
"When called without an argument, returns the list of categories that are currently being debug logged.\n"
"When called with arguments, adds or removes categories from debug logging.\n"
"The valid logging categories are: " + ListLogCategories() + "\n"
"libevent logging is configured on startup and cannot be modified by this RPC during runtime."
"Arguments:\n"
"1. \"include\" (array of strings) add debug logging for these categories.\n"
"2. \"exclude\" (array of strings) remove debug logging for these categories.\n"
"\nResult: <categories> (string): a list of the logging categories that are active.\n"
"\nExamples:\n"
+ HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"")
+ HelpExampleRpc("logging", "[\"all\"], \"[libevent]\"")
);
}
uint32_t originalLogCategories = logCategories;
if (request.params.size() > 0 && request.params[0].isArray()) {
logCategories |= getCategoryMask(request.params[0]);
}
if (request.params.size() > 1 && request.params[1].isArray()) {
logCategories &= ~getCategoryMask(request.params[1]);
}
UniValue result(UniValue::VOBJ);
std::vector<CLogCategoryActive> vLogCatActive = ListActiveLogCategories();
for (const auto& logCatActive : vLogCatActive) {
result.pushKV(logCatActive.category, logCatActive.active);
}
return result;
}
UniValue echo(const JSONRPCRequest& request) UniValue echo(const JSONRPCRequest& request)
{ {
if (request.fHelp) if (request.fHelp)
@ -582,6 +635,7 @@ static const CRPCCommand commands[] =
{ "hidden", "setmocktime", &setmocktime, true, {"timestamp"}}, { "hidden", "setmocktime", &setmocktime, true, {"timestamp"}},
{ "hidden", "echo", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, { "hidden", "echo", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
{ "hidden", "echojson", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, { "hidden", "echojson", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
{ "hidden", "logging", &logging, true, {"include", "exclude"}},
}; };
void RegisterMiscRPCCommands(CRPCTable &t) void RegisterMiscRPCCommands(CRPCTable &t)

View file

@ -118,7 +118,7 @@ bool fLogIPs = DEFAULT_LOGIPS;
std::atomic<bool> fReopenDebugLog(false); std::atomic<bool> fReopenDebugLog(false);
CTranslationInterface translationInterface; CTranslationInterface translationInterface;
/** Log categories bitfield. Leveldb/libevent need special handling if their flags are changed at runtime. */ /** Log categories bitfield. libevent needs special handling if their flags are changed at runtime. */
std::atomic<uint32_t> logCategories(0); std::atomic<uint32_t> logCategories(0);
/** Init OpenSSL library multithreading support */ /** Init OpenSSL library multithreading support */
@ -295,6 +295,21 @@ std::string ListLogCategories()
return ret; return ret;
} }
std::vector<CLogCategoryActive> ListActiveLogCategories()
{
std::vector<CLogCategoryActive> ret;
for (unsigned int i = 0; i < ARRAYLEN(LogCategories); i++) {
// Omit the special cases.
if (LogCategories[i].flag != BCLog::NONE && LogCategories[i].flag != BCLog::ALL) {
CLogCategoryActive catActive;
catActive.category = LogCategories[i].category;
catActive.active = LogAcceptCategory(LogCategories[i].flag);
ret.push_back(catActive);
}
}
return ret;
}
/** /**
* fStartedNewLine is a state variable held by the calling context that will * fStartedNewLine is a state variable held by the calling context that will
* suppress printing of the timestamp when multiple calls are made that don't * suppress printing of the timestamp when multiple calls are made that don't

View file

@ -69,6 +69,12 @@ inline std::string _(const char* psz)
void SetupEnvironment(); void SetupEnvironment();
bool SetupNetworking(); bool SetupNetworking();
struct CLogCategoryActive
{
std::string category;
bool active;
};
namespace BCLog { namespace BCLog {
enum LogFlags : uint32_t { enum LogFlags : uint32_t {
NONE = 0, NONE = 0,
@ -102,9 +108,12 @@ static inline bool LogAcceptCategory(uint32_t category)
return (logCategories.load(std::memory_order_relaxed) & category) != 0; return (logCategories.load(std::memory_order_relaxed) & category) != 0;
} }
/** Returns a string with the supported log categories */ /** Returns a string with the log categories. */
std::string ListLogCategories(); std::string ListLogCategories();
/** Returns a vector of the active log categories. */
std::vector<CLogCategoryActive> ListActiveLogCategories();
/** Return true if str parses as a log category and set the flags in f */ /** Return true if str parses as a log category and set the flags in f */
bool GetLogCategory(uint32_t *f, const std::string *str); bool GetLogCategory(uint32_t *f, const std::string *str);