Add rolled log files to BugSplat

This commit is contained in:
Ryan Huffman 2016-04-06 10:14:12 -07:00
parent 891cc12d3f
commit 5fb898de74
3 changed files with 64 additions and 32 deletions

View file

@ -12,7 +12,6 @@
#include "FileLogger.h" #include "FileLogger.h"
#include <QtCore/QDateTime> #include <QtCore/QDateTime>
#include <QtCore/QFile>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtGui/QDesktopServices> #include <QtGui/QDesktopServices>
@ -30,6 +29,8 @@ static const qint64 MAX_LOG_SIZE = 1024 * 1024;
// Max log age is 1 hour // Max log age is 1 hour
static const uint64_t MAX_LOG_AGE_USECS = USECS_PER_SECOND * 3600; static const uint64_t MAX_LOG_AGE_USECS = USECS_PER_SECOND * 3600;
static FilePersistThread* _persistThreadInstance;
QString getLogRollerFilename() { QString getLogRollerFilename() {
QString result = FileUtils::standardPath(LOGS_DIRECTORY); QString result = FileUtils::standardPath(LOGS_DIRECTORY);
QHostAddress clientAddress = getGuessedLocalAddress(); QHostAddress clientAddress = getGuessedLocalAddress();
@ -43,51 +44,53 @@ const QString& getLogFilename() {
return fileName; return fileName;
} }
FilePersistThread::FilePersistThread(const FileLogger& logger) : _logger(logger) {
setObjectName("LogFileWriter");
class FilePersistThread : public GenericQueueThread < QString > { // A file may exist from a previous run - if it does, roll the file and suppress notifying listeners.
public: QFile file(_logger._fileName);
FilePersistThread(const FileLogger& logger) : _logger(logger) { if (file.exists()) {
setObjectName("LogFileWriter"); rollFileIfNecessary(file, false);
} }
_lastRollTime = usecTimestampNow();
}
protected: void FilePersistThread::rollFileIfNecessary(QFile& file, bool notifyListenersIfRolled) {
void rollFileIfNecessary(QFile& file) { uint64_t now = usecTimestampNow();
uint64_t now = usecTimestampNow(); if ((file.size() > MAX_LOG_SIZE) || (now - _lastRollTime) > MAX_LOG_AGE_USECS) {
if ((file.size() > MAX_LOG_SIZE) || (now - _lastRollTime) > MAX_LOG_AGE_USECS) { QString newFileName = getLogRollerFilename();
QString newFileName = getLogRollerFilename(); if (file.copy(newFileName)) {
if (file.copy(newFileName)) { file.open(QIODevice::WriteOnly | QIODevice::Truncate);
_lastRollTime = now; file.close();
file.open(QIODevice::WriteOnly | QIODevice::Truncate); qDebug() << "Rolled log file:" << newFileName;
file.close();
qDebug() << "Rolled log file:" << newFileName; if (notifyListenersIfRolled) {
emit rollingLogFile(newFileName);
} }
_lastRollTime = now;
} }
} }
}
virtual bool processQueueItems(const Queue& messages) { bool FilePersistThread::processQueueItems(const Queue& messages) {
QFile file(_logger._fileName); QFile file(_logger._fileName);
rollFileIfNecessary(file); rollFileIfNecessary(file);
if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
QTextStream out(&file); QTextStream out(&file);
foreach(const QString& message, messages) { foreach(const QString& message, messages) {
out << message; out << message;
}
} }
return true;
} }
private: return true;
const FileLogger& _logger; }
uint64_t _lastRollTime = 0;
};
static FilePersistThread* _persistThreadInstance;
FileLogger::FileLogger(QObject* parent) : FileLogger::FileLogger(QObject* parent) :
AbstractLoggerInterface(parent), _fileName(getLogFilename()) AbstractLoggerInterface(parent), _fileName(getLogFilename())
{ {
_persistThreadInstance = new FilePersistThread(*this); _persistThreadInstance = new FilePersistThread(*this);
_persistThreadInstance->initialize(true, QThread::LowestPriority); _persistThreadInstance->initialize(true, QThread::LowestPriority);
connect(_persistThreadInstance, &FilePersistThread::rollingLogFile, this, &FileLogger::rollingLogFile);
} }
FileLogger::~FileLogger() { FileLogger::~FileLogger() {

View file

@ -15,6 +15,8 @@
#include "AbstractLoggerInterface.h" #include "AbstractLoggerInterface.h"
#include <GenericQueueThread.h> #include <GenericQueueThread.h>
#include <QtCore/QFile>
class FileLogger : public AbstractLoggerInterface { class FileLogger : public AbstractLoggerInterface {
Q_OBJECT Q_OBJECT
@ -27,11 +29,32 @@ public:
virtual QString getLogData() override; virtual QString getLogData() override;
virtual void locateLog() override; virtual void locateLog() override;
signals:
void rollingLogFile(QString newFilename);
private: private:
const QString _fileName; const QString _fileName;
friend class FilePersistThread; friend class FilePersistThread;
}; };
class FilePersistThread : public GenericQueueThread < QString > {
Q_OBJECT
public:
FilePersistThread(const FileLogger& logger);
signals:
void rollingLogFile(QString newFilename);
protected:
void rollFileIfNecessary(QFile& file, bool notifyListenersIfRolled = true);
virtual bool processQueueItems(const Queue& messages);
private:
const FileLogger& _logger;
uint64_t _lastRollTime;
};
#endif // hifi_FileLogger_h #endif // hifi_FileLogger_h

View file

@ -177,8 +177,14 @@ int main(int argc, const char* argv[]) {
}); });
// BugSplat WILL NOT work with file paths that do not use OS native separators. // BugSplat WILL NOT work with file paths that do not use OS native separators.
auto logPath = QDir::toNativeSeparators(app.getLogger()->getFilename()); auto logger = app.getLogger();
auto logPath = QDir::toNativeSeparators(logger->getFilename());
mpSender.sendAdditionalFile(qPrintable(logPath)); mpSender.sendAdditionalFile(qPrintable(logPath));
QObject::connect(logger, &FileLogger::rollingLogFile, &app, [&mpSender](QString newFilename) {
auto rolledLogPath = QDir::toNativeSeparators(newFilename);
mpSender.sendAdditionalFile(qPrintable(rolledLogPath));
});
#endif #endif
printSystemInformation(); printSystemInformation();