diff --git a/CMakeLists.txt b/CMakeLists.txt index 057c05d..f5e7f4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) +CMAKE_MINIMUM_REQUIRED(VERSION 3.1) SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/include/FileAppender.h b/include/FileAppender.h index ab9e12a..b57a087 100644 --- a/include/FileAppender.h +++ b/include/FileAppender.h @@ -32,6 +32,11 @@ class CUTELOGGERSHARED_EXPORT FileAppender : public AbstractStringAppender QString fileName() const; void setFileName(const QString&); + bool flushOnWrite() const; + void setFlushOnWrite(bool); + + bool flush(); + bool reopenFile(); protected: @@ -42,6 +47,7 @@ class CUTELOGGERSHARED_EXPORT FileAppender : public AbstractStringAppender private: QFile m_logFile; + bool m_flushOnWrite; QTextStream m_logStream; mutable QMutex m_logFileMutex; }; diff --git a/include/Logger.h b/include/Logger.h index 509bc5f..941e556 100644 --- a/include/Logger.h +++ b/include/Logger.h @@ -18,6 +18,7 @@ #include #include #include +#include // Local #include "CuteLogger_global.h" @@ -224,7 +225,7 @@ class CUTELOGGERSHARED_EXPORT LoggerTimingHelper private: Logger* m_logger; - QTime m_time; + QElapsedTimer m_time; Logger::LogLevel m_logLevel; Logger::TimingMode m_timingMode; const char* m_file; diff --git a/src/AbstractStringAppender.cpp b/src/AbstractStringAppender.cpp index ce64aae..ea5883f 100644 --- a/src/AbstractStringAppender.cpp +++ b/src/AbstractStringAppender.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -155,12 +155,13 @@ QByteArray AbstractStringAppender::qCleanupFuncinfo(const char* name) } bool hasLambda = false; - QRegExp lambdaRegex("::"); - int lambdaIndex = lambdaRegex.indexIn(QString::fromLatin1(info)); + QRegularExpression lambdaRegex("::"); + QRegularExpressionMatch match = lambdaRegex.match(QString::fromLatin1(info)); + int lambdaIndex = match.capturedStart(); if (lambdaIndex != -1) { hasLambda = true; - info.remove(lambdaIndex, lambdaRegex.matchedLength()); + info.remove(lambdaIndex, match.capturedLength()); } // operator names with '(', ')', '<', '>' in it @@ -405,7 +406,7 @@ QString AbstractStringAppender::formattedString(const QDateTime& timeStamp, Logg // Filename without a path else if (command == QLatin1String("file")) - chunk = QString(QLatin1String(file)).section(QRegExp("[/\\\\]"), -1); + chunk = QString(QLatin1String(file)).section(QRegularExpression("[/\\\\]"), -1); // Source line number else if (command == QLatin1String("line")) diff --git a/src/FileAppender.cpp b/src/FileAppender.cpp index b9018b0..7e2b5b6 100644 --- a/src/FileAppender.cpp +++ b/src/FileAppender.cpp @@ -26,6 +26,7 @@ //! Constructs the new file appender assigned to file with the given name. FileAppender::FileAppender(const QString& fileName) + : m_flushOnWrite(false) { setFileName(fileName); } @@ -65,6 +66,37 @@ void FileAppender::setFileName(const QString& s) } +bool FileAppender::flushOnWrite() const +{ + return m_flushOnWrite; +} + + +//! Allows FileAppender to flush file immediately after writing a log record. +/** + * Default value is false. This could result in substantial app slowdown when writing massive amount of log records + * with FileAppender on a rather slow file system due to FileAppender blocking until the data would be phisically + * written. + * + * Leaving this as is may result in some log data not being written if the application crashes. + */ +void FileAppender::setFlushOnWrite(bool flush) +{ + m_flushOnWrite = flush; +} + + +//! Force-flush any remaining buffers to file system. Returns true if successful, otherwise returns false. +bool FileAppender::flush() +{ + QMutexLocker locker(&m_logFileMutex); + if (m_logFile.isOpen()) + return m_logFile.flush(); + else + return true; +} + + bool FileAppender::reopenFile() { closeFile(); @@ -104,7 +136,8 @@ void FileAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, { m_logStream << formattedString(timeStamp, logLevel, file, line, function, category, message); m_logStream.flush(); - m_logFile.flush(); + if (m_flushOnWrite) + m_logFile.flush(); } } diff --git a/src/Logger.cpp b/src/Logger.cpp index 16a18db..5499d03 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #if defined(Q_OS_ANDROID) # include @@ -600,8 +599,14 @@ Logger::~Logger() // Cleanup appenders QMutexLocker appendersLocker(&d->loggerMutex); +#if QT_VERSION >= 0x050e00 + QSet deleteList(d->appenders.begin(), d->appenders.end()); + auto cal = d->categoryAppenders.values(); + deleteList.unite(QSet(cal.begin(), cal.end())); +#else QSet deleteList(QSet::fromList(d->appenders)); deleteList.unite(QSet::fromList(d->categoryAppenders.values())); +#endif qDeleteAll(deleteList); appendersLocker.unlock(); @@ -1032,7 +1037,11 @@ void LoggerTimingHelper::start(const char* msg, ...) { va_list va; va_start(va, msg); +#if QT_VERSION >= 0x050500 + m_block = QString().vasprintf(msg, va); +#else m_block = QString().vsprintf(msg, va); +#endif va_end(va); m_time.start(); @@ -1062,7 +1071,7 @@ LoggerTimingHelper::~LoggerTimingHelper() else message = QString(QLatin1String("\"%1\" finished in ")).arg(m_block); - int elapsed = m_time.elapsed(); + qint64 elapsed = m_time.elapsed(); if (elapsed >= 10000 && m_timingMode == Logger::TimingAuto) message += QString(QLatin1String("%1 s.")).arg(elapsed / 1000); else diff --git a/src/RollingFileAppender.cpp b/src/RollingFileAppender.cpp index 267744f..bc64a6f 100644 --- a/src/RollingFileAppender.cpp +++ b/src/RollingFileAppender.cpp @@ -200,7 +200,11 @@ void RollingFileAppender::computeRollOverTime() break; default: Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant"); +#if QT_VERSION >= 0x050800 + m_rollOverTime = QDateTime::fromSecsSinceEpoch(0); +#else m_rollOverTime = QDateTime::fromTime_t(0); +#endif } m_rollOverSuffix = start.toString(m_datePatternString);