mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-25 22:34:27 +00:00
Merge #10150: [rpc] Add logging rpc
7fd50c3 allow libevent logging to be updated during runtime (John Newbery) 5255aca [rpc] Add logging RPC (John Newbery) 4d9950d Set BCLog::LIBEVENT correctly for old libevent versions. (John Newbery) Tree-SHA512: d6788a7205372c0528da71eca052910dfb055f2940ca884f422ff3db66e23a2b49c6a15b8f27d5255554fe5c5a928f5dd903fdc63b0bd6c8fa7783e77bb30fe8
This commit is contained in:
commit
350b22497c
@ -97,7 +97,7 @@ endif
|
|||||||
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
||||||
test_test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_CFLAGS)
|
test_test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_CFLAGS)
|
||||||
test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||||
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS)
|
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
|
||||||
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
|
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
|
||||||
|
@ -384,15 +384,13 @@ bool InitHTTPServer()
|
|||||||
|
|
||||||
// Redirect libevent's logging to our own log
|
// Redirect libevent's logging to our own log
|
||||||
event_set_log_callback(&libevent_log_cb);
|
event_set_log_callback(&libevent_log_cb);
|
||||||
#if LIBEVENT_VERSION_NUMBER >= 0x02010100
|
// Update libevent's log handling. Returns false if our version of
|
||||||
// If -debug=libevent, set full libevent debugging.
|
// libevent doesn't support debug logging, in which case we should
|
||||||
// Otherwise, disable all libevent debugging.
|
// clear the BCLog::LIBEVENT flag.
|
||||||
if (LogAcceptCategory(BCLog::LIBEVENT)) {
|
if (!UpdateHTTPServerLogging(logCategories & BCLog::LIBEVENT)) {
|
||||||
event_enable_debug_logging(EVENT_DBG_ALL);
|
logCategories &= ~BCLog::LIBEVENT;
|
||||||
} else {
|
|
||||||
event_enable_debug_logging(EVENT_DBG_NONE);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
evthread_use_windows_threads();
|
evthread_use_windows_threads();
|
||||||
#else
|
#else
|
||||||
@ -435,6 +433,20 @@ bool InitHTTPServer()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UpdateHTTPServerLogging(bool enable) {
|
||||||
|
#if LIBEVENT_VERSION_NUMBER >= 0x02010100
|
||||||
|
if (enable) {
|
||||||
|
event_enable_debug_logging(EVENT_DBG_ALL);
|
||||||
|
} else {
|
||||||
|
event_enable_debug_logging(EVENT_DBG_NONE);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
// Can't update libevent logging if version < 02010100
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
std::thread threadHTTP;
|
std::thread threadHTTP;
|
||||||
std::future<bool> threadResult;
|
std::future<bool> threadResult;
|
||||||
|
|
||||||
|
@ -32,6 +32,10 @@ void InterruptHTTPServer();
|
|||||||
/** Stop HTTP server */
|
/** Stop HTTP server */
|
||||||
void StopHTTPServer();
|
void StopHTTPServer();
|
||||||
|
|
||||||
|
/** Change logging level for libevent. Removes BCLog::LIBEVENT from logCategories if
|
||||||
|
* libevent doesn't support debug logging.*/
|
||||||
|
bool UpdateHTTPServerLogging(bool enable);
|
||||||
|
|
||||||
/** Handler for requests to a certain HTTP path */
|
/** Handler for requests to a certain HTTP path */
|
||||||
typedef std::function<bool(HTTPRequest* req, const std::string &)> HTTPRequestHandler;
|
typedef std::function<bool(HTTPRequest* req, const std::string &)> HTTPRequestHandler;
|
||||||
/** Register handler for prefix.
|
/** Register handler for prefix.
|
||||||
|
@ -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" },
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "clientversion.h"
|
#include "clientversion.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "validation.h"
|
#include "validation.h"
|
||||||
|
#include "httpserver.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "netbase.h"
|
#include "netbase.h"
|
||||||
#include "rpc/blockchain.h"
|
#include "rpc/blockchain.h"
|
||||||
@ -555,6 +556,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)
|
UniValue echo(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
if (request.fHelp)
|
if (request.fHelp)
|
||||||
@ -581,7 +649,8 @@ static const CRPCCommand commands[] =
|
|||||||
/* Not shown in help */
|
/* Not shown in help */
|
||||||
{ "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)
|
||||||
|
17
src/util.cpp
17
src/util.cpp
@ -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. */
|
||||||
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
|
||||||
|
11
src/util.h
11
src/util.h
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user