diff options
Diffstat (limited to 'src/rpc/misc.cpp')
-rw-r--r-- | src/rpc/misc.cpp | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index de1bbe62e5..1f973a0c18 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -4,11 +4,14 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" +#include "chain.h" #include "clientversion.h" #include "init.h" #include "validation.h" +#include "httpserver.h" #include "net.h" #include "netbase.h" +#include "rpc/blockchain.h" #include "rpc/server.h" #include "timedata.h" #include "util.h" @@ -554,6 +557,73 @@ 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]); + } + + // Update libevent logging if BCLog::LIBEVENT has changed. + // If the library version doesn't allow it, UpdateHTTPServerLogging() returns false, + // in which case we should clear the BCLog::LIBEVENT flag. + // Throw an error if the user has explicitly asked to change only the libevent + // flag and it failed. + uint32_t changedLogCategories = originalLogCategories ^ logCategories; + if (changedLogCategories & BCLog::LIBEVENT) { + if (!UpdateHTTPServerLogging(logCategories & BCLog::LIBEVENT)) { + logCategories &= ~BCLog::LIBEVENT; + if (changedLogCategories == BCLog::LIBEVENT) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "libevent logging cannot be updated when using libevent before v2.1.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) @@ -580,7 +650,8 @@ static const CRPCCommand commands[] = /* Not shown in help */ { "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", "echojson", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, + { "hidden", "logging", &logging, true, {"include", "exclude"}}, }; void RegisterMiscRPCCommands(CRPCTable &t) |