Skip to content

Commit 3770ad9

Browse files
laanwjPastaPastaPasta
authored andcommitted
Merge bitcoin#11781: Add -debuglogfile option
5a7c09a test: Add tests for `-debuglogfile` with subdirs (Anthony Towns) 4158734 doc: Update release notes for `-debuglogfile` (Wladimir J. van der Laan) 2323242 test: Add test for `-debuglogfile` (Wladimir J. van der Laan) cf5f432 Add `-debuglogfile` option (Wladimir J. van der Laan) Pull request description: This patch adds an option to configure the name and/or directory of the debug log file. 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. Alternative to bitcoin#11741 that gets rid of the concept of a "log directory" by specifying the path for the specific kind of log, the debug log. Which happens to be the only kind of log we have at this point*, but a hypothetical new kind of log (say, an audit log) would get a new option. This has more flexibility than specifying a directory which has to contain all of them. \* excluding `db.log` which is internally generated by the wallet database library, but that one moves along with `-walletdir`. Tree-SHA512: 4434d0e598dc23504e5c9e67fdbaef56db4f0fd490f9f54fd503e69d4dda9b5b69c539e1794ed841e72161b7b1dc3374d2f1193dd431b057566750e56fd8f24b
1 parent 883d22d commit 3770ad9

File tree

5 files changed

+95
-14
lines changed

5 files changed

+95
-14
lines changed

src/init.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ std::string HelpMessage(HelpMessageMode mode)
441441
}
442442
strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
443443
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup"));
444+
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));
444445
strUsage += HelpMessageOpt("-maxorphantxsize=<n>", strprintf(_("Maximum total size of all orphan transactions in megabytes (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS_SIZE));
445446
strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE));
446447
strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf(_("Do not keep transactions in the mempool longer than <n> hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY));
@@ -1518,8 +1519,11 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
15181519
ShrinkDebugFile();
15191520
}
15201521

1521-
if (fPrintToDebugLog)
1522-
OpenDebugLog();
1522+
if (fPrintToDebugLog) {
1523+
if (!OpenDebugLog()) {
1524+
return InitError(strprintf("Could not open debug log file %s", GetDebugLogPath().string()));
1525+
}
1526+
}
15231527

15241528
if (!fLogTimestamps)
15251529
LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));

src/util.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ int nWalletBackups = 10;
109109

110110
const char * const BITCOIN_CONF_FILENAME = "dash.conf";
111111
const char * const BITCOIN_PID_FILENAME = "dashd.pid";
112+
const char * const DEFAULT_DEBUGLOGFILE = "debug.log";
112113

113114
ArgsManager gArgs;
114115
bool fPrintToConsole = false;
@@ -210,26 +211,40 @@ static void DebugPrintInit()
210211
vMsgsBeforeOpenLog = new std::list<std::string>;
211212
}
212213

213-
void OpenDebugLog()
214+
fs::path GetDebugLogPath()
215+
{
216+
fs::path logfile(gArgs.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE));
217+
if (logfile.is_absolute()) {
218+
return logfile;
219+
} else {
220+
return GetDataDir() / logfile;
221+
}
222+
}
223+
224+
bool OpenDebugLog()
214225
{
215226
boost::call_once(&DebugPrintInit, debugPrintInitFlag);
216227
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
217228

218229
assert(fileout == nullptr);
219230
assert(vMsgsBeforeOpenLog);
220-
fs::path pathDebug = GetDataDir() / "debug.log";
231+
fs::path pathDebug = GetDebugLogPath();
232+
221233
fileout = fsbridge::fopen(pathDebug, "a");
222-
if (fileout) {
223-
setbuf(fileout, nullptr); // unbuffered
224-
// dump buffered messages from before we opened the log
225-
while (!vMsgsBeforeOpenLog->empty()) {
226-
FileWriteStr(vMsgsBeforeOpenLog->front(), fileout);
227-
vMsgsBeforeOpenLog->pop_front();
228-
}
234+
if (!fileout) {
235+
return false;
236+
}
237+
238+
setbuf(fileout, nullptr); // unbuffered
239+
// dump buffered messages from before we opened the log
240+
while (!vMsgsBeforeOpenLog->empty()) {
241+
FileWriteStr(vMsgsBeforeOpenLog->front(), fileout);
242+
vMsgsBeforeOpenLog->pop_front();
229243
}
230244

231245
delete vMsgsBeforeOpenLog;
232246
vMsgsBeforeOpenLog = nullptr;
247+
return true;
233248
}
234249

235250
struct CLogCategoryDesc
@@ -447,7 +462,7 @@ int LogPrintStr(const std::string &str)
447462
// reopen the log file, if requested
448463
if (fReopenDebugLog) {
449464
fReopenDebugLog = false;
450-
fs::path pathDebug = GetDataDir() / "debug.log";
465+
fs::path pathDebug = GetDebugLogPath();
451466
if (fsbridge::freopen(pathDebug,"a",fileout) != nullptr)
452467
setbuf(fileout, nullptr); // unbuffered
453468
}
@@ -876,7 +891,7 @@ void ShrinkDebugFile()
876891
// Amount of debug.log to save at end when shrinking (must fit in memory)
877892
constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000;
878893
// Scroll debug.log if it's getting too big
879-
fs::path pathLog = GetDataDir() / "debug.log";
894+
fs::path pathLog = GetDebugLogPath();
880895
FILE* file = fsbridge::fopen(pathLog, "r");
881896
// If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE
882897
// trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes

src/util.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static const bool DEFAULT_LOGTIMEMICROS = false;
5656
static const bool DEFAULT_LOGIPS = false;
5757
static const bool DEFAULT_LOGTIMESTAMPS = true;
5858
static const bool DEFAULT_LOGTHREADNAMES = false;
59+
extern const char * const DEFAULT_DEBUGLOGFILE;
5960

6061
/** Signals for translation. */
6162
class CTranslationInterface
@@ -232,7 +233,8 @@ void CreatePidFile(const fs::path &path, pid_t pid);
232233
#ifdef WIN32
233234
fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
234235
#endif
235-
void OpenDebugLog();
236+
fs::path GetDebugLogPath();
237+
bool OpenDebugLog();
236238
void ShrinkDebugFile();
237239
void runCommand(const std::string& strCommand);
238240

test/functional/feature_logging.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2017 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
"""Test debug logging."""
6+
7+
import os
8+
9+
from test_framework.test_framework import BitcoinTestFramework
10+
11+
class LoggingTest(BitcoinTestFramework):
12+
def set_test_params(self):
13+
self.num_nodes = 1
14+
self.setup_clean_chain = True
15+
16+
def run_test(self):
17+
# test default log file name
18+
assert os.path.isfile(os.path.join(self.nodes[0].datadir, "regtest", "debug.log"))
19+
20+
# test alternative log file name in datadir
21+
self.restart_node(0, ["-debuglogfile=foo.log"])
22+
assert os.path.isfile(os.path.join(self.nodes[0].datadir, "regtest", "foo.log"))
23+
24+
# test alternative log file name outside datadir
25+
tempname = os.path.join(self.options.tmpdir, "foo.log")
26+
self.restart_node(0, ["-debuglogfile=%s" % tempname])
27+
assert os.path.isfile(tempname)
28+
29+
# check that invalid log (relative) will cause error
30+
invdir = os.path.join(self.nodes[0].datadir, "regtest", "foo")
31+
invalidname = os.path.join("foo", "foo.log")
32+
self.stop_node(0)
33+
self.assert_start_raises_init_error(0, ["-debuglogfile=%s" % (invalidname)],
34+
"Error: Could not open debug log file")
35+
assert not os.path.isfile(os.path.join(invdir, "foo.log"))
36+
37+
# check that invalid log (relative) works after path exists
38+
self.stop_node(0)
39+
os.mkdir(invdir)
40+
self.start_node(0, ["-debuglogfile=%s" % (invalidname)])
41+
assert os.path.isfile(os.path.join(invdir, "foo.log"))
42+
43+
# check that invalid log (absolute) will cause error
44+
self.stop_node(0)
45+
invdir = os.path.join(self.options.tmpdir, "foo")
46+
invalidname = os.path.join(invdir, "foo.log")
47+
self.assert_start_raises_init_error(0, ["-debuglogfile=%s" % invalidname],
48+
"Error: Could not open debug log file")
49+
assert not os.path.isfile(os.path.join(invdir, "foo.log"))
50+
51+
# check that invalid log (absolute) works after path exists
52+
self.stop_node(0)
53+
os.mkdir(invdir)
54+
self.start_node(0, ["-debuglogfile=%s" % (invalidname)])
55+
assert os.path.isfile(os.path.join(invdir, "foo.log"))
56+
57+
58+
if __name__ == '__main__':
59+
LoggingTest().main()

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
'feature_shutdown.py',
143143
'privatesend.py',
144144
'uacomment.py',
145+
'feature_logging.py',
145146
]
146147

147148
EXTENDED_SCRIPTS = [

0 commit comments

Comments
 (0)