zcashd/src/logging.cpp

146 lines
4.5 KiB
C++
Raw Normal View History

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Copyright (c) 2018-2023 The Zcash developers
// Distributed under the MIT software license, see the accompanying
2020-12-12 16:33:22 -08:00
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "logging.h"
#include "fs.h"
#include "serialize.h"
scripted-diff: Move util files to separate directory. -BEGIN VERIFY SCRIPT- mkdir -p src/util git mv src/util.h src/util/system.h git mv src/util.cpp src/util/system.cpp git mv src/utilmoneystr.h src/util/moneystr.h git mv src/utilmoneystr.cpp src/util/moneystr.cpp git mv src/utilstrencodings.h src/util/strencodings.h git mv src/utilstrencodings.cpp src/util/strencodings.cpp git mv src/utiltime.h src/util/time.h git mv src/utiltime.cpp src/util/time.cpp sed -i -e 's/"util\.h"/"util\/system\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') git checkout HEAD -- src/secp256k1 # exclude secp256k1, which has its own "util.h" sed -i -e 's/"utilmoneystr\.h"/"util\/moneystr\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/"utilstrencodings\.h"/"util\/strencodings\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/<utilstrencodings\.h>/<util\/strencodings\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/"utiltime\.h"/"util\/time\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/BITCOIN_UTIL_H/BITCOIN_UTIL_SYSTEM_H/g' src/util/system.h sed -i -e 's/BITCOIN_UTILMONEYSTR_H/BITCOIN_UTIL_MONEYSTR_H/g' src/util/moneystr.h sed -i -e 's/BITCOIN_UTILSTRENCODINGS_H/BITCOIN_UTIL_STRENCODINGS_H/g' src/util/strencodings.h sed -i -e 's/BITCOIN_UTILTIME_H/BITCOIN_UTIL_TIME_H/g' src/util/time.h sed -i -e 's/ util\.\(h\|cpp\)/ util\/system\.\1/g' src/Makefile.am sed -i -e 's/utilmoneystr\.\(h\|cpp\)/util\/moneystr\.\1/g' src/Makefile.am sed -i -e 's/utilstrencodings\.\(h\|cpp\)/util\/strencodings\.\1/g' src/Makefile.am sed -i -e 's/utiltime\.\(h\|cpp\)/util\/time\.\1/g' src/Makefile.am sed -i -e 's/src\/util\.cpp/src\/util\/system\.cpp/g' test/lint/lint-locale-dependence.sh sed -i -e 's/src\/utilmoneystr\.cpp/src\/util\/moneystr\.cpp/g' test/lint/lint-locale-dependence.sh sed -i -e 's/src\/utilstrencodings\.\(h\|cpp\)/src\/util\/strencodings\.\1/g' test/lint/lint-locale-dependence.sh -END VERIFY SCRIPT-
2018-10-22 15:51:11 -07:00
#include "util/system.h"
#include <set>
#include <boost/thread/mutex.hpp>
#include <boost/thread/once.hpp>
#include <boost/thread/tss.hpp>
using namespace std;
const char * const DEFAULT_DEBUGLOGFILE = "debug.log";
bool fPrintToConsole = false;
bool fPrintToDebugLog = true;
bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS;
bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS;
bool fLogIPs = DEFAULT_LOGIPS;
std::atomic<bool> fReopenDebugLog(false);
/**
* LogPrintf() has been broken a couple of times now
* by well-meaning people adding mutexes in the most straightforward way.
* It breaks because it may be called by global destructors during shutdown.
* Since the order of destruction of static/global objects is undefined,
* defining a mutex as a global object doesn't work (the mutex gets
* destroyed, and then some later destructor calls OutputDebugStringF,
* maybe indirectly, and you get a core dump at shutdown trying to lock
* the mutex).
*/
static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
/**
* We use boost::call_once() to make sure mutexDebugLog and
* 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 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()
{
assert(mutexDebugLog == NULL);
mutexDebugLog = new boost::mutex();
vMsgsBeforeOpenLog = new list<string>;
}
fs::path GetDebugLogPath()
{
fs::path logfile(GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE));
return AbsPathForConfigVal(logfile);
}
std::string LogConfigFilter()
{
// With no -debug flags, show errors and LogPrintf lines.
std::string filter = "error,main=info";
auto& categories = mapMultiArgs["-debug"];
std::set<std::string> setCategories(categories.begin(), categories.end());
if (setCategories.count(string("")) != 0 || setCategories.count(string("1")) != 0) {
// Turn on the firehose!
filter = "debug";
} else {
for (auto category : setCategories) {
filter += "," + category + "=debug";
}
}
return filter;
}
bool LogAcceptCategory(const char* category)
{
if (category != NULL)
{
if (!fDebug)
return false;
// Give each thread quick access to -debug settings.
// This helps prevent issues debugging global destructors,
// where mapMultiArgs might be deleted before another
// global destructor calls LogPrint()
static boost::thread_specific_ptr<set<string> > ptrCategory;
if (ptrCategory.get() == NULL)
{
const vector<string>& categories = mapMultiArgs["-debug"];
ptrCategory.reset(new set<string>(categories.begin(), categories.end()));
// thread_specific_ptr automatically deletes the set when the thread ends.
}
const set<string>& setCategories = *ptrCategory.get();
// if not debugging everything and not debugging specific category, LogPrint does nothing.
if (setCategories.count(string("")) == 0 &&
setCategories.count(string("1")) == 0 &&
setCategories.count(string(category)) == 0)
return false;
}
return true;
}
void ShrinkDebugFile()
{
// Scroll debug log if it's getting too big
fs::path pathLog = GetDebugLogPath();
FILE* file = fsbridge::fopen(pathLog, "r");
if (file && fs::file_size(pathLog) > 10 * 1000000)
{
// Restart the file with some of the end
std::vector <char> vch(200000,0);
fseek(file, -((long)vch.size()), SEEK_END);
int nBytes = fread(begin_ptr(vch), 1, vch.size(), file);
fclose(file);
file = fsbridge::fopen(pathLog, "w");
if (file)
{
fwrite(begin_ptr(vch), 1, nBytes, file);
fclose(file);
}
}
else if (file != NULL)
fclose(file);
}