Skip to content

Commit 24df9af

Browse files
committed
Merge #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 #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
2 parents 00d25e9 + 5a7c09a commit 24df9af

File tree

6 files changed

+98
-14
lines changed

6 files changed

+98
-14
lines changed

doc/release-notes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ Low-level RPC changes
9090
* `getmininginfo`
9191
- The wallet RPC `getreceivedbyaddress` will return an error if called with an address not in the wallet.
9292

93+
Changed command-line options
94+
-----------------------------
95+
- `-debuglogfile=<file>` can be used to specify an alternative debug logging file.
9396

9497
Credits
9598
=======

src/init.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ std::string HelpMessage(HelpMessageMode mode)
342342
if (showDebug)
343343
strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER));
344344
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup"));
345+
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));
345346
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
346347
strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE));
347348
strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf(_("Do not keep transactions in the mempool longer than <n> hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY));
@@ -1209,8 +1210,11 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
12091210
ShrinkDebugFile();
12101211
}
12111212

1212-
if (fPrintToDebugLog)
1213-
OpenDebugLog();
1213+
if (fPrintToDebugLog) {
1214+
if (!OpenDebugLog()) {
1215+
return InitError(strprintf("Could not open debug log file %s", GetDebugLogPath().string()));
1216+
}
1217+
}
12141218

12151219
if (!fLogTimestamps)
12161220
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
@@ -89,6 +89,7 @@ const int64_t nStartupTime = GetTime();
8989

9090
const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf";
9191
const char * const BITCOIN_PID_FILENAME = "bitcoind.pid";
92+
const char * const DEFAULT_DEBUGLOGFILE = "debug.log";
9293

9394
ArgsManager gArgs;
9495
bool fPrintToConsole = false;
@@ -189,26 +190,40 @@ static void DebugPrintInit()
189190
vMsgsBeforeOpenLog = new std::list<std::string>;
190191
}
191192

192-
void OpenDebugLog()
193+
fs::path GetDebugLogPath()
194+
{
195+
fs::path logfile(gArgs.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE));
196+
if (logfile.is_absolute()) {
197+
return logfile;
198+
} else {
199+
return GetDataDir() / logfile;
200+
}
201+
}
202+
203+
bool OpenDebugLog()
193204
{
194205
boost::call_once(&DebugPrintInit, debugPrintInitFlag);
195206
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
196207

197208
assert(fileout == nullptr);
198209
assert(vMsgsBeforeOpenLog);
199-
fs::path pathDebug = GetDataDir() / "debug.log";
210+
fs::path pathDebug = GetDebugLogPath();
211+
200212
fileout = fsbridge::fopen(pathDebug, "a");
201-
if (fileout) {
202-
setbuf(fileout, nullptr); // unbuffered
203-
// dump buffered messages from before we opened the log
204-
while (!vMsgsBeforeOpenLog->empty()) {
205-
FileWriteStr(vMsgsBeforeOpenLog->front(), fileout);
206-
vMsgsBeforeOpenLog->pop_front();
207-
}
213+
if (!fileout) {
214+
return false;
215+
}
216+
217+
setbuf(fileout, nullptr); // unbuffered
218+
// dump buffered messages from before we opened the log
219+
while (!vMsgsBeforeOpenLog->empty()) {
220+
FileWriteStr(vMsgsBeforeOpenLog->front(), fileout);
221+
vMsgsBeforeOpenLog->pop_front();
208222
}
209223

210224
delete vMsgsBeforeOpenLog;
211225
vMsgsBeforeOpenLog = nullptr;
226+
return true;
212227
}
213228

214229
struct CLogCategoryDesc
@@ -355,7 +370,7 @@ int LogPrintStr(const std::string &str)
355370
// reopen the log file, if requested
356371
if (fReopenDebugLog) {
357372
fReopenDebugLog = false;
358-
fs::path pathDebug = GetDataDir() / "debug.log";
373+
fs::path pathDebug = GetDebugLogPath();
359374
if (fsbridge::freopen(pathDebug,"a",fileout) != nullptr)
360375
setbuf(fileout, nullptr); // unbuffered
361376
}
@@ -774,7 +789,7 @@ void ShrinkDebugFile()
774789
// Amount of debug.log to save at end when shrinking (must fit in memory)
775790
constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000;
776791
// Scroll debug.log if it's getting too big
777-
fs::path pathLog = GetDataDir() / "debug.log";
792+
fs::path pathLog = GetDebugLogPath();
778793
FILE* file = fsbridge::fopen(pathLog, "r");
779794
// If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE
780795
// 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
@@ -36,6 +36,7 @@ int64_t GetStartupTime();
3636
static const bool DEFAULT_LOGTIMEMICROS = false;
3737
static const bool DEFAULT_LOGIPS = false;
3838
static const bool DEFAULT_LOGTIMESTAMPS = true;
39+
extern const char * const DEFAULT_DEBUGLOGFILE;
3940

4041
/** Signals for translation. */
4142
class CTranslationInterface
@@ -180,7 +181,8 @@ void CreatePidFile(const fs::path &path, pid_t pid);
180181
#ifdef WIN32
181182
fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
182183
#endif
183-
void OpenDebugLog();
184+
fs::path GetDebugLogPath();
185+
bool OpenDebugLog();
184186
void ShrinkDebugFile();
185187
void runCommand(const std::string& strCommand);
186188

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
@@ -127,6 +127,7 @@
127127
'p2p-fingerprint.py',
128128
'uacomment.py',
129129
'p2p-acceptblock.py',
130+
'feature_logging.py',
130131
]
131132

132133
EXTENDED_SCRIPTS = [

0 commit comments

Comments
 (0)