/*! * * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * \copyright \n * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, \n * IN PART OR IN WHOLE, \n * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. \n * * \file logger.h * \date 2019/09/30 * \author Behrouz NematiPour * */ #pragma once // Qt #include #include #include // Project #include "main.h" #include "storageglobals.h" // Define #define _Logger Storage::Logger::I() #define LOG_EXPORT _Logger.concurrentExportLogs() #define LOG_DEBUG(vCONTENT) emit Storage::Logger::I().didLog(vCONTENT, Storage::Logger::LogType::eLogDebug) #define LOG_EVENT(vCONTENT) emit Storage::Logger::I().didLog(vCONTENT, Storage::Logger::LogType::eLogEvent) #define LOG_DATUM(vCONTENT) emit Storage::Logger::I().didLog(vCONTENT, Storage::Logger::LogType::eLogDatum) // forward declarations class tst_logging; namespace Storage { /*! * \brief The Logger class * \details Main logger class that has all the required implementation for logging. * The provided interface is the LOG_DATUM, LOG_EVENT, LOG_DEBUG, LOG_EXPORT defines * and no other methods. * This should have its own thread. * \note * PLEASE BE CAREFUL THIS CLASS IS USING QtConcurrent::run FOR THE EXPORT LOG FILES. * AND ONLY PRIVATE VOID LOG (,) IS CALLING IN POOLED THREAD * PLEASE BE VERY CAREFUL. * ALL THE OTHER CLASSES TO USE THIS CLASS SHOULD ONLY USE LOG_DATUM, LOG_EVENT, LOG_DEBUG * TO DO THE LOGGING */ class Logger : public QObject { Q_OBJECT // friends friend class ::tst_logging; public : enum LogType { eLogDebug, ///< Application Error : CANBus messages doesn't have error it's Evnet/Data only eLogEvent, ///< Massages on the CANBus : Error is an event type eLogDatum, ///< Massages on the CANBus : Broadcast data type eLogType_Count, }; private: QDir _dir; QString _logFileNamePrefix; QHash _logPathNames; const QHash _logBasePathNames { { LogType::eLogEvent, "log/" }, { LogType::eLogDatum, "log/" }, { LogType::eLogDebug, "service/" }, }; const QHash _logPrefix { // Will be used for the logging in the file { LogType::eLogEvent, "E" }, { LogType::eLogDatum, "D" }, { LogType::eLogDebug, "" }, // it has its own file and all the content is Error }; const QHash _logTypeName { // Will be used for for information { LogType::eLogEvent, "Event" }, { LogType::eLogDatum, "Datum" }, { LogType::eLogDebug, "Error" }, // it has its own file and all the content is Error }; const QHash _logFileNameExt { { LogType::eLogEvent, ".log" }, { LogType::eLogDatum, ".log" }, { LogType::eLogDebug, ".err" }, }; const QHash _logTypeExpiryDay { { LogType::eLogEvent, 15 }, { LogType::eLogDatum, 15 }, { LogType::eLogDebug, 5 }, }; const qint8 _availableSpacePercent = 25; // currently 16G SD-Card so 4G should always be available. const char *_dateFormat = "yyyy_MM_dd"; const char *_timeFormat = "HH:mm:ss"; const char *_dateSeparator = "_"; // used in filename const char *_separator = ","; QString _logFileName = ""; QFutureWatcher _exportLogsWatcher; QFutureWatcher _removeLogsWatcher; QThread *_thread = nullptr; bool _init = false; // Singleton SINGLETON(Logger) public slots: bool init(); bool init(QThread &vThread); private slots: void quit(); private: void initConnections(); void initThread(QThread &vThread); void quitThread(); private: // ----- setting up void checkLogPath (); void setLogBasePath (bool vUseApplicationDirPath = false); bool setLogPath (); bool setLogPath (LogType vLogType); // ----- Export structure private : bool exportLogs(); public slots: // this slot is thread safe and can be called from outside by LOG_EXPORT. bool concurrentExportLogs(); void onExportLogs(); signals: void didExportLogs(); // ----- Remove Old Logs structure private: int removeLogs(); private slots: // this slot is thread safe and can be called from outside but preffered not to. bool concurrentRemoveLogs(); void onRemoveLogs(); signals: void didRemoveLogs(); // ----- Available space is low private slots: void onSDCardSpaceChange(bool vReady, qint64 vTotal, qint64 vAvailable, quint8 vPercent); // ----- logging structure private slots: void onLog (const QString &vContent, LogType vLogType); private: void log (const QString &vContent, LogType vLogType); signals: /*! * \brief didLog * \details Notifies the logger on a request for log * \param vContent - content as type of string to be logged * \param vLogType - the type of logging of type Storage::Logger::LogType */ void didLog (const QString &vContent, LogType vLogType); }; }