From 9ae1bb5c6c780c23bf4069d71ab29067dd2d64b0 Mon Sep 17 00:00:00 2001 From: sfadiga Date: Sat, 19 Oct 2013 15:04:26 -0300 Subject: [PATCH] now qlogger can handle qt4 version too and also some small fixes --- README | 6 ++-- configfilehandler.h | 81 ++++++++++++++++++++++++--------------------- configuration.h | 3 +- qlogger.cpp | 27 +++++++++------ qlogger.h | 31 +++++++++++++---- textoutput.cpp | 17 ++++++---- xmloutput.cpp | 3 +- xmloutput.h | 4 +-- 8 files changed, 102 insertions(+), 70 deletions(-) diff --git a/README b/README index e765352..c5b3b32 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ -QLogger - A tiny Qt logging framework. +QLogger - A tiny Qt log framework. -The purpose of this logging framework is to be easy to configure and use on +The purpose of this log framework is to be easy to configure and use on a Qt project. QLogger rely only on Qt framework, so it does not have any other external dependencies. @@ -20,7 +20,7 @@ The code is licensed under MIT License. using namespace qlogger; int main(int argc, char *argv[]) { - QLOG_FATAL("this is quick logged using the default root logger"); + QLOG_FATAL("this is quick log using the default root logger"); //or for the ones who does not like macros QLogger::fatal("this is quick logged using the default root logger"); ... diff --git a/configfilehandler.h b/configfilehandler.h index 6529b20..6081fd3 100644 --- a/configfilehandler.h +++ b/configfilehandler.h @@ -49,23 +49,23 @@ namespace qlogger //! owner.fileName = { file name mask, must contain all %1 %2 %3 params, example: log_%1_%2_%3.txt //! owner.fileNameTimeStamp = { the timestamp that will be written in param %3 of the file name mask, must follow QTimeDate string format. -static const QString LEVEL = "level"; +static const QString CH_LEVEL = "level"; -static const QString OUTPUT_TYPE = "outputType"; +static const QString CH_OUTPUT_TYPE = "outputType"; -static const QString LOG_MASK = "logMask"; +static const QString CH_LOG_MASK = "logMask"; -static const QString MAX_FILE_SIZE = "maxFileSize"; +static const QString CH_MAX_FILE_SIZE = "maxFileSize"; -static const QString PATH = "path"; +static const QString CH_PATH = "path"; -static const QString TIMESTAMP_FORMAT = "timestampFormat"; +static const QString CH_TIMESTAMP_FORMAT = "timestampFormat"; -static const QString FILE_NAME = "fileName"; +static const QString CH_FILE_NAME = "fileName"; -static const QString FILE_NAME_TIMESTAMP = "fileNameTimeStamp"; +static const QString CH_FILE_NAME_TIMESTAMP = "fileNameTimeStamp"; -static const QString CONFIG_FILE_NAME = "qlogger.cfg"; +static const QString CH_CONFIG_FILE_NAME = "qlogger.cfg"; class ConfigFileHandler { @@ -74,17 +74,17 @@ class ConfigFileHandler inline static void recursiveFolderSearch(QDir& dir, bool &found) { - QDir::setCurrent(dir.absolutePath()); + QDir path(dir.absolutePath()); QStringList list = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); const int size = list.size(); for(int i = 0; i < size ; ++i) { - QString path = list.at(i); + QString currentPath = list.at(i); if(found) { return; } - else if(QFile::exists(CONFIG_FILE_NAME)) + else if(QFile::exists(CH_CONFIG_FILE_NAME)) { found = true; return; @@ -92,7 +92,7 @@ class ConfigFileHandler else { found = false; - dir.cd(path); + dir.cd(currentPath); recursiveFolderSearch(dir, found); if(!found) dir.cdUp(); @@ -104,7 +104,7 @@ class ConfigFileHandler inline static bool searchForConfigFile() { - QDir dir(QCoreApplication::applicationDirPath()); + QDir dir(QDir::currentPath()); //search on the folder tree bool found = false; recursiveFolderSearch(dir, found); @@ -112,24 +112,25 @@ class ConfigFileHandler } inline static bool createConfiguration(QMultiHash &ownerConfigLines, - QMultiHash &loggers) + QList &configs)//QMultiHash &loggers) { - QList configs = ownerConfigLines.keys(); + QList configTextList = ownerConfigLines.keys(); QString currentConfig = QString(); bool localTest = false; // the loggers reference could already been filled from somewhere else - const int size = configs.size(); + const int size = configTextList.size(); for(int i = 0 ; i < size ; i++) { - QString config = configs.at(i); - if(currentConfig != config) + QString configText = configTextList.at(i); + if(currentConfig != configText) { - QStringList values = ownerConfigLines.values(config); - loggers.insert(config, parseAllLinesOfConfig(config, values)); - currentConfig = config; + QStringList values = ownerConfigLines.values(configText); + //loggers.insert(config, parseAllLinesOfConfig(config, values)); + configs.append(parseAllLinesOfConfig(configText, values)); + currentConfig = configText; localTest = true; } } - return localTest; + return localTest; } inline static Configuration* parseAllLinesOfConfig(QString owner, QStringList lines) @@ -143,16 +144,18 @@ class ConfigFileHandler QString timestampFormat = QString(); QString fileName = QString(); QString fileNameTimestamp = QString(); - foreach(QString line , lines) + int size = lines.size(); + for (int i = 0 ; i < size ; i++)//(QString line , lines) { + QString line = lines.at(i); QStringList configList = line.trimmed().split("="); QString key = configList.isEmpty() ? QString() : configList.at(0); // left hand QString paramValue = configList.size() < 1 ? QString() : configList.at(1); //right hand - if(key == LEVEL) + if(key == CH_LEVEL) { level = Configuration::levelFromString(paramValue); } - else if(key == OUTPUT_TYPE) + else if(key == CH_OUTPUT_TYPE) { if(paramValue.toUpper().contains("TEXT")) { @@ -167,34 +170,35 @@ class ConfigFileHandler outputType = Configuration::CONSOLE; } } - else if(key == LOG_MASK) + else if(key == CH_LOG_MASK) { logMask = paramValue; } - else if(key == MAX_FILE_SIZE) + else if(key == CH_MAX_FILE_SIZE) { bool ok; maxFileSize = paramValue.toInt(&ok); if(!ok) maxFileSize = 1000; } - else if(key == PATH) - { - path = paramValue; - } - else if(key == TIMESTAMP_FORMAT) + else if(key == CH_TIMESTAMP_FORMAT) { timestampFormat = paramValue; } - else if(key == FILE_NAME) + else if(key == CH_FILE_NAME) { fileName = paramValue; } - else if(key == FILE_NAME_TIMESTAMP) + else if(key == CH_FILE_NAME_TIMESTAMP) { fileNameTimestamp = paramValue; + } + else if(key == CH_PATH) + { + path = paramValue; } } + return new Configuration(owner, level, outputType, timestampFormat, logMask, fileName, fileNameTimestamp, path, maxFileSize); } @@ -202,10 +206,10 @@ class ConfigFileHandler //! only public method, this will receive a hash by reference and fill it with found configurations //! false will be returned if no config is filled in - inline static bool parseConfigurationFile(QMultiHash &loggers) + inline static bool parseConfigurationFile(QList &configs)//(QMultiHash &loggers) { QMultiHash ownerConfigLines; - QFile* file = new QFile(CONFIG_FILE_NAME); + QFile* file = new QFile(CH_CONFIG_FILE_NAME); if (ConfigFileHandler::searchForConfigFile() && file->open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -224,7 +228,8 @@ class ConfigFileHandler } } } while (!configLine.isNull()); - return createConfiguration(ownerConfigLines, loggers); + file->close(); + return createConfiguration(ownerConfigLines, configs); } else { diff --git a/configuration.h b/configuration.h index 1da8c1f..f09e36c 100644 --- a/configuration.h +++ b/configuration.h @@ -24,7 +24,6 @@ #define CONFIGURATION_H #include -#include #include #include "textoutput.h" #include "xmloutput.h" @@ -64,7 +63,7 @@ class Configuration QString logTextMask = DEFAULT_TEXT_MASK, QString fileNameMask = QString(), QString fileNameTimestampFormat = FILE_NAME_TIMESTAMP_FORMAT, - QString filePath = QCoreApplication::applicationDirPath(), + QString filePath = QDir::currentPath(), int fileMaxSizeInKb = 1000); //! destructor, check for outputLog and closes it diff --git a/qlogger.cpp b/qlogger.cpp index d8e53b7..911d7fc 100644 --- a/qlogger.cpp +++ b/qlogger.cpp @@ -44,8 +44,8 @@ QLoggerDestroyer::~QLoggerDestroyer() { QLogger::mutex.lock(); // call the close file methods for all loggers - singleton.loadAcquire()->close(); - delete singleton.loadAcquire(); + QLoggerDestroyer::getPointerInstance()->close(); + delete QLoggerDestroyer::getPointerInstance(); QLogger::mutex.unlock(); } @@ -73,30 +73,37 @@ void QLogger::close() QLogger* QLogger::getInstance() { - if(!instance.load()) + if(!QLogger::getPointerInstance()) { mutex.lock(); if (instance.testAndSetOrdered(0, new QLogger())) { destroyer.SetSingleton(instance); - //add the default "root" logger - QLogger::instance.load()->loggers.insert("root", new Configuration("root", Configuration::q1ERROR)); - // configuration file read, then start with the default logger - ConfigFileHandler::parseConfigurationFile(QLogger::instance.load()->loggers); + QList lst; + //add the default "root" logger + lst.append(new Configuration("root", Configuration::q1ERROR)); + // configuration file read, then start with the default logger + ConfigFileHandler::parseConfigurationFile(lst);//QLogger::getPointerInstance()->loggers); + int size = lst.size(); + for(int i = 0 ; i < size ; i++) + { + Configuration* config = lst.at(i); + QLogger::getPointerInstance()->loggers.insert(config->getLogOwner(), config); + } } mutex.unlock(); } - return instance.loadAcquire(); + return QLogger::getPointerInstance(); } void QLogger::addLogger(QString logOwner, Configuration* configuration) { QLogger::getInstance(); mutex.lock(); - if(!QLogger::instance.load()->loggers.values(logOwner).contains(configuration)) + if(!QLogger::getPointerInstance()->loggers.values(logOwner).contains(configuration)) { configuration->setLogOwner(logOwner); - QLogger::instance.load()->loggers.insert(logOwner, configuration); + QLogger::getPointerInstance()->loggers.insert(logOwner, configuration); } mutex.unlock(); } diff --git a/qlogger.h b/qlogger.h index df56d88..56e76fd 100644 --- a/qlogger.h +++ b/qlogger.h @@ -46,6 +46,17 @@ class QLoggerDestroyer private: QAtomicPointer singleton; +public: + //! Handles the acess to QAtomicPointer methods based on Qt version + inline QLogger* getPointerInstance() + { + #if (QT_VERSION < QT_VERSION_CHECK(5,0,0)) + return singleton; + #else + return singleton.loadAcquire(); + #endif + } + }; //! Main QLogger class, its a singleton responsible for register the log messages to @@ -82,15 +93,23 @@ class QLogger //! this static instance is responsible for call the singleton destructor when program ends static QLoggerDestroyer destroyer; - //! This constructor is the one used for initial set of the level, - //! one call only after the program starts there is no way to change the log level - //QLogger(Configuration); + //! this methods adds a loger based on a configuration + static void addLogger(QString logOwner, Configuration* configuration); - //! Stop the compiler generating methods of copy the object +private: + //! Stop the compiler generating methods of copy the object QLogger(QLogger const& copy); // Not Implemented QLogger& operator=(QLogger const& copy); // Not Implemented - static void addLogger(QString logOwner, Configuration* configuration); + //! Handles the acess to QAtomicPointer methods based on Qt version + static inline QLogger* getPointerInstance() + { + #if (QT_VERSION < QT_VERSION_CHECK(5,0,0)) + return instance; + #else + return instance.loadAcquire(); + #endif + } private: @@ -150,7 +169,7 @@ class QLogger }; - +// MACROS FOR THE PEOPLE! #define QLOG_FATAL(message, ...) QLogger::log(Configuration::q0FATAL, message, __FUNCTION__ , __LINE__, ##__VA_ARGS__); #define QLOG_ERROR(message, ...) QLogger::log(Configuration::q1ERROR, message, __FUNCTION__ , __LINE__ , ##__VA_ARGS__); #define QLOG_WARN(message, ...) QLogger::log(Configuration::q2WARN, message, __FUNCTION__ , __LINE__ , ##__VA_ARGS__); diff --git a/textoutput.cpp b/textoutput.cpp index ccba8a5..aca80e9 100644 --- a/textoutput.cpp +++ b/textoutput.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -105,7 +104,7 @@ TextFileOutput::TextFileOutput(QString logOwner, QString logFormatMask, QString // check if a valid path was informed QDir test(filePath); if(filePath.isEmpty() || !test.exists()) - filePath = QCoreApplication::applicationDirPath(); + filePath = QDir::currentPath(); else filePath = path; @@ -117,7 +116,6 @@ TextFileOutput::TextFileOutput(QString logOwner, QString logFormatMask, QString else fileNameMask = fileMask; - QDir::setCurrent(filePath); createNextFile(); } @@ -131,7 +129,7 @@ TextFileOutput::~TextFileOutput() void TextFileOutput::createNextFile() { - if(qTextStream && currentFile) + if(qTextStream && currentFile) { qTextStream->flush(); delete qTextStream; @@ -139,19 +137,24 @@ void TextFileOutput::createNextFile() currentFile->close(); } // TEXT FILE MODE - currentFile = new QFile(getFileName()); + QDir dir(filePath); + QString myFile = dir.absoluteFilePath(getFileName()); + currentFile = new QFile(myFile); if(currentFile->open(QIODevice::WriteOnly | QIODevice::Text)) - qTextStream = new QTextStream(currentFile); + { + qTextStream = new QTextStream(currentFile); + } else // Fall back to console mode + { qTextStream = new QTextStream(stdout); + } // enables the output to text mode and have correct line breaks qTextStream->device()->setTextModeEnabled(true); qTextStream->setCodec(QTextCodec::codecForName("UTF-8")); } - QString TextFileOutput::getFileName() const { QString name = fileNameMask diff --git a/xmloutput.cpp b/xmloutput.cpp index b9a8d09..ff7b0cb 100644 --- a/xmloutput.cpp +++ b/xmloutput.cpp @@ -39,8 +39,7 @@ XmlOutput::XmlOutput(QString logOwner, if(fileNameMask.isEmpty() || !(fileNameMask.contains("%1") && fileNameMask.contains("%2") && fileNameMask.contains("%3"))) fileNameMask = XML_FILE_NAME_MASK; - QDir::setCurrent(filePath); - createNextFile(); + createNextFile(); } XmlOutput::~XmlOutput() diff --git a/xmloutput.h b/xmloutput.h index cd1e47c..25fa8a0 100644 --- a/xmloutput.h +++ b/xmloutput.h @@ -26,7 +26,7 @@ #include "textoutput.h" #include -#include +#include namespace qlogger @@ -53,7 +53,7 @@ class XmlOutput : public TextFileOutput public: XmlOutput(QString logOwner, QString fileNameMask = XML_FILE_NAME_MASK, QString fileNameTimestampFormat = FILE_NAME_TIMESTAMP_FORMAT, - QString filePath = QCoreApplication::applicationDirPath(), int fileMaxSizeInKb = 100); + QString filePath = QDir::currentPath(), int fileMaxSizeInKb = 100); virtual ~XmlOutput(); //! reimplemented to write a xml on the file