diff --git a/src/httpserver.h b/src/httpserver.h
--- a/src/httpserver.h
+++ b/src/httpserver.h
@@ -40,6 +40,12 @@
 /** Stop HTTP server */
 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 */
 typedef std::function<bool(Config &config, HTTPRequest *req,
                            const std::string &)>
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -8,6 +8,7 @@
 #include <chainparamsbase.h>
 #include <compat.h>
 #include <config.h>
+#include <logging.h>
 #include <netbase.h>
 #include <rpc/protocol.h> // For HTTP status codes
 #include <sync.h>
@@ -379,15 +380,14 @@
 
     // Redirect libevent's logging to our own log
     event_set_log_callback(&libevent_log_cb);
-#if LIBEVENT_VERSION_NUMBER >= 0x02010100
-    // If -debug=libevent, set full libevent debugging.
-    // Otherwise, disable all libevent debugging.
-    if (LogAcceptCategory(BCLog::LIBEVENT)) {
-        event_enable_debug_logging(EVENT_DBG_ALL);
-    } else {
-        event_enable_debug_logging(EVENT_DBG_NONE);
+    // Update libevent's log handling. Returns false if our version of
+    // libevent doesn't support debug logging, in which case we should
+    // clear the BCLog::LIBEVENT flag.
+    if (!UpdateHTTPServerLogging(
+            GetLogger().WillLogCategory(BCLog::LIBEVENT))) {
+        GetLogger().DisableCategory(BCLog::LIBEVENT);
     }
-#endif
+
 #ifdef WIN32
     evthread_use_windows_threads();
 #else
@@ -434,6 +434,20 @@
     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::future<bool> threadResult;
 static std::vector<std::thread> g_thread_http_workers;
diff --git a/src/logging.h b/src/logging.h
--- a/src/logging.h
+++ b/src/logging.h
@@ -23,6 +23,11 @@
 extern bool fLogIPs;
 extern const char *const DEFAULT_DEBUGLOGFILE;
 
+struct CLogCategoryActive {
+    std::string category;
+    bool active;
+};
+
 namespace BCLog {
 
 enum LogFlags : uint32_t {
@@ -64,8 +69,7 @@
     std::atomic_bool m_started_new_line{true};
 
     /**
-     * Log categories bitfield. Leveldb/libevent need special handling if their
-     * flags are changed at runtime.
+     * Log categories bitfield.
      */
     std::atomic<uint32_t> m_categories{0};
 
@@ -89,6 +93,8 @@
     bool OpenDebugLog();
     void ShrinkDebugFile();
 
+    uint32_t GetCategoryMask() const { return m_categories.load(); }
+
     void EnableCategory(LogFlags category);
     bool EnableCategory(const std::string &str);
     void DisableCategory(LogFlags category);
@@ -110,9 +116,12 @@
     return GetLogger().WillLogCategory(category);
 }
 
-/** 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 flag */
 bool GetLogCategory(BCLog::LogFlags &flag, const std::string &str);
 
diff --git a/src/logging.cpp b/src/logging.cpp
--- a/src/logging.cpp
+++ b/src/logging.cpp
@@ -125,6 +125,21 @@
     return ret;
 }
 
+std::vector<CLogCategoryActive> ListActiveLogCategories() {
+    std::vector<CLogCategoryActive> ret;
+    for (const CLogCategoryDesc &category_desc : LogCategories) {
+        // Omit the special cases.
+        if (category_desc.flag != BCLog::NONE &&
+            category_desc.flag != BCLog::ALL) {
+            CLogCategoryActive catActive;
+            catActive.category = category_desc.category;
+            catActive.active = LogAcceptCategory(category_desc.flag);
+            ret.push_back(catActive);
+        }
+    }
+    return ret;
+}
+
 BCLog::Logger::~Logger() {
     if (m_fileout) {
         fclose(m_fileout);
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -127,6 +127,8 @@
     {"getmempoolancestors", 1, "verbose"},
     {"getmempooldescendants", 1, "verbose"},
     {"disconnectnode", 1, "nodeid"},
+    {"logging", 0, "include"},
+    {"logging", 1, "exclude"},
     // Echo with conversion (For testing only)
     {"echojson", 0, "arg0"},
     {"echojson", 1, "arg1"},
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -7,8 +7,10 @@
 #include <clientversion.h>
 #include <config.h>
 #include <core_io.h>
+#include <httpserver.h>
 #include <init.h>
 #include <key_io.h>
+#include <logging.h>
 #include <net.h>
 #include <netbase.h>
 #include <rpc/blockchain.h>
@@ -396,6 +398,93 @@
     }
 }
 
+static void EnableOrDisableLogCategories(UniValue cats, bool enable) {
+    cats = cats.get_array();
+    for (size_t i = 0; i < cats.size(); ++i) {
+        std::string cat = cats[i].get_str();
+
+        bool success;
+        if (enable) {
+            success = GetLogger().EnableCategory(cat);
+        } else {
+            success = GetLogger().DisableCategory(cat);
+        }
+
+        if (!success) {
+            throw JSONRPCError(RPC_INVALID_PARAMETER,
+                               "unknown logging category " + cat);
+        }
+    }
+}
+
+static UniValue logging(const Config &config, 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.\n"
+            "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:\n"
+            "<categories>  (string): a list of the logging categories that are "
+            "active.\n"
+            "\nExamples:\n" +
+            HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"") +
+            HelpExampleRpc("logging", "[\"all\"], \"[libevent]\""));
+    }
+
+    uint32_t original_log_categories = GetLogger().GetCategoryMask();
+    if (request.params.size() > 0 && request.params[0].isArray()) {
+        EnableOrDisableLogCategories(request.params[0], true);
+    }
+
+    if (request.params.size() > 1 && request.params[1].isArray()) {
+        EnableOrDisableLogCategories(request.params[1], false);
+    }
+
+    uint32_t updated_log_categories = GetLogger().GetCategoryMask();
+    uint32_t changed_log_categories =
+        original_log_categories ^ updated_log_categories;
+
+    /**
+     * 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.
+     */
+    if (changed_log_categories & BCLog::LIBEVENT) {
+        if (!UpdateHTTPServerLogging(
+                GetLogger().WillLogCategory(BCLog::LIBEVENT))) {
+            GetLogger().DisableCategory(BCLog::LIBEVENT);
+            if (changed_log_categories == 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;
+}
+
 static UniValue echo(const Config &config, const JSONRPCRequest &request) {
     if (request.fHelp) {
         throw std::runtime_error(
@@ -439,6 +528,7 @@
     { "hidden",             "echo",                   echo,                   {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
     { "hidden",             "echojson",               echo,                   {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
     { "hidden",             "getinfo",                getinfo_deprecated,     {}},
+    { "hidden",             "logging",                logging,                {"include", "exclude"}},
 };
 // clang-format on