diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp --- a/src/bench/bench_bitcoin.cpp +++ b/src/bench/bench_bitcoin.cpp @@ -15,7 +15,10 @@ RandomInit(); ECC_Start(); SetupEnvironment(); - fPrintToDebugLog = false; // don't want to write to debug.log file + + g_logger.reset(new BCLog::Logger()); + // don't want to write to debug.log file + g_logger->fPrintToDebugLog = false; benchmark::BenchRunner::RunAll(); diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -277,7 +277,9 @@ } void HandleSIGHUP(int) { - fReopenDebugLog = true; + if (g_logger) { + g_logger->fReopenDebugLog = true; + } } static bool Bind(CConnman &connman, const CService &addr, unsigned int flags) { @@ -1227,9 +1229,13 @@ } void InitLogging() { - fPrintToConsole = gArgs.GetBoolArg("-printtoconsole", false); - fLogTimestamps = gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); - fLogTimeMicros = gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); + g_logger.reset(new BCLog::Logger()); + g_logger->fPrintToConsole = gArgs.GetBoolArg("-printtoconsole", false); + g_logger->fLogTimestamps = + gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); + g_logger->fLogTimeMicros = + gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); + fLogIPs = gArgs.GetBoolArg("-logips", DEFAULT_LOGIPS); LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); @@ -1740,11 +1746,11 @@ ShrinkDebugFile(); } - if (fPrintToDebugLog) { + if (g_logger->fPrintToDebugLog) { OpenDebugLog(); } - if (!fLogTimestamps) { + if (!g_logger->fLogTimestamps) { LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime())); } diff --git a/src/logging.h b/src/logging.h --- a/src/logging.h +++ b/src/logging.h @@ -9,23 +9,20 @@ #include #include +#include #include static const bool DEFAULT_LOGTIMEMICROS = false; static const bool DEFAULT_LOGIPS = false; static const bool DEFAULT_LOGTIMESTAMPS = true; -extern bool fPrintToConsole; -extern bool fPrintToDebugLog; - -extern bool fLogTimestamps; -extern bool fLogTimeMicros; extern bool fLogIPs; extern std::atomic fReopenDebugLog; extern std::atomic logCategories; namespace BCLog { + enum LogFlags : uint32_t { NONE = 0, NET = (1 << 0), @@ -51,7 +48,35 @@ LEVELDB = (1 << 20), ALL = ~uint32_t(0), }; -} + +class Logger { +private: + /** + * 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 end in a newline. Initialize it to true, and hold it, in the + * calling context. + */ + std::atomic_bool fStartedNewLine{true}; + + std::string LogTimestampStr(const std::string &str); + +public: + bool fPrintToConsole = false; + bool fPrintToDebugLog = true; + + bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; + bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; + + std::atomic fReopenDebugLog{false}; + + /** Send a string to the log output */ + int LogPrintStr(const std::string &str); +}; + +} // namespace BCLog + +extern std::unique_ptr g_logger; /** Return true if log accepts specified category */ static inline bool LogAcceptCategory(uint32_t category) { @@ -64,19 +89,18 @@ /** Return true if str parses as a log category and set the flags in f */ bool GetLogCategory(uint32_t *f, const std::string *str); -/** Send a string to the log output */ -int LogPrintStr(const std::string &str); - #define LogPrint(category, ...) \ do { \ - if (LogAcceptCategory((category))) { \ - LogPrintStr(tfm::format(__VA_ARGS__)); \ + if (g_logger && LogAcceptCategory((category))) { \ + g_logger->LogPrintStr(tfm::format(__VA_ARGS__)); \ } \ } while (0) #define LogPrintf(...) \ do { \ - LogPrintStr(tfm::format(__VA_ARGS__)); \ + if (g_logger) { \ + g_logger->LogPrintStr(tfm::format(__VA_ARGS__)); \ + } \ } while (0) void OpenDebugLog(); diff --git a/src/logging.cpp b/src/logging.cpp --- a/src/logging.cpp +++ b/src/logging.cpp @@ -12,13 +12,7 @@ #include #include -bool fPrintToConsole = false; -bool fPrintToDebugLog = true; - -bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; -bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; bool fLogIPs = DEFAULT_LOGIPS; -std::atomic fReopenDebugLog(false); /** * Log categories bitfield. Leveldb/libevent need special handling if their @@ -26,6 +20,8 @@ */ std::atomic logCategories(0); +std::unique_ptr g_logger; + /** * LogPrintf() has been broken a couple of times now by well-meaning people * adding mutexes in the most straightforward way. It breaks because it may be @@ -145,18 +141,12 @@ 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 - * end in a newline. Initialize it to true, and hold it, in the calling context. - */ -static std::string LogTimestampStr(const std::string &str, - std::atomic_bool *fStartedNewLine) { +std::string BCLog::Logger::LogTimestampStr(const std::string &str) { std::string strStamped; if (!fLogTimestamps) return str; - if (*fStartedNewLine) { + if (fStartedNewLine) { int64_t nTimeMicros = GetLogTimeMicros(); strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTimeMicros / 1000000); @@ -167,19 +157,18 @@ strStamped = str; if (!str.empty() && str[str.size() - 1] == '\n') - *fStartedNewLine = true; + fStartedNewLine = true; else - *fStartedNewLine = false; + fStartedNewLine = false; return strStamped; } -int LogPrintStr(const std::string &str) { +int BCLog::Logger::LogPrintStr(const std::string &str) { // Returns total number of characters written. int ret = 0; - static std::atomic_bool fStartedNewLine(true); - std::string strTimestamped = LogTimestampStr(str, &fStartedNewLine); + std::string strTimestamped = LogTimestampStr(str); if (fPrintToConsole) { // Print to console. diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -11,6 +11,7 @@ #include "crypto/sha256.h" #include "fs.h" #include "key.h" +#include "logging.h" #include "miner.h" #include "net_processing.h" #include "pubkey.h" @@ -38,7 +39,6 @@ uint256 insecure_rand_seed = GetRandHash(); FastRandomContext insecure_rand_ctx(insecure_rand_seed); -extern bool fPrintToConsole; extern void noui_connect(); BasicTestingSetup::BasicTestingSetup(const std::string &chainName) { @@ -49,8 +49,11 @@ SetupNetworking(); InitSignatureCache(); InitScriptExecutionCache(); + + g_logger.reset(new BCLog::Logger()); // Don't want to write to debug.log file. - fPrintToDebugLog = false; + g_logger->fPrintToDebugLog = false; + fCheckBlockIndex = true; SelectParams(chainName); noui_connect(); @@ -63,6 +66,7 @@ BasicTestingSetup::~BasicTestingSetup() { ECC_Stop(); g_connman.reset(); + g_logger.reset(); } TestingSetup::TestingSetup(const std::string &chainName)