Skip to content

Commit

Permalink
Merge #1455: [Init] Add -debuglogfile option
Browse files Browse the repository at this point in the history
882ef90 [Doc] Update release notes for `-debuglogfile` (random-zebra)
3d5ad7f test: Add tests for `-debuglogfile` with subdirs (random-zebra)
2c2e36d test: Add test for `-debuglogfile` (random-zebra)
b44a324 Add `-debuglogfile` option (random-zebra)

Pull request description:

  Implemented on top of
  - [x] #1449
  - [x] #1437
  - [x] #1439
  - [x] #1450
  - [x] #1451

  Only last 4 commits are relevant to this PR.
  Backports bitcoin#11781

  > This patch adds an option to configure the name and/or directory of the debug log file.</br></br>
  The user can specify either a relative path, in which case the path is relative to the (network specific) data directory. They can also specify an absolute path to put the log anywhere else in the file system.

  Functional test included.

ACKs for top commit:
  Fuzzbawls:
    ACK 882ef90
  furszy:
    utACK 882ef90

Tree-SHA512: 02a0e6487683e5111765af7296ef7ce035372febf037268d99d29b4c4a2f74bcc40f46a0f5b1bacddc2249c2a7e40255555e83ca9d51bf71d9e054c6e85765cc
  • Loading branch information
random-zebra committed Apr 9, 2020
2 parents 3dddd25 + 882ef90 commit b26dbc4
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 16 deletions.
6 changes: 6 additions & 0 deletions doc/release-notes.md
Expand Up @@ -150,6 +150,12 @@ E.g. `logging "[\"all\"]" "[\"http\"]""`
Details about each new command can be found below.


Changed command-line options
-----------------------------

- `-debuglogfile=<file>` 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
==============

Expand Down
6 changes: 4 additions & 2 deletions src/init.cpp
Expand Up @@ -383,6 +383,7 @@ std::string HelpMessage(HelpMessageMode mode)
#endif
}
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
strUsage += HelpMessageOpt("-debuglogfile=<file>", 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=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
strUsage += HelpMessageOpt("-maxreorg=<n>", strprintf(_("Set the Maximum reorg depth (default: %u)"), DEFAULT_MAX_REORG_DEPTH));
Expand Down Expand Up @@ -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
Expand Down
37 changes: 24 additions & 13 deletions src/util.cpp
Expand Up @@ -102,6 +102,9 @@ bool fSucessfullyLoaded = false;
std::vector<int64_t> obfuScationDenominations;
std::string strBudgetMode = "";

const char * const DEFAULT_DEBUGLOGFILE = "debug.log";
namespace fs = boost::filesystem;

std::map<std::string, std::string> mapArgs;
std::map<std::string, std::vector<std::string> > mapMultiArgs;
bool fPrintToConsole = false;
Expand Down Expand Up @@ -203,17 +206,29 @@ static void DebugPrintInit()
vMsgsBeforeOpenLog = new std::list<std::string>;
}

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);
Expand All @@ -222,6 +237,7 @@ void OpenDebugLog()

delete vMsgsBeforeOpenLog;
vMsgsBeforeOpenLog = nullptr;
return true;
}

struct CLogCategoryDesc
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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)) {
Expand Down
5 changes: 4 additions & 1 deletion src/util.h
Expand Up @@ -32,6 +32,8 @@
#include <boost/thread/exceptions.hpp>
#include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted

extern const char * const DEFAULT_DEBUGLOGFILE;

//PIVX only features

extern bool fMasterNode;
Expand Down Expand Up @@ -161,7 +163,8 @@ void ReadConfigFile(std::map<std::string, std::string>& 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);

Expand Down
65 changes: 65 additions & 0 deletions test/functional/feature_logging.py
@@ -0,0 +1,65 @@
#!/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
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=%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)
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()
2 changes: 2 additions & 0 deletions test/functional/test_runner.py
Expand Up @@ -66,6 +66,7 @@
'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
Expand Down Expand Up @@ -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',
Expand Down

0 comments on commit b26dbc4

Please sign in to comment.