From b44a324c0baee30db49d4dbec3111a6dc353abe7 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Tue, 24 Mar 2020 11:54:44 +0100 Subject: [PATCH 1/4] Add `-debuglogfile` option This patch adds an option to configure the name and/or directory of the debug log. The user can specify either a relative path, in which case the path is relative to the data directory. They can also specify an absolute path to put the log anywhere else in the file system. backports bitcoin@cf5f432c69418adb51f0f4a0bdbd6ba3112ee11a --- src/init.cpp | 6 ++++-- src/util.cpp | 37 ++++++++++++++++++++++++------------- src/util.h | 5 ++++- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 68a8992e8f2d8..e99fee0a376c5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -383,6 +383,7 @@ std::string HelpMessage(HelpMessageMode mode) #endif } strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); + strUsage += HelpMessageOpt("-debuglogfile=", strprintf(_("Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s)"), DEFAULT_DEBUGLOGFILE)); strUsage += HelpMessageOpt("-dbcache=", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); strUsage += HelpMessageOpt("-loadblock=", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); strUsage += HelpMessageOpt("-maxreorg=", strprintf(_("Set the Maximum reorg depth (default: %u)"), DEFAULT_MAX_REORG_DEPTH)); @@ -1063,8 +1064,9 @@ bool AppInit2() #endif if (GetBoolArg("-shrinkdebugfile", logCategories != BCLog::NONE)) ShrinkDebugFile(); - if (fPrintToDebugLog) - OpenDebugLog(); + if (fPrintToDebugLog && !OpenDebugLog()) { + return UIError(strprintf("Could not open debug log file %s", GetDebugLogPath().string())); + } #ifdef ENABLE_WALLET LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); #endif diff --git a/src/util.cpp b/src/util.cpp index 958bf072a951e..452ef33ca154a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -102,6 +102,9 @@ bool fSucessfullyLoaded = false; std::vector obfuScationDenominations; std::string strBudgetMode = ""; +const char * const DEFAULT_DEBUGLOGFILE = "debug.log"; +namespace fs = boost::filesystem; + std::map mapArgs; std::map > mapMultiArgs; bool fPrintToConsole = false; @@ -203,17 +206,29 @@ static void DebugPrintInit() vMsgsBeforeOpenLog = new std::list; } -void OpenDebugLog() +fs::path GetDebugLogPath() +{ + fs::path logfile(GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE)); + if (logfile.is_absolute()) { + return logfile; + } else { + return GetDataDir() / logfile; + } +} + +bool OpenDebugLog() { boost::call_once(&DebugPrintInit, debugPrintInitFlag); boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); assert(fileout == nullptr); assert(vMsgsBeforeOpenLog); - boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + boost::filesystem::path pathDebug = GetDebugLogPath(); + fileout = fopen(pathDebug.string().c_str(), "a"); - if (fileout) setbuf(fileout, nullptr); // unbuffered + if (!fileout) return false; + setbuf(fileout, nullptr); // unbuffered // dump buffered messages from before we opened the log while (!vMsgsBeforeOpenLog->empty()) { FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); @@ -222,6 +237,7 @@ void OpenDebugLog() delete vMsgsBeforeOpenLog; vMsgsBeforeOpenLog = nullptr; + return true; } struct CLogCategoryDesc @@ -357,7 +373,7 @@ int LogPrintStr(const std::string& str) // reopen the log file, if requested if (fReopenDebugLog) { fReopenDebugLog = false; - boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + boost::filesystem::path pathDebug = GetDebugLogPath(); if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL) setbuf(fileout, NULL); // unbuffered } @@ -497,7 +513,6 @@ void PrintExceptionContinue(const std::exception* pex, const char* pszThread) boost::filesystem::path GetDefaultDataDir() { - namespace fs = boost::filesystem; // Windows < Vista: C:\Documents and Settings\Username\Application Data\PIVX // Windows >= Vista: C:\Users\Username\AppData\Roaming\PIVX // Mac: ~/Library/Application Support/PIVX @@ -524,14 +539,12 @@ boost::filesystem::path GetDefaultDataDir() #endif } -static boost::filesystem::path pathCached; -static boost::filesystem::path pathCachedNetSpecific; +static fs::path pathCached; +static fs::path pathCachedNetSpecific; static RecursiveMutex csPathCached; -const boost::filesystem::path& GetDataDir(bool fNetSpecific) +const fs::path& GetDataDir(bool fNetSpecific) { - namespace fs = boost::filesystem; - LOCK(csPathCached); fs::path& path = fNetSpecific ? pathCachedNetSpecific : pathCached; @@ -755,7 +768,7 @@ void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length) void ShrinkDebugFile() { // Scroll debug.log if it's getting too big - boost::filesystem::path pathLog = GetDataDir() / "debug.log"; + boost::filesystem::path pathLog = GetDebugLogPath(); FILE* file = fopen(pathLog.string().c_str(), "r"); if (file && boost::filesystem::file_size(pathLog) > 10 * 1000000) { // Restart the file with some of the end @@ -776,8 +789,6 @@ void ShrinkDebugFile() #ifdef WIN32 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate) { - namespace fs = boost::filesystem; - char pszPath[MAX_PATH] = ""; if (SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate)) { diff --git a/src/util.h b/src/util.h index 6733d634595a1..e5bb1d30b5cbb 100644 --- a/src/util.h +++ b/src/util.h @@ -32,6 +32,8 @@ #include #include // for boost::thread_interrupted +extern const char * const DEFAULT_DEBUGLOGFILE; + //PIVX only features extern bool fMasterNode; @@ -161,7 +163,8 @@ void ReadConfigFile(std::map& mapSettingsRet, std::map boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif boost::filesystem::path GetTempPath(); -void OpenDebugLog(); +boost::filesystem::path GetDebugLogPath(); +bool OpenDebugLog(); void ShrinkDebugFile(); void runCommand(std::string strCommand); From 2c2e36dd32acc80340789f23d76a5a2dc5c96eb0 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Tue, 24 Mar 2020 12:06:21 +0100 Subject: [PATCH 2/4] test: Add test for `-debuglogfile` backports bitcoin@23232422e507a90922c0870611cade5c789bb83a --- test/functional/feature_logging.py | 48 ++++++++++++++++++++++++++++++ test/functional/test_runner.py | 2 ++ 2 files changed, 50 insertions(+) create mode 100755 test/functional/feature_logging.py diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py new file mode 100755 index 0000000000000..122653e3f6a08 --- /dev/null +++ b/test/functional/feature_logging.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Bitcoin Core developers +# Copyright (c) 20200 The PIVX Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test debug logging.""" + +import os + +from test_framework.test_framework import PivxTestFramework + +class LoggingTest(PivxTestFramework): + def set_test_params(self): + self.num_nodes = 1 + self.setup_clean_chain = True + + def run_test(self): + # test default log file name + assert os.path.isfile(os.path.join(self.nodes[0].datadir, "regtest", "debug.log")) + self.log.info("Default filename ok") + + # test alternative log file name in datadir + self.restart_node(0, ["-debuglogfile=foo.log"]) + assert os.path.isfile(os.path.join(self.nodes[0].datadir, "regtest", "foo.log")) + self.log.info("Alternative filename ok") + + # test alternative log file name outside datadir + tempname = os.path.join(self.options.tmpdir, "foo.log") + self.restart_node(0, ["-debuglogfile=%s" % tempname]) + assert os.path.isfile(tempname) + self.log.info("Alternative filename outside datadir ok") + + # check that invalid log (relative) will cause error + self.stop_node(0) + self.assert_start_raises_init_error(0, ["-debuglogfile=ssdksjdf/sdasdfa/sdfsdfsfd"], + "Error: Could not open debug log file") + self.log.info("Invalid relative filename throws") + + # check that invalid log (absolute) will cause error + self.stop_node(0) + invalidname = os.path.join(self.options.tmpdir, "foo/foo.log") + self.assert_start_raises_init_error(0, ["-debuglogfile=%s" % invalidname], + "Error: Could not open debug log file") + self.log.info("Invalid absolute filename throws") + + +if __name__ == '__main__': + LoggingTest().main() \ No newline at end of file diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 94ac0066279ca..54a78e19392db 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -69,6 +69,7 @@ 'rpc_rawtransaction.py', # ~ 193 sec 'wallet_zapwallettxes.py', # ~ 180 sec 'wallet_keypool_topup.py', # ~ 174 sec + 'feature_logging.py', # ~ 166 sec 'wallet_txn_doublespend.py --mineblock', # ~ 157 sec 'wallet_txn_clone.py --mineblock', # ~ 157 sec 'rpc_spork.py', # ~ 156 sec @@ -153,6 +154,7 @@ LEGACY_SKIP_TESTS = [ # These tests are not run when the flag --legacywallet is used 'feature_help.py', + 'feature_logging.py', 'feature_reindex.py', 'feature_proxy.py', 'feature_uacomment.py', From 3d5ad7fb0abc735de54169266ff921ee57358494 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Tue, 24 Mar 2020 12:16:38 +0100 Subject: [PATCH 3/4] test: Add tests for `-debuglogfile` with subdirs backports bitcoin@5a7c09aebf8b0229e9f320135472275d244a7a35 --- test/functional/feature_logging.py | 21 +++++++++++++++++++-- test/functional/test_runner.py | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py index 122653e3f6a08..70299b374a525 100755 --- a/test/functional/feature_logging.py +++ b/test/functional/feature_logging.py @@ -31,18 +31,35 @@ def run_test(self): self.log.info("Alternative filename outside datadir ok") # check that invalid log (relative) will cause error + invdir = os.path.join(self.nodes[0].datadir, "regtest", "foo") + invalidname = os.path.join("foo", "foo.log") self.stop_node(0) - self.assert_start_raises_init_error(0, ["-debuglogfile=ssdksjdf/sdasdfa/sdfsdfsfd"], + self.assert_start_raises_init_error(0, ["-debuglogfile=%s" % (invalidname)], "Error: Could not open debug log file") + assert not os.path.isfile(os.path.join(invdir, "foo.log")) self.log.info("Invalid relative filename throws") + # check that a previously invalid log (relative) works after path exists + os.mkdir(invdir) + self.start_node(0, ["-debuglogfile=%s" % (invalidname)]) + assert os.path.isfile(os.path.join(invdir, "foo.log")) + self.log.info("Relative filename ok when path exists") + # check that invalid log (absolute) will cause error self.stop_node(0) - invalidname = os.path.join(self.options.tmpdir, "foo/foo.log") + invdir = os.path.join(self.options.tmpdir, "foo") + invalidname = os.path.join(invdir, "foo.log") self.assert_start_raises_init_error(0, ["-debuglogfile=%s" % invalidname], "Error: Could not open debug log file") + assert not os.path.isfile(os.path.join(invdir, "foo.log")) self.log.info("Invalid absolute filename throws") + # check that a previously invalid log (relative) works after path exists + os.mkdir(invdir) + self.start_node(0, ["-debuglogfile=%s" % (invalidname)]) + assert os.path.isfile(os.path.join(invdir, "foo.log")) + self.log.info("Absolute filename ok when path exists") + if __name__ == '__main__': LoggingTest().main() \ No newline at end of file diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 54a78e19392db..75c6ec399bad9 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -66,10 +66,10 @@ 'wallet_abandonconflict.py', # ~ 212 sec 'wallet_hd.py', # ~ 210 sec 'wallet_zerocoin_publicspends.py', # ~ 202 sec + 'feature_logging.py', # ~ 200 sec 'rpc_rawtransaction.py', # ~ 193 sec 'wallet_zapwallettxes.py', # ~ 180 sec 'wallet_keypool_topup.py', # ~ 174 sec - 'feature_logging.py', # ~ 166 sec 'wallet_txn_doublespend.py --mineblock', # ~ 157 sec 'wallet_txn_clone.py --mineblock', # ~ 157 sec 'rpc_spork.py', # ~ 156 sec From 882ef9002d672e9e8f8a21e7e3acfc725d775486 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Tue, 24 Mar 2020 12:19:16 +0100 Subject: [PATCH 4/4] [Doc] Update release notes for `-debuglogfile` --- doc/release-notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 1956746c3aaf9..eee7c183011ef 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -150,6 +150,12 @@ E.g. `logging "[\"all\"]" "[\"http\"]""` Details about each new command can be found below. +Changed command-line options +----------------------------- + +- `-debuglogfile=` can be used to specify an alternative debug logging file. This can be an absolute path or a path relative to the data directory + + *version* Change log ==============