Index: sources/storage/logger.cpp =================================================================== diff -u -r44a85c96ab55e424866ec4cca0270aa218355f82 -rd2035a8728794afeefaa244bf8d1597926d945f5 --- sources/storage/logger.cpp (.../logger.cpp) (revision 44a85c96ab55e424866ec4cca0270aa218355f82) +++ sources/storage/logger.cpp (.../logger.cpp) (revision d2035a8728794afeefaa244bf8d1597926d945f5) @@ -23,9 +23,12 @@ #include // Project +#include "DriveWatcher.h" +#include "threads.h" #include "storageglobals.h" +#include "maintimer.h" #include "filehandler.h" -#include "threads.h" +#include "format.h" using namespace Storage; @@ -35,7 +38,9 @@ * \param parent - QObject parent owner object. * Qt handles the children destruction by their parent objects life-cycle. */ -Logger::Logger(QObject *parent) : QObject(parent) { } +Logger::Logger(QObject *parent) : QObject(parent) { + _logFileNamePrefix = QFileInfo(qApp->applicationFilePath()).baseName(); +} /*! * \brief Logger::init @@ -51,7 +56,7 @@ checkLogPath(); initConnections(); - LOG_EVENT(QObject::tr("%1 Initialized").arg(metaObject()->className())); + LOG_EVENT("UI," + tr("%1 Initialized").arg(metaObject()->className())); return true; } @@ -87,11 +92,6 @@ } // coco end -void Logger::onLog(const QString &vContent, LogType vLogType) -{ - log(vContent,vLogType); -} - /*! * \brief Logger::initConnections * \details Initializes the required signal/slot connection between this class and other objects @@ -100,11 +100,21 @@ */ void Logger::initConnections() { - connect(&_exportWatcher, SIGNAL(finished()), - this , SLOT(onExport())); + connect(&_exportLogsWatcher, SIGNAL(finished ()), + this , SLOT(onExportLogs())); connect(this, SIGNAL(didLog(QString,LogType)), this, SLOT( onLog(QString,LogType))); + + + connect(&_MainTimer, SIGNAL( didDateChange ()), + this , SLOT( concurrentRemoveLogs())); + + connect(&_removeLogsWatcher, SIGNAL(finished ()), + this , SLOT(onRemoveLogs())); + + connect(&_DriveWatcher, SIGNAL( didSDCardSpaceChange(bool, qint64, qint64, quint8)), + this , SLOT( onSDCardSpaceChange(bool, qint64, qint64, quint8))); } /*! @@ -143,6 +153,11 @@ } // coco end +void Logger::onLog(const QString &vContent, LogType vLogType) +{ + log(vContent,vLogType); +} + /*! * \brief Logger::checkLogPath * \details Sets the log paths and creates them if didn't exist. @@ -170,10 +185,12 @@ { if (vUseApplicationDirPath) { _dir.setPath(qApp->applicationDirPath()); - LOG_EVENT(tr("Application Dir Path used for events logging (%1)").arg(_dir.path())); - } else { - _dir.setPath(Log_Base_Path_Name); + // Don't use LOG_XXXXX, At this moment Logger has not been initialized yet + qDebug() << QString("Application path used for events logging (%1)").arg(_dir.path()); } + else { + _dir.setPath(SDCard_Base_Path_Name); + } } /*! @@ -184,9 +201,9 @@ bool Logger::setLogPath() { bool ok = true; - if ( ! setLogPath(LogType::eLogEvent) ) ok = false; - if ( ! setLogPath(LogType::eLogError) ) ok = false; - if ( ! setLogPath(LogType::eLogDatum) ) ok = false; + if ( ok && ! setLogPath(LogType::eLogDebug) ) ok = false; + if ( ok && ! setLogPath(LogType::eLogEvent) ) ok = false; + if ( ok && ! setLogPath(LogType::eLogDatum) ) ok = false; return ok; } @@ -199,17 +216,18 @@ */ bool Logger::setLogPath(LogType vLogType) { - _logPathNames[vLogType] = _dir.path() + "/" + _logBasePathNames[vLogType]; - if ( ! _dir.exists(_logBasePathNames[vLogType]) ) { - if ( ! _dir.mkpath(_logBasePathNames[vLogType]) ) { - LOG_ERROR(tr("Can't create %1 log path (%2)") - .arg(_logPrefix[vLogType]) - .arg(_logPathNames[vLogType]) - ); - return false; - } + bool ok = false; + switch (vLogType) { + case LogType::eLogDebug: + _logPathNames[vLogType] = qApp->applicationDirPath() + "/" + _logBasePathNames[vLogType]; + break; + + default: + _logPathNames[vLogType] = _dir.path() + "/" + _logBasePathNames[vLogType]; + break; } - return true; + ok = FileHandler::makeFolder(_logPathNames[vLogType]); + return ok; } /*! @@ -220,34 +238,37 @@ * \note This method is not thread-safe so is private and needs to be called by concurrentLog * Which uses QtConcurrent::run to run in thread and thread-safe. */ -void Logger::log(const QString &vContent, Logger::LogType vLogType) +void Logger::log(const QString &vContent, LogType vLogType) { QString date = QDate::currentDate().toString(_dateFormat); - QString mContent; - + QString fileName = date + _dateSeparator + _logFileNamePrefix; switch (vLogType) { - case eLogEvent: - case eLogError: - case eLogDatum: + case LogType::eLogEvent: + case LogType::eLogDatum: + case LogType::eLogDebug: + fileName += _logFileNameExt[vLogType]; break; default: - LOG_ERROR(tr("Incorrect type of logging").arg(vLogType)); + fileName += _logFileNameExt[eLogDebug]; + LOG_DEBUG(QString("Incorrect type of logging %1").arg(vLogType)); } + QString mContent = QTime::currentTime().toString(_timeFormat) + _separator; + QString logPrefix = _logPrefix[vLogType]; - if (logPrefix.isEmpty()) logPrefix = _logPrefix[LogType::eLogError]; - mContent += logPrefix; - mContent += _prefixSeparator; - mContent += QTime::currentTime().toString(_timeFormat); - mContent += _timeSeparator + vContent; - QString fileName = date + _dateSeparator + Log_File_Name; + if ( ! logPrefix.isEmpty()) { + mContent += logPrefix; + mContent += _separator; + } + mContent += vContent; + QString logPathName = _logPathNames[vLogType]; if (logPathName.isEmpty()) - logPathName = _logPathNames[LogType::eLogError]; + logPathName = _logPathNames[eLogDebug]; _logFileName = logPathName + fileName; FileHandler::write(_logFileName, mContent + "\r\n", true); - if (vLogType == eLogError) { + if (vLogType == eLogDebug) { #ifdef QT_DEBUG //mContent.prepend("\033[1;31m --- @ --- \033[0m"); mContent.prepend(" @ "); @@ -256,29 +277,121 @@ } } + +bool Logger::exportLogs() +{ + // coco begin validated: This needs user interaction to check the old files deleted + // has been tested manually + int result = 0; + static QString mOSource; + QString mDestination = USB_Mount_Point; + for ( const auto &iType : { eLogEvent , eLogDatum } ) { + QString mCSource = _logPathNames[iType]; + if (mOSource != mCSource) { + mOSource = mCSource; + // Copy Folder + result = FileHandler::copyFolder( mCSource, mDestination); + } + } + mOSource = ""; + return result >= 0; // refer to QProcess::execute(hit F1 on execute) doc. +} +// coco end + /*! - * \brief Logger::concurrentExport + * \brief Logger::concurrentExportLogs * \details Exports the log files from log folder (Storage::Log_Base_Path_Name_Location) * into USB drive folder (Storage::USB_Mount_Point) * \return always returns true for now. * \note This method uses QtConcurrent run to execute the FileHandler copyFolder method. */ -bool Logger::concurrentExport() +bool Logger::concurrentExportLogs() { // coco begin validated: This needs user interaction to export to USB device // has been tested manually - QString mSource = Storage::Log_Base_Path_Name_Location; - QString mDestination = Storage::USB_Mount_Point; - QFuture future = QtConcurrent::run(&FileHandler::copyFolder, mSource, mDestination); - _exportWatcher.setFuture(future); - return true; + LOG_DEBUG("Export Logs Start"); + QFuture future = QtConcurrent::run(this, &Logger::exportLogs); + _exportLogsWatcher.setFuture(future); + return true; } // coco end -void Logger::onExport() +void Logger::onExportLogs() { // coco begin validated: This needs user interaction to export to USB device // has been tested manually - emit didExport(); + LOG_DEBUG(QString("Export Logs Ended: %1").arg(_exportLogsWatcher.result())); + emit didExportLogs(); } // coco end + +/*! + * \brief Logger::removeLogs + * \details Remove old logs by iterating in the log/service folders and look for expired logs. + * \return count file(s) have been removed. + */ +int Logger::removeLogs() +{ + // coco begin validated: This needs user interaction to check the old files deleted + // has been tested manually + static QString mOSource; + int countRemoved = 0; + QStringList mLogFileFilter; + QDate mOlderThan ; + for ( const auto &iType : { eLogEvent , eLogDatum , eLogDebug } ) { + QString mCSource = _logPathNames[iType]; + if (mOSource != mCSource) { + mOSource = mCSource; + // Remove Logs + if (_logTypeExpiryDay.value(iType)) { + mOlderThan = QDate().currentDate().addDays( _logTypeExpiryDay.value(iType) * -1 /*Please Notice (-1)*/ ); + mLogFileFilter = Format::toStringList(_logFileNameExt .values(iType), true, "*"); + LOG_DEBUG(QString("Removing logs older than %1 from folder %2").arg(mOlderThan.toString("yyyy-MM-dd")).arg(mCSource)); + countRemoved += FileHandler::removeFiles({ mCSource }, mLogFileFilter, mOlderThan); + } + else { + LOG_DEBUG("Current day logs cannot be deletet"); + } + } + } + mOSource = ""; + return countRemoved; +} +// coco end + +/*! + * \brief Logger::concurrentRemoveLogs + * \details + * + * \return always returns true for now. + * \note This method uses QtConcurrent run to execute the FileHandler copyFolder method. + */ +bool Logger::concurrentRemoveLogs() +{ + // coco begin validated: This needs user interaction to check the old files deleted + // has been tested manually + LOG_DEBUG("Remove Logs Start"); + QFuture mFuture = QtConcurrent::run(this,&Logger::removeLogs); + _removeLogsWatcher.setFuture(mFuture); + return true; +} +// coco end + +void Logger::onRemoveLogs() +{ + // coco begin validated: This needs user interaction to export to USB device + // has been tested manually + LOG_DEBUG(QString("Remove Logs Ended: %1").arg(_removeLogsWatcher.result())); + emit didRemoveLogs(); +} + +void Logger::onSDCardSpaceChange(bool vReady, qint64 vTotal, qint64 vAvailable, quint8 vPercent) +{ + Q_UNUSED(vReady ) + Q_UNUSED(vTotal ) + Q_UNUSED(vAvailable ) + if (vPercent < _availableSpacePercent ) { + concurrentRemoveLogs(); + } +} +// coco end