Merge pull request #6149
27d7605
Buffer log messages and explicitly open logs (Adam Weiss)
This commit is contained in:
commit
633fe10869
|
@ -668,6 +668,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
fLogTimestamps = GetBoolArg("-logtimestamps", true);
|
fLogTimestamps = GetBoolArg("-logtimestamps", true);
|
||||||
fLogIPs = GetBoolArg("-logips", false);
|
fLogIPs = GetBoolArg("-logips", false);
|
||||||
|
|
||||||
|
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||||
|
LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
|
||||||
|
|
||||||
// when specifying an explicit binding address, you want to listen on it
|
// when specifying an explicit binding address, you want to listen on it
|
||||||
// even when -connect or -proxy is specified
|
// even when -connect or -proxy is specified
|
||||||
if (mapArgs.count("-bind")) {
|
if (mapArgs.count("-bind")) {
|
||||||
|
@ -941,8 +944,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
#endif
|
#endif
|
||||||
if (GetBoolArg("-shrinkdebugfile", !fDebug))
|
if (GetBoolArg("-shrinkdebugfile", !fDebug))
|
||||||
ShrinkDebugFile();
|
ShrinkDebugFile();
|
||||||
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
|
||||||
LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
|
if (fPrintToDebugLog)
|
||||||
|
OpenDebugLog();
|
||||||
|
|
||||||
LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
|
LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
|
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
|
||||||
|
|
91
src/util.cpp
91
src/util.cpp
|
@ -175,23 +175,51 @@ instance_of_cinit;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
|
static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We use boost::call_once() to make sure these are initialized
|
* We use boost::call_once() to make sure mutexDebugLog and
|
||||||
* in a thread-safe manner the first time called:
|
* vMsgsBeforeOpenLog are initialized in a thread-safe manner.
|
||||||
|
*
|
||||||
|
* NOTE: fileout, mutexDebugLog and sometimes vMsgsBeforeOpenLog
|
||||||
|
* are leaked on exit. This is ugly, but will be cleaned up by
|
||||||
|
* the OS/libc. When the shutdown sequence is fully audited and
|
||||||
|
* tested, explicit destruction of these objects can be implemented.
|
||||||
*/
|
*/
|
||||||
static FILE* fileout = NULL;
|
static FILE* fileout = NULL;
|
||||||
static boost::mutex* mutexDebugLog = NULL;
|
static boost::mutex* mutexDebugLog = NULL;
|
||||||
|
static list<string> *vMsgsBeforeOpenLog;
|
||||||
|
|
||||||
|
static int FileWriteStr(const std::string &str, FILE *fp)
|
||||||
|
{
|
||||||
|
return fwrite(str.data(), 1, str.size(), fp);
|
||||||
|
}
|
||||||
|
|
||||||
static void DebugPrintInit()
|
static void DebugPrintInit()
|
||||||
{
|
{
|
||||||
assert(fileout == NULL);
|
|
||||||
assert(mutexDebugLog == NULL);
|
assert(mutexDebugLog == NULL);
|
||||||
|
mutexDebugLog = new boost::mutex();
|
||||||
|
vMsgsBeforeOpenLog = new list<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenDebugLog()
|
||||||
|
{
|
||||||
|
boost::call_once(&DebugPrintInit, debugPrintInitFlag);
|
||||||
|
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
|
||||||
|
|
||||||
|
assert(fileout == NULL);
|
||||||
|
assert(vMsgsBeforeOpenLog);
|
||||||
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
|
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
|
||||||
fileout = fopen(pathDebug.string().c_str(), "a");
|
fileout = fopen(pathDebug.string().c_str(), "a");
|
||||||
if (fileout) setbuf(fileout, NULL); // unbuffered
|
if (fileout) setbuf(fileout, NULL); // unbuffered
|
||||||
|
|
||||||
mutexDebugLog = new boost::mutex();
|
// dump buffered messages from before we opened the log
|
||||||
|
while (!vMsgsBeforeOpenLog->empty()) {
|
||||||
|
FileWriteStr(vMsgsBeforeOpenLog->front(), fileout);
|
||||||
|
vMsgsBeforeOpenLog->pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete vMsgsBeforeOpenLog;
|
||||||
|
vMsgsBeforeOpenLog = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LogAcceptCategory(const char* category)
|
bool LogAcceptCategory(const char* category)
|
||||||
|
@ -223,25 +251,56 @@ bool LogAcceptCategory(const char* category)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fStartedNewLine is a state variable held by the calling context that will
|
||||||
|
* suppress printing of the timestamp when multiple calls are made that don't
|
||||||
|
* end in a newline. Initialize it to true, and hold it, in the calling context.
|
||||||
|
*/
|
||||||
|
static std::string LogTimestampStr(const std::string &str, bool *fStartedNewLine)
|
||||||
|
{
|
||||||
|
string strStamped;
|
||||||
|
|
||||||
|
if (!fLogTimestamps)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
if (*fStartedNewLine)
|
||||||
|
strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()) + ' ' + str;
|
||||||
|
else
|
||||||
|
strStamped = str;
|
||||||
|
|
||||||
|
if (!str.empty() && str[str.size()-1] == '\n')
|
||||||
|
*fStartedNewLine = true;
|
||||||
|
else
|
||||||
|
*fStartedNewLine = false;
|
||||||
|
|
||||||
|
return strStamped;
|
||||||
|
}
|
||||||
|
|
||||||
int LogPrintStr(const std::string &str)
|
int LogPrintStr(const std::string &str)
|
||||||
{
|
{
|
||||||
int ret = 0; // Returns total number of characters written
|
int ret = 0; // Returns total number of characters written
|
||||||
|
static bool fStartedNewLine = true;
|
||||||
if (fPrintToConsole)
|
if (fPrintToConsole)
|
||||||
{
|
{
|
||||||
// print to console
|
// print to console
|
||||||
ret = fwrite(str.data(), 1, str.size(), stdout);
|
ret = fwrite(str.data(), 1, str.size(), stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
else if (fPrintToDebugLog && AreBaseParamsConfigured())
|
else if (fPrintToDebugLog)
|
||||||
{
|
{
|
||||||
static bool fStartedNewLine = true;
|
|
||||||
boost::call_once(&DebugPrintInit, debugPrintInitFlag);
|
boost::call_once(&DebugPrintInit, debugPrintInitFlag);
|
||||||
|
|
||||||
if (fileout == NULL)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
|
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
|
||||||
|
|
||||||
|
string strTimestamped = LogTimestampStr(str, &fStartedNewLine);
|
||||||
|
|
||||||
|
// buffer if we haven't opened the log yet
|
||||||
|
if (fileout == NULL) {
|
||||||
|
assert(vMsgsBeforeOpenLog);
|
||||||
|
ret = strTimestamped.length();
|
||||||
|
vMsgsBeforeOpenLog->push_back(strTimestamped);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// reopen the log file, if requested
|
// reopen the log file, if requested
|
||||||
if (fReopenDebugLog) {
|
if (fReopenDebugLog) {
|
||||||
fReopenDebugLog = false;
|
fReopenDebugLog = false;
|
||||||
|
@ -250,17 +309,9 @@ int LogPrintStr(const std::string &str)
|
||||||
setbuf(fileout, NULL); // unbuffered
|
setbuf(fileout, NULL); // unbuffered
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug print useful for profiling
|
ret = FileWriteStr(strTimestamped, fileout);
|
||||||
if (fLogTimestamps && fStartedNewLine)
|
}
|
||||||
ret += fprintf(fileout, "%s ", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
|
|
||||||
if (!str.empty() && str[str.size()-1] == '\n')
|
|
||||||
fStartedNewLine = true;
|
|
||||||
else
|
|
||||||
fStartedNewLine = false;
|
|
||||||
|
|
||||||
ret = fwrite(str.data(), 1, str.size(), fileout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,7 @@ void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map
|
||||||
boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
|
boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
|
||||||
#endif
|
#endif
|
||||||
boost::filesystem::path GetTempPath();
|
boost::filesystem::path GetTempPath();
|
||||||
|
void OpenDebugLog();
|
||||||
void ShrinkDebugFile();
|
void ShrinkDebugFile();
|
||||||
void runCommand(const std::string& strCommand);
|
void runCommand(const std::string& strCommand);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue