diff --git a/doc/release-notes.md b/doc/release-notes.md
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -28,3 +28,6 @@
- Added the `datadir` option to the seeder allowing a directory to be
specified for the files the seeder writes to and reads from (default is the
`~/.bitcoin/seeder` directory). See help for more details.
+- The seeder will now log some of its debug and output strings to a
+ `seederdebug.log` file. The location of this file is defined by the
+ `-datadir` option.
diff --git a/src/seeder/main.cpp b/src/seeder/main.cpp
--- a/src/seeder/main.cpp
+++ b/src/seeder/main.cpp
@@ -112,14 +112,13 @@
// Warn about relative -datadir path
if (gArgs.IsArgSet("-datadir") &&
!fs::path(gArgs.GetArg("-datadir", "")).is_absolute()) {
- tfm::format(
- std::cout,
- "Warning: relative datadir option '%s' specified, which will "
- "be interpreted relative to the current working directory "
- "'%s'. This is fragile, because if the seeder is started in "
- "the future from a different location, it will be unable to "
- "locate the current data files.\n",
- gArgs.GetArg("-datadir", ""), fs::current_path().string());
+ LogPrintf("Warning: relative datadir option '%s' specified, which "
+ "will be interpreted relative to the current working "
+ "directory '%s'. This is fragile, because if the seeder "
+ "is started in the future from a different location, it "
+ "will be unable to locate the current data files.\n",
+ gArgs.GetArg("-datadir", ""),
+ fs::current_path().string());
}
if (gArgs.IsArgSet("-filter")) {
@@ -186,6 +185,14 @@
"-datadir=
",
"Specifies the directory that the seeder reads from and writes to.",
ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-printtoconsole",
+ "Send trace/debug info to console (default: 1)",
+ ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ gArgs.AddArg(
+ "-logtofile",
+ "Write trace/debug info to seederdebug.log file. This option does "
+ "not affect database files (default: 0)",
+ ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
SetupChainParamsBaseOptions();
gArgs.AddArg("-help", "", ArgsManager::ALLOW_ANY,
@@ -509,9 +516,6 @@
}
int main(int argc, char **argv) {
- // The logger dump everything on the console by default.
- LogInstance().m_print_to_console = true;
-
signal(SIGPIPE, SIG_IGN);
setbuf(stdout, nullptr);
CDnsSeedOpts opts;
@@ -520,88 +524,104 @@
return parseResults;
}
- tfm::format(std::cout, "Supporting whitelisted filters: ");
+ // Set up logger
+ BCLog::Logger &logger = LogInstance();
+ logger.m_print_to_console = gArgs.GetBoolArg("-printtoconsole", true);
+ logger.m_print_to_file = gArgs.GetBoolArg("-logtofile", false);
+ logger.m_file_path = AbsPathForConfigVal(GetDataDir() / "seederdebug.log");
+ logger.m_log_timestamps = DEFAULT_LOGTIMESTAMPS;
+ logger.m_log_time_micros = DEFAULT_LOGTIMEMICROS;
+ logger.m_log_threadnames = DEFAULT_LOGTHREADNAMES;
+ if (!logger.StartLogging()) {
+ tfm::format(std::cout, "Could not open debug log file %s\n",
+ logger.m_file_path.string());
+ tfm::format(std::cout, "Logging only to console\n");
+ logger.m_print_to_file = false;
+ }
+ if (!logger.m_log_timestamps) {
+ LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime()));
+ }
+ LogPrintf("%s Seeder version %s\n", PACKAGE_NAME, FormatFullVersion());
+
+ LogPrintfToBeContinued("Supporting whitelisted filters: ");
for (std::set::const_iterator it = opts.filter_whitelist.begin();
it != opts.filter_whitelist.end(); it++) {
if (it != opts.filter_whitelist.begin()) {
- tfm::format(std::cout, ",");
+ LogPrintfToBeContinued(",");
}
- tfm::format(std::cout, "0x%lx", (unsigned long)*it);
+ LogPrintfToBeContinued("0x%lx", (unsigned long)*it);
}
- tfm::format(std::cout, "\n");
+ LogPrintf("\n");
if (!opts.tor.empty()) {
CService service(LookupNumeric(opts.tor.c_str(), 9050));
if (service.IsValid()) {
- tfm::format(std::cout, "Using Tor proxy at %s\n",
- service.ToStringIPPort());
+ LogPrintf("Using Tor proxy at %s\n", service.ToStringIPPort());
SetProxy(NET_ONION, proxyType(service));
}
}
if (!opts.ipv4_proxy.empty()) {
CService service(LookupNumeric(opts.ipv4_proxy.c_str(), 9050));
if (service.IsValid()) {
- tfm::format(std::cout, "Using IPv4 proxy at %s\n",
- service.ToStringIPPort());
+ LogPrintf("Using IPv4 proxy at %s\n", service.ToStringIPPort());
SetProxy(NET_IPV4, proxyType(service));
}
}
if (!opts.ipv6_proxy.empty()) {
CService service(LookupNumeric(opts.ipv6_proxy.c_str(), 9050));
if (service.IsValid()) {
- tfm::format(std::cout, "Using IPv6 proxy at %s\n",
- service.ToStringIPPort());
+ LogPrintf("Using IPv6 proxy at %s\n", service.ToStringIPPort());
SetProxy(NET_IPV6, proxyType(service));
}
}
bool fDNS = true;
- tfm::format(std::cout, "Using %s.\n", gArgs.GetChainName());
+ LogPrintf("Using %s.\n", gArgs.GetChainName());
netMagic = Params().NetMagic();
if (opts.ns.empty()) {
- tfm::format(std::cout, "No nameserver set. Not starting DNS server.\n");
+ LogPrintf("No nameserver set. Not starting DNS server.\n");
fDNS = false;
}
if (fDNS && opts.host.empty()) {
- tfm::format(std::cerr, "No hostname set. Please use -h.\n");
+ LogPrintf("No hostname set. Please use -h.\n");
return EXIT_FAILURE;
}
if (fDNS && opts.mbox.empty()) {
- tfm::format(std::cerr, "No e-mail address set. Please use -m.\n");
+ LogPrintf("No e-mail address set. Please use -m.\n");
return EXIT_FAILURE;
}
FILE *f = fsbridge::fopen(GetDataDir() / "dnsseed.dat", "r");
if (f) {
- tfm::format(std::cout, "Loading dnsseed.dat...");
+ LogPrintfToBeContinued("Loading dnsseed.dat...");
CAutoFile cf(f, SER_DISK, CLIENT_VERSION);
cf >> db;
if (opts.fWipeBan) {
db.banned.clear();
- tfm::format(std::cout, "Ban list wiped...");
+ LogPrintfToBeContinued("Ban list wiped...");
}
if (opts.fWipeIgnore) {
db.ResetIgnores();
- tfm::format(std::cout, "Ignore list wiped...");
+ LogPrintfToBeContinued("Ignore list wiped...");
}
- tfm::format(std::cout, "done\n");
+ LogPrintf("done\n");
}
pthread_t threadDns, threadSeed, threadDump, threadStats;
if (fDNS) {
- tfm::format(std::cout,
- "Starting %i DNS threads for %s on %s (port %i)...",
- opts.nDnsThreads, opts.host, opts.ns, opts.nPort);
+ LogPrintfToBeContinued(
+ "Starting %i DNS threads for %s on %s (port %i)...",
+ opts.nDnsThreads, opts.host, opts.ns, opts.nPort);
dnsThread.clear();
for (int i = 0; i < opts.nDnsThreads; i++) {
dnsThread.push_back(new CDnsThread(&opts, i));
pthread_create(&threadDns, nullptr, ThreadDNS, dnsThread[i]);
- tfm::format(std::cout, ".");
+ LogPrintfToBeContinued(".");
Sleep(20);
}
- tfm::format(std::cout, "done\n");
+ LogPrintf("done\n");
}
- tfm::format(std::cout, "Starting seeder...");
+ LogPrintfToBeContinued("Starting seeder...");
pthread_create(&threadSeed, nullptr, ThreadSeeder, nullptr);
- tfm::format(std::cout, "done\n");
- tfm::format(std::cout, "Starting %i crawler threads...", opts.nThreads);
+ LogPrintf("done\n");
+ LogPrintfToBeContinued("Starting %i crawler threads...", opts.nThreads);
pthread_attr_t attr_crawler;
pthread_attr_init(&attr_crawler);
pthread_attr_setstacksize(&attr_crawler, 0x20000);
@@ -610,7 +630,7 @@
pthread_create(&thread, &attr_crawler, ThreadCrawler, &opts.nThreads);
}
pthread_attr_destroy(&attr_crawler);
- tfm::format(std::cout, "done\n");
+ LogPrintf("done\n");
pthread_create(&threadStats, nullptr, ThreadStats, nullptr);
pthread_create(&threadDump, nullptr, ThreadDumper, nullptr);
void *res;