[rpc] Add logging RPC
Adds an RPC to get and set currently active logging categories.
This commit is contained in:
parent
4d9950d3bc
commit
5255aca3f4
4 changed files with 83 additions and 3 deletions
|
@ -113,6 +113,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "getmempoolancestors", 1, "verbose" },
|
||||
{ "getmempooldescendants", 1, "verbose" },
|
||||
{ "bumpfee", 1, "options" },
|
||||
{ "logging", 0, "include" },
|
||||
{ "logging", 1, "exclude" },
|
||||
// Echo with conversion (For testing only)
|
||||
{ "echojson", 0, "arg0" },
|
||||
{ "echojson", 1, "arg1" },
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
if (request.fHelp)
|
||||
|
@ -582,6 +635,7 @@ static const CRPCCommand commands[] =
|
|||
{ "hidden", "setmocktime", &setmocktime, true, {"timestamp"}},
|
||||
{ "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", "logging", &logging, true, {"include", "exclude"}},
|
||||
};
|
||||
|
||||
void RegisterMiscRPCCommands(CRPCTable &t)
|
||||
|
|
17
src/util.cpp
17
src/util.cpp
|
@ -118,7 +118,7 @@ bool fLogIPs = DEFAULT_LOGIPS;
|
|||
std::atomic<bool> fReopenDebugLog(false);
|
||||
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);
|
||||
|
||||
/** Init OpenSSL library multithreading support */
|
||||
|
@ -295,6 +295,21 @@ std::string ListLogCategories()
|
|||
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
|
||||
* suppress printing of the timestamp when multiple calls are made that don't
|
||||
|
|
11
src/util.h
11
src/util.h
|
@ -69,6 +69,12 @@ inline std::string _(const char* psz)
|
|||
void SetupEnvironment();
|
||||
bool SetupNetworking();
|
||||
|
||||
struct CLogCategoryActive
|
||||
{
|
||||
std::string category;
|
||||
bool active;
|
||||
};
|
||||
|
||||
namespace BCLog {
|
||||
enum LogFlags : uint32_t {
|
||||
NONE = 0,
|
||||
|
@ -102,9 +108,12 @@ static inline bool LogAcceptCategory(uint32_t category)
|
|||
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();
|
||||
|
||||
/** 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 */
|
||||
bool GetLogCategory(uint32_t *f, const std::string *str);
|
||||
|
||||
|
|
Loading…
Reference in a new issue