From 6b3bb3d9bae730d26ddd561b93efc667f5c8d499 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 25 Dec 2016 20:19:40 +0000 Subject: Change LogAcceptCategory to use uint32_t rather than sets of strings. This changes the logging categories to boolean flags instead of strings. This simplifies the acceptance testing by avoiding accessing a scoped static thread local pointer to a thread local set of strings. It eliminates the only use of boost::thread_specific_ptr outside of lockorder debugging. This change allows log entries to be directed to multiple categories and makes it easy to change the logging flags at runtime (e.g. via an RPC, though that isn't done by this commit.) It also eliminates the fDebug global. Configuration of unknown logging categories now produces a warning. --- src/util.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 28 deletions(-) (limited to 'src/util.cpp') diff --git a/src/util.cpp b/src/util.cpp index a997199fb0..766826da49 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -110,7 +110,6 @@ CCriticalSection cs_args; std::map mapArgs; static std::map > _mapMultiArgs; const std::map >& mapMultiArgs = _mapMultiArgs; -bool fDebug = false; bool fPrintToConsole = false; bool fPrintToDebugLog = true; @@ -120,6 +119,9 @@ bool fLogIPs = DEFAULT_LOGIPS; std::atomic fReopenDebugLog(false); CTranslationInterface translationInterface; +/** Log categories bitfield. Leveldb/libevent need special handling if their flags are changed at runtime. */ +std::atomic logCategories(0); + /** Init OpenSSL library multithreading support */ static CCriticalSection** ppmutexOpenSSL; void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS @@ -231,36 +233,70 @@ void OpenDebugLog() vMsgsBeforeOpenLog = NULL; } -bool LogAcceptCategory(const char* category) -{ - if (category != NULL) - { - if (!fDebug) - return false; - - // Give each thread quick access to -debug settings. - // This helps prevent issues debugging global destructors, - // where mapMultiArgs might be deleted before another - // global destructor calls LogPrint() - static boost::thread_specific_ptr > ptrCategory; - if (ptrCategory.get() == NULL) - { - if (mapMultiArgs.count("-debug")) { - const std::vector& categories = mapMultiArgs.at("-debug"); - ptrCategory.reset(new std::set(categories.begin(), categories.end())); - // thread_specific_ptr automatically deletes the set when the thread ends. - } else - ptrCategory.reset(new std::set()); +struct CLogCategoryDesc +{ + uint32_t flag; + std::string category; +}; + +const CLogCategoryDesc LogCategories[] = +{ + {BCLog::NONE, "0"}, + {BCLog::NET, "net"}, + {BCLog::TOR, "tor"}, + {BCLog::MEMPOOL, "mempool"}, + {BCLog::HTTP, "http"}, + {BCLog::BENCH, "bench"}, + {BCLog::ZMQ, "zmq"}, + {BCLog::DB, "db"}, + {BCLog::RPC, "rpc"}, + {BCLog::ESTIMATEFEE, "estimatefee"}, + {BCLog::ADDRMAN, "addrman"}, + {BCLog::SELECTCOINS, "selectcoins"}, + {BCLog::REINDEX, "reindex"}, + {BCLog::CMPCTBLOCK, "cmpctblock"}, + {BCLog::RAND, "rand"}, + {BCLog::PRUNE, "prune"}, + {BCLog::PROXY, "proxy"}, + {BCLog::MEMPOOLREJ, "mempoolrej"}, + {BCLog::LIBEVENT, "libevent"}, + {BCLog::COINDB, "coindb"}, + {BCLog::QT, "qt"}, + {BCLog::LEVELDB, "leveldb"}, + {BCLog::ALL, "1"}, + {BCLog::ALL, "all"}, +}; + +bool GetLogCategory(uint32_t *f, const std::string *str) +{ + if (f && str) { + if (*str == "") { + *f = BCLog::ALL; + return true; } - const std::set& setCategories = *ptrCategory; + for (unsigned int i = 0; i < ARRAYLEN(LogCategories); i++) { + if (LogCategories[i].category == *str) { + *f = LogCategories[i].flag; + return true; + } + } + } + return false; +} - // if not debugging everything and not debugging specific category, LogPrint does nothing. - if (setCategories.count(std::string("")) == 0 && - setCategories.count(std::string("1")) == 0 && - setCategories.count(std::string(category)) == 0) - return false; +std::string ListLogCategories() +{ + std::string ret; + int outcount = 0; + for (unsigned int i = 0; i < ARRAYLEN(LogCategories); i++) { + // Omit the special cases. + if (LogCategories[i].flag != BCLog::NONE && LogCategories[i].flag != BCLog::ALL) { + if (outcount != 0) ret += ", "; + ret += LogCategories[i].category; + outcount++; + } } - return true; + return ret; } /** -- cgit v1.2.3