diff --git a/src/init.cpp b/src/init.cpp index 703815196..ad2472816 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -306,7 +306,7 @@ void HandleSIGTERM(int) void HandleSIGHUP(int) { - fReopenDebugLog = true; + fReopenLogFiles = true; } bool static Bind(const CService &addr, unsigned int flags) { diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 3e9c12fc9..3bece8261 100755 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -320,8 +321,9 @@ RPCConsole::~RPCConsole() void RPCConsole::errorLogInitPos() { + error("errorLogInitPos"); // Get a QFile instance - errorLogFile = new QFile(QString::fromStdString(GetDebugLogPath().string())); + errorLogFile = new QFile(QString::fromStdString(GetErrorLogPath().string())); // Try to open file if (!errorLogFile->open(QFile::ReadOnly | QFile::Text)) @@ -370,15 +372,10 @@ void RPCConsole::errorLogRefresh() QTextStream in(errorLogFile); // Load up the lines - QString line; QString logLines = ""; while (!in.atEnd()) { // Load the next line - line = in.readLine() + "\n"; - - // Check if it's an error - if (line.contains("error", Qt::CaseInsensitive) && !line.contains("ErrorFile")) - logLines += line; // Use the line + logLines += in.readLine() + "\n"; } // Check if we have lines @@ -387,6 +384,32 @@ void RPCConsole::errorLogRefresh() ui->errorLogTextBrowser->textCursor().insertText(logLines); } + // Count the lines in the UI textarea + int uiLineCount = ui->errorLogTextBrowser->document()->lineCount(); + + // Check if lines are more than ERROR_LOG_INITIAL_COUNT + if (uiLineCount > ERROR_LOG_INITIAL_COUNT) { + // Count how many to remove + int lineCountDiff = uiLineCount - ERROR_LOG_INITIAL_COUNT; + + // Get our cursor + QTextCursor cursor = ui->errorLogTextBrowser->textCursor(); + + // REMOVE THEM + for (int i = 0; i < lineCountDiff; i++) { + cursor.movePosition(QTextCursor::Start); + cursor.select(QTextCursor::LineUnderCursor); + cursor.deleteChar(); // Remove the selected text + cursor.deleteChar(); // This is by design, this removes the \n + } + + // Replace the cursor + ui->errorLogTextBrowser->setTextCursor(cursor); + + // Move cursor back to the end + ui->errorLogTextBrowser->moveCursor(QTextCursor::End); + } + // Mark as done errorLogRefreshing = false; } diff --git a/src/qt/ui_getaddresstoreceive.h b/src/qt/ui_getaddresstoreceive.h index 34ddbc84b..6312246ad 100644 --- a/src/qt/ui_getaddresstoreceive.h +++ b/src/qt/ui_getaddresstoreceive.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'getaddresstoreceive.ui' ** -** Created by: Qt User Interface Compiler version 5.9.5 +** Created by: Qt User Interface Compiler version 5.7.1 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/src/qt/ui_navtechsetup.h b/src/qt/ui_navtechsetup.h index 4bbc0b222..bf9d29cb3 100644 --- a/src/qt/ui_navtechsetup.h +++ b/src/qt/ui_navtechsetup.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'navtechsetup.ui' ** -** Created by: Qt User Interface Compiler version 5.9.5 +** Created by: Qt User Interface Compiler version 5.7.1 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/src/util.cpp b/src/util.cpp index caa69fb87..5a8d0a1f0 100755 --- a/src/util.cpp +++ b/src/util.cpp @@ -122,7 +122,7 @@ string strMiscWarning; bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; bool fLogIPs = DEFAULT_LOGIPS; -std::atomic fReopenDebugLog(false); +std::atomic fReopenLogFiles(false); CTranslationInterface translationInterface; /** Init OpenSSL library multithreading support */ @@ -193,12 +193,13 @@ 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 + * NOTE: fileoutDebugLog, fileoutErrorLog, 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* fileoutDebugLog = NULL; +static FILE* fileoutErrorLog = NULL; static boost::mutex* mutexDebugLog = NULL; static list *vMsgsBeforeOpenLog; @@ -207,6 +208,23 @@ static int FileWriteStr(const std::string &str, FILE *fp) return fwrite(str.data(), 1, str.size(), fp); } +static int LogWriteStr(const std::string &str) +{ + // Save the size of written data + int size = FileWriteStr(str, fileoutDebugLog); // write to debug log + + // What is our prefix + std::string prefix = "ERROR"; + + // Check if we need to write to error log + if (str.find(prefix) != string::npos) { + FileWriteStr(str, fileoutErrorLog); // write to error log + } + + // Return the int from the write size + return size; +} + static void DebugPrintInit() { assert(mutexDebugLog == NULL); @@ -219,15 +237,20 @@ void OpenDebugLog() boost::call_once(&DebugPrintInit, debugPrintInitFlag); boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); - assert(fileout == NULL); + assert(fileoutDebugLog == NULL); assert(vMsgsBeforeOpenLog); - boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; - fileout = fopen(pathDebug.string().c_str(), "a"); - if (fileout) setbuf(fileout, NULL); // unbuffered + + // Open the debug log + fileoutDebugLog = fopen(GetDebugLogPath().string().c_str(), "a"); + if (fileoutDebugLog) setbuf(fileoutDebugLog, NULL); // unbuffered + + // Open the error log + fileoutErrorLog = fopen(GetErrorLogPath().string().c_str(), "a"); + if (fileoutErrorLog) setbuf(fileoutErrorLog, NULL); // unbuffered // dump buffered messages from before we opened the log while (!vMsgsBeforeOpenLog->empty()) { - FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); + LogWriteStr(vMsgsBeforeOpenLog->front()); // write to log vMsgsBeforeOpenLog->pop_front(); } @@ -298,6 +321,11 @@ boost::filesystem::path GetDebugLogPath() return GetDataDir() / "debug.log"; } +boost::filesystem::path GetErrorLogPath() +{ + return GetDataDir() / "error.log"; +} + int LogPrintStr(const std::string &str) { int ret = 0; // Returns total number of characters written @@ -317,7 +345,7 @@ int LogPrintStr(const std::string &str) boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); // buffer if we haven't opened the log yet - if (fileout == NULL) { + if (fileoutDebugLog == NULL) { assert(vMsgsBeforeOpenLog); ret = strTimestamped.length(); vMsgsBeforeOpenLog->push_back(strTimestamped); @@ -325,16 +353,17 @@ int LogPrintStr(const std::string &str) else { // reopen the log file, if requested - if (fReopenDebugLog) { - fReopenDebugLog = false; - boost::filesystem::path pathDebug = GetDebugLogPath(); - if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL) - setbuf(fileout, NULL); // unbuffered + if (fReopenLogFiles) { + fReopenLogFiles = false; + + // Open the log files + OpenDebugLog(); } - ret = FileWriteStr(strTimestamped, fileout); + ret = LogWriteStr(strTimestamped); } } + return ret; } @@ -747,19 +776,19 @@ bool TryCreateDirectory(const boost::filesystem::path& p) return false; } -void FileCommit(FILE *fileout) +void FileCommit(FILE *file) { - fflush(fileout); // harmless if redundantly called + fflush(file); // harmless if redundantly called #ifdef WIN32 - HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(fileout)); + HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file)); FlushFileBuffers(hFile); #else #if defined(__linux__) || defined(__NetBSD__) - fdatasync(fileno(fileout)); + fdatasync(fileno(file)); #elif defined(__APPLE__) && defined(F_FULLFSYNC) - fcntl(fileno(fileout), F_FULLFSYNC, 0); + fcntl(fileno(file), F_FULLFSYNC, 0); #else - fsync(fileno(fileout)); + fsync(fileno(file)); #endif #endif } @@ -842,11 +871,16 @@ void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) { } void ShrinkDebugFile() +{ + ShrinkDebugFile(GetDebugLogPath(), 10); // Shrink the debug log + ShrinkDebugFile(GetErrorLogPath(), 2); // Shrink the error log +} + +void ShrinkDebugFile(boost::filesystem::path pathLog, int maxSize) { // Scroll debug.log if it's getting too big - boost::filesystem::path pathLog = GetDataDir() / "debug.log"; FILE* file = fopen(pathLog.string().c_str(), "r"); - if (file && boost::filesystem::file_size(pathLog) > 10 * 1000000) + if (file && boost::filesystem::file_size(pathLog) > maxSize * 1000000) { // Restart the file with some of the end std::vector vch(200000,0); diff --git a/src/util.h b/src/util.h index ac5c4ac15..c9e6d8efc 100755 --- a/src/util.h +++ b/src/util.h @@ -51,7 +51,7 @@ extern std::string strMiscWarning; extern bool fLogTimestamps; extern bool fLogTimeMicros; extern bool fLogIPs; -extern std::atomic fReopenDebugLog; +extern std::atomic fReopenLogFiles; extern CTranslationInterface translationInterface; extern const char * const NAVCOIN_CONF_FILENAME; @@ -76,6 +76,9 @@ bool LogAcceptCategory(const char* category); /** Returns the path to the debug.log file */ boost::filesystem::path GetDebugLogPath(); +/** Returns the path to the error.log file */ +boost::filesystem::path GetErrorLogPath(); + /** Send a string to the log output */ int LogPrintStr(const std::string &str); @@ -123,7 +126,7 @@ static inline bool error(std::string s) } void PrintExceptionContinue(const std::exception *pex, const char* pszThread); void ParseParameters(int argc, const char*const argv[]); -void FileCommit(FILE *fileout); +void FileCommit(FILE *file); bool TruncateFile(FILE *file, unsigned int length); int RaiseFileDescriptorLimit(int nMinFD); void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length); @@ -147,6 +150,7 @@ boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif void OpenDebugLog(); void ShrinkDebugFile(); +void ShrinkDebugFile(boost::filesystem::path pathLog, int maxSize); void runCommand(const std::string& strCommand); inline bool IsSwitchChar(char c)