From 70ffe10057d5a410b74e8c37eb5f148596bc443e Mon Sep 17 00:00:00 2001
From: Brad Davis <bdavis@saintandreas.org>
Date: Mon, 31 Aug 2015 14:44:12 -0700
Subject: [PATCH] Use a constant log file and rollover accumulated logs to a
 new file based on startup, time or size

---
 interface/src/FileLogger.cpp | 62 ++++++++++++++++++++++++++++--------
 interface/src/FileLogger.h   |  2 +-
 2 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/interface/src/FileLogger.cpp b/interface/src/FileLogger.cpp
index 00da80814b..0b2128cf17 100644
--- a/interface/src/FileLogger.cpp
+++ b/interface/src/FileLogger.cpp
@@ -10,16 +10,39 @@
 //
 
 #include "FileLogger.h"
-#include "HifiSockAddr.h"
-#include <FileUtils.h>
-#include <QDateTime>
-#include <QFile>
-#include <QDir>
-#include <QDesktopServices>
 
-const QString FILENAME_FORMAT = "hifi-log_%1_%2.txt";
-const QString DATETIME_FORMAT = "yyyy-MM-dd_hh.mm.ss";
-const QString LOGS_DIRECTORY = "Logs";
+#include <QtCore/QDateTime>
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtGui/QDesktopServices>
+
+#include <NumericalConstants.h>
+#include <FileUtils.h>
+#include <SharedUtil.h>
+
+#include "HifiSockAddr.h"
+
+static const QString FILENAME_FORMAT = "hifi-log_%1_%2.txt";
+static const QString DATETIME_FORMAT = "yyyy-MM-dd_hh.mm.ss";
+static const QString LOGS_DIRECTORY = "Logs";
+// Max log size is 1 MB
+static const uint64_t MAX_LOG_SIZE = 1024 * 1024;
+// Max log age is 1 hour
+static const uint64_t MAX_LOG_AGE_USECS = USECS_PER_SECOND * 3600;
+
+QString getLogRollerFilename() {
+    QString result = FileUtils::standardPath(LOGS_DIRECTORY);
+    QHostAddress clientAddress = getLocalAddress();
+    QDateTime now = QDateTime::currentDateTime();
+    result.append(QString(FILENAME_FORMAT).arg(clientAddress.toString(), now.toString(DATETIME_FORMAT)));
+    return result;
+}
+
+const QString& getLogFilename() {
+    static QString fileName = FileUtils::standardPath(LOGS_DIRECTORY) + "hifi-log.txt";
+    return fileName;
+}
+
 
 class FilePersistThread : public GenericQueueThread < QString > {    
 public:
@@ -28,8 +51,22 @@ public:
     }
 
 protected:
+    void rollFileIfNecessary(QFile& file) {
+        uint64_t now = usecTimestampNow();
+        if ((file.size() > MAX_LOG_SIZE) || (now - _lastRollTime) > MAX_LOG_AGE_USECS) {
+            QString newFileName = getLogRollerFilename();
+            if (file.copy(newFileName)) {
+                _lastRollTime = now;
+                file.open(QIODevice::WriteOnly | QIODevice::Truncate);
+                file.close();
+                qDebug() << "Rolled log file: " << newFileName;
+            }
+        }
+    }
+
     virtual bool processQueueItems(const Queue& messages) {
         QFile file(_logger._fileName);
+        rollFileIfNecessary(file);
         if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
             QTextStream out(&file);
             foreach(const QString& message, messages) {
@@ -40,20 +77,17 @@ protected:
     }
 private:
     const FileLogger& _logger;
+    uint64_t _lastRollTime = 0; 
 };
 
 static FilePersistThread* _persistThreadInstance;
 
 FileLogger::FileLogger(QObject* parent) :
-    AbstractLoggerInterface(parent)
+    AbstractLoggerInterface(parent), _fileName(getLogFilename())
 {
     _persistThreadInstance = new FilePersistThread(*this);
     _persistThreadInstance->initialize(true, QThread::LowestPriority);
 
-    _fileName = FileUtils::standardPath(LOGS_DIRECTORY);
-    QHostAddress clientAddress = getLocalAddress();
-    QDateTime now = QDateTime::currentDateTime();
-    _fileName.append(QString(FILENAME_FORMAT).arg(clientAddress.toString(), now.toString(DATETIME_FORMAT)));
 }
 
 FileLogger::~FileLogger() {
diff --git a/interface/src/FileLogger.h b/interface/src/FileLogger.h
index 549654ca5c..122da20ae7 100644
--- a/interface/src/FileLogger.h
+++ b/interface/src/FileLogger.h
@@ -27,7 +27,7 @@ public:
     virtual void locateLog() override;
 
 private:
-    QString _fileName;
+    const QString _fileName;
     friend class FilePersistThread;
 };