mirror of
https://github.com/YACReader/yacreader
synced 2025-06-04 01:28:55 -04:00
using QsLog for logging
This commit is contained in:
parent
9db62a6475
commit
308eadd117
248
QsLog/QsLog.cpp
Normal file
248
QsLog/QsLog.cpp
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
// Copyright (c) 2013, Razvan Petru
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
// * The name of the contributors may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "QsLog.h"
|
||||||
|
#include "QsLogDest.h"
|
||||||
|
#ifdef QS_LOG_SEPARATE_THREAD
|
||||||
|
#include <QThreadPool>
|
||||||
|
#include <QRunnable>
|
||||||
|
#endif
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace QsLogging
|
||||||
|
{
|
||||||
|
typedef QVector<DestinationPtr> DestinationList;
|
||||||
|
|
||||||
|
static const char TraceString[] = "TRACE";
|
||||||
|
static const char DebugString[] = "DEBUG";
|
||||||
|
static const char InfoString[] = "INFO ";
|
||||||
|
static const char WarnString[] = "WARN ";
|
||||||
|
static const char ErrorString[] = "ERROR";
|
||||||
|
static const char FatalString[] = "FATAL";
|
||||||
|
|
||||||
|
// not using Qt::ISODate because we need the milliseconds too
|
||||||
|
static const QString fmtDateTime("yyyy-MM-ddThh:mm:ss.zzz");
|
||||||
|
|
||||||
|
static Logger* sInstance = 0;
|
||||||
|
|
||||||
|
static const char* LevelToText(Level theLevel)
|
||||||
|
{
|
||||||
|
switch (theLevel) {
|
||||||
|
case TraceLevel:
|
||||||
|
return TraceString;
|
||||||
|
case DebugLevel:
|
||||||
|
return DebugString;
|
||||||
|
case InfoLevel:
|
||||||
|
return InfoString;
|
||||||
|
case WarnLevel:
|
||||||
|
return WarnString;
|
||||||
|
case ErrorLevel:
|
||||||
|
return ErrorString;
|
||||||
|
case FatalLevel:
|
||||||
|
return FatalString;
|
||||||
|
case OffLevel:
|
||||||
|
return "";
|
||||||
|
default: {
|
||||||
|
assert(!"bad log level");
|
||||||
|
return InfoString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef QS_LOG_SEPARATE_THREAD
|
||||||
|
class LogWriterRunnable : public QRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LogWriterRunnable(QString message, Level level);
|
||||||
|
virtual void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString mMessage;
|
||||||
|
Level mLevel;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class LoggerImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LoggerImpl();
|
||||||
|
|
||||||
|
#ifdef QS_LOG_SEPARATE_THREAD
|
||||||
|
QThreadPool threadPool;
|
||||||
|
#endif
|
||||||
|
QMutex logMutex;
|
||||||
|
Level level;
|
||||||
|
DestinationList destList;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef QS_LOG_SEPARATE_THREAD
|
||||||
|
LogWriterRunnable::LogWriterRunnable(QString message, Level level)
|
||||||
|
: QRunnable()
|
||||||
|
, mMessage(message)
|
||||||
|
, mLevel(level)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogWriterRunnable::run()
|
||||||
|
{
|
||||||
|
Logger::instance().write(mMessage, mLevel);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
LoggerImpl::LoggerImpl()
|
||||||
|
: level(InfoLevel)
|
||||||
|
{
|
||||||
|
// assume at least file + console
|
||||||
|
destList.reserve(2);
|
||||||
|
#ifdef QS_LOG_SEPARATE_THREAD
|
||||||
|
threadPool.setMaxThreadCount(1);
|
||||||
|
threadPool.setExpiryTimeout(-1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Logger::Logger()
|
||||||
|
: d(new LoggerImpl)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger& Logger::instance()
|
||||||
|
{
|
||||||
|
if (!sInstance)
|
||||||
|
sInstance = new Logger;
|
||||||
|
|
||||||
|
return *sInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::destroyInstance()
|
||||||
|
{
|
||||||
|
delete sInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tries to extract the level from a string log message. If available, conversionSucceeded will
|
||||||
|
// contain the conversion result.
|
||||||
|
Level Logger::levelFromLogMessage(const QString& logMessage, bool* conversionSucceeded)
|
||||||
|
{
|
||||||
|
if (conversionSucceeded)
|
||||||
|
*conversionSucceeded = true;
|
||||||
|
|
||||||
|
if (logMessage.startsWith(QLatin1String(TraceString)))
|
||||||
|
return TraceLevel;
|
||||||
|
if (logMessage.startsWith(QLatin1String(DebugString)))
|
||||||
|
return DebugLevel;
|
||||||
|
if (logMessage.startsWith(QLatin1String(InfoString)))
|
||||||
|
return InfoLevel;
|
||||||
|
if (logMessage.startsWith(QLatin1String(WarnString)))
|
||||||
|
return WarnLevel;
|
||||||
|
if (logMessage.startsWith(QLatin1String(ErrorString)))
|
||||||
|
return ErrorLevel;
|
||||||
|
if (logMessage.startsWith(QLatin1String(FatalString)))
|
||||||
|
return FatalLevel;
|
||||||
|
|
||||||
|
if (conversionSucceeded)
|
||||||
|
*conversionSucceeded = false;
|
||||||
|
return OffLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::~Logger()
|
||||||
|
{
|
||||||
|
#ifdef QS_LOG_SEPARATE_THREAD
|
||||||
|
d->threadPool.waitForDone();
|
||||||
|
#endif
|
||||||
|
delete d;
|
||||||
|
d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::addDestination(DestinationPtr destination)
|
||||||
|
{
|
||||||
|
assert(destination.data());
|
||||||
|
d->destList.push_back(destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::setLoggingLevel(Level newLevel)
|
||||||
|
{
|
||||||
|
d->level = newLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
Level Logger::loggingLevel() const
|
||||||
|
{
|
||||||
|
return d->level;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! creates the complete log message and passes it to the logger
|
||||||
|
void Logger::Helper::writeToLog()
|
||||||
|
{
|
||||||
|
const char* const levelName = LevelToText(level);
|
||||||
|
const QString completeMessage(QString("%1 %2 %3")
|
||||||
|
.arg(levelName)
|
||||||
|
.arg(QDateTime::currentDateTime().toString(fmtDateTime))
|
||||||
|
.arg(buffer)
|
||||||
|
);
|
||||||
|
|
||||||
|
Logger::instance().enqueueWrite(completeMessage, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::Helper::~Helper()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
writeToLog();
|
||||||
|
}
|
||||||
|
catch(std::exception&) {
|
||||||
|
// you shouldn't throw exceptions from a sink
|
||||||
|
assert(!"exception in logger helper destructor");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! directs the message to the task queue or writes it directly
|
||||||
|
void Logger::enqueueWrite(const QString& message, Level level)
|
||||||
|
{
|
||||||
|
#ifdef QS_LOG_SEPARATE_THREAD
|
||||||
|
LogWriterRunnable *r = new LogWriterRunnable(message, level);
|
||||||
|
d->threadPool.start(r);
|
||||||
|
#else
|
||||||
|
write(message, level);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Sends the message to all the destinations. The level for this message is passed in case
|
||||||
|
//! it's useful for processing in the destination.
|
||||||
|
void Logger::write(const QString& message, Level level)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&d->logMutex);
|
||||||
|
for (DestinationList::iterator it = d->destList.begin(),
|
||||||
|
endIt = d->destList.end();it != endIt;++it) {
|
||||||
|
(*it)->write(message, level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace
|
137
QsLog/QsLog.h
Normal file
137
QsLog/QsLog.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
// Copyright (c) 2013, Razvan Petru
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
// * The name of the contributors may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef QSLOG_H
|
||||||
|
#define QSLOG_H
|
||||||
|
|
||||||
|
#include "QsLogLevel.h"
|
||||||
|
#include "QsLogDest.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#define QS_LOG_VERSION "2.0b1"
|
||||||
|
|
||||||
|
namespace QsLogging
|
||||||
|
{
|
||||||
|
class Destination;
|
||||||
|
class LoggerImpl; // d pointer
|
||||||
|
|
||||||
|
class QSLOG_SHARED_OBJECT Logger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Logger& instance();
|
||||||
|
static void destroyInstance();
|
||||||
|
static Level levelFromLogMessage(const QString& logMessage, bool* conversionSucceeded = 0);
|
||||||
|
|
||||||
|
~Logger();
|
||||||
|
|
||||||
|
//! Adds a log message destination. Don't add null destinations.
|
||||||
|
void addDestination(DestinationPtr destination);
|
||||||
|
//! Logging at a level < 'newLevel' will be ignored
|
||||||
|
void setLoggingLevel(Level newLevel);
|
||||||
|
//! The default level is INFO
|
||||||
|
Level loggingLevel() const;
|
||||||
|
|
||||||
|
//! The helper forwards the streaming to QDebug and builds the final
|
||||||
|
//! log message.
|
||||||
|
class Helper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Helper(Level logLevel) :
|
||||||
|
level(logLevel),
|
||||||
|
qtDebug(&buffer) {}
|
||||||
|
~Helper();
|
||||||
|
QDebug& stream(){ return qtDebug; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void writeToLog();
|
||||||
|
|
||||||
|
Level level;
|
||||||
|
QString buffer;
|
||||||
|
QDebug qtDebug;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Logger();
|
||||||
|
Logger(const Logger&); // not available
|
||||||
|
Logger& operator=(const Logger&); // not available
|
||||||
|
|
||||||
|
void enqueueWrite(const QString& message, Level level);
|
||||||
|
void write(const QString& message, Level level);
|
||||||
|
|
||||||
|
LoggerImpl* d;
|
||||||
|
|
||||||
|
friend class LogWriterRunnable;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace
|
||||||
|
|
||||||
|
//! Logging macros: define QS_LOG_LINE_NUMBERS to get the file and line number
|
||||||
|
//! in the log output.
|
||||||
|
#ifndef QS_LOG_LINE_NUMBERS
|
||||||
|
#define QLOG_TRACE() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::TraceLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::TraceLevel).stream()
|
||||||
|
#define QLOG_DEBUG() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::DebugLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::DebugLevel).stream()
|
||||||
|
#define QLOG_INFO() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::InfoLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::InfoLevel).stream()
|
||||||
|
#define QLOG_WARN() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::WarnLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::WarnLevel).stream()
|
||||||
|
#define QLOG_ERROR() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::ErrorLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::ErrorLevel).stream()
|
||||||
|
#define QLOG_FATAL() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::FatalLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::FatalLevel).stream()
|
||||||
|
#else
|
||||||
|
#define QLOG_TRACE() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::TraceLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::TraceLevel).stream() << __FILE__ << '@' << __LINE__
|
||||||
|
#define QLOG_DEBUG() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::DebugLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::DebugLevel).stream() << __FILE__ << '@' << __LINE__
|
||||||
|
#define QLOG_INFO() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::InfoLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::InfoLevel).stream() << __FILE__ << '@' << __LINE__
|
||||||
|
#define QLOG_WARN() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::WarnLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::WarnLevel).stream() << __FILE__ << '@' << __LINE__
|
||||||
|
#define QLOG_ERROR() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::ErrorLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::ErrorLevel).stream() << __FILE__ << '@' << __LINE__
|
||||||
|
#define QLOG_FATAL() \
|
||||||
|
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::FatalLevel) {} \
|
||||||
|
else QsLogging::Logger::Helper(QsLogging::FatalLevel).stream() << __FILE__ << '@' << __LINE__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef QS_LOG_DISABLE
|
||||||
|
#include "QsLogDisableForThisFile.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // QSLOG_H
|
19
QsLog/QsLog.pri
Normal file
19
QsLog/QsLog.pri
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
#DEFINES += QS_LOG_LINE_NUMBERS # automatically writes the file and line for each log message
|
||||||
|
#DEFINES += QS_LOG_DISABLE # logging code is replaced with a no-op
|
||||||
|
DEFINES += QS_LOG_SEPARATE_THREAD # messages are queued and written from a separate thread
|
||||||
|
SOURCES += $$PWD/QsLogDest.cpp \
|
||||||
|
$$PWD/QsLog.cpp \
|
||||||
|
$$PWD/QsLogDestConsole.cpp \
|
||||||
|
$$PWD/QsLogDestFile.cpp
|
||||||
|
|
||||||
|
HEADERS += $$PWD/QSLogDest.h \
|
||||||
|
$$PWD/QsLog.h \
|
||||||
|
$$PWD/QsLogDestConsole.h \
|
||||||
|
$$PWD/QsLogLevel.h \
|
||||||
|
$$PWD/QsLogDestFile.h \
|
||||||
|
$$PWD/QsLogDisableForThisFile.h
|
||||||
|
|
||||||
|
OTHER_FILES += \
|
||||||
|
$$PWD/QsLogChanges.txt \
|
||||||
|
$$PWD/QsLogReadme.txt
|
55
QsLog/QsLogDest.cpp
Normal file
55
QsLog/QsLogDest.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (c) 2013, Razvan Petru
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
// * The name of the contributors may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "QsLogDest.h"
|
||||||
|
#include "QsLogDestConsole.h"
|
||||||
|
#include "QsLogDestFile.h"
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace QsLogging
|
||||||
|
{
|
||||||
|
|
||||||
|
//! destination factory
|
||||||
|
DestinationPtr DestinationFactory::MakeFileDestination(const QString& filePath,
|
||||||
|
LogRotationOption rotation, const MaxSizeBytes &sizeInBytesToRotateAfter,
|
||||||
|
const MaxOldLogCount &oldLogsToKeep)
|
||||||
|
{
|
||||||
|
if (EnableLogRotation == rotation) {
|
||||||
|
QScopedPointer<SizeRotationStrategy> logRotation(new SizeRotationStrategy);
|
||||||
|
logRotation->setMaximumSizeInBytes(sizeInBytesToRotateAfter.size);
|
||||||
|
logRotation->setBackupCount(oldLogsToKeep.count);
|
||||||
|
|
||||||
|
return DestinationPtr(new FileDestination(filePath, RotationStrategyPtr(logRotation.take())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return DestinationPtr(new FileDestination(filePath, RotationStrategyPtr(new NullRotationStrategy)));
|
||||||
|
}
|
||||||
|
|
||||||
|
DestinationPtr DestinationFactory::MakeDebugOutputDestination()
|
||||||
|
{
|
||||||
|
return DestinationPtr(new DebugOutputDestination);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace
|
89
QsLog/QsLogDest.h
Normal file
89
QsLog/QsLogDest.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright (c) 2013, Razvan Petru
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
// * The name of the contributors may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef QSLOGDEST_H
|
||||||
|
#define QSLOGDEST_H
|
||||||
|
|
||||||
|
#include "QsLogLevel.h"
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QtGlobal>
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
#ifdef QSLOG_IS_SHARED_LIBRARY
|
||||||
|
#define QSLOG_SHARED_OBJECT Q_DECL_EXPORT
|
||||||
|
#else
|
||||||
|
#define QSLOG_SHARED_OBJECT /*Q_DECL_IMPORT*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace QsLogging
|
||||||
|
{
|
||||||
|
|
||||||
|
class QSLOG_SHARED_OBJECT Destination
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Destination(){}
|
||||||
|
virtual void write(const QString& message, Level level) = 0;
|
||||||
|
virtual bool isValid() = 0; // returns whether the destination was created correctly
|
||||||
|
};
|
||||||
|
typedef QSharedPointer<Destination> DestinationPtr;
|
||||||
|
|
||||||
|
|
||||||
|
// a series of "named" paramaters, to make the file destination creation more readable
|
||||||
|
enum LogRotationOption
|
||||||
|
{
|
||||||
|
DisableLogRotation = 0,
|
||||||
|
EnableLogRotation = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QSLOG_SHARED_OBJECT MaxSizeBytes
|
||||||
|
{
|
||||||
|
MaxSizeBytes() : size(0) {}
|
||||||
|
MaxSizeBytes(qint64 size_) : size(size_) {}
|
||||||
|
qint64 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QSLOG_SHARED_OBJECT MaxOldLogCount
|
||||||
|
{
|
||||||
|
MaxOldLogCount() : count(0) {}
|
||||||
|
MaxOldLogCount(int count_) : count(count_) {}
|
||||||
|
int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//! Creates logging destinations/sinks. The caller shares ownership of the destinations with the logger.
|
||||||
|
//! After being added to a logger, the caller can discard the pointers.
|
||||||
|
class QSLOG_SHARED_OBJECT DestinationFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static DestinationPtr MakeFileDestination(const QString& filePath,
|
||||||
|
LogRotationOption rotation = DisableLogRotation,
|
||||||
|
const MaxSizeBytes &sizeInBytesToRotateAfter = MaxSizeBytes(),
|
||||||
|
const MaxOldLogCount &oldLogsToKeep = MaxOldLogCount());
|
||||||
|
static DestinationPtr MakeDebugOutputDestination();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace
|
||||||
|
|
||||||
|
#endif // QSLOGDEST_H
|
55
QsLog/QsLogDestConsole.cpp
Normal file
55
QsLog/QsLogDestConsole.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (c) 2013, Razvan Petru
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
// * The name of the contributors may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "QsLogDestConsole.h"
|
||||||
|
#include <QString>
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
void QsDebugOutput::output( const QString& message )
|
||||||
|
{
|
||||||
|
OutputDebugStringW(reinterpret_cast<const WCHAR*>(message.utf16()));
|
||||||
|
OutputDebugStringW(L"\n");
|
||||||
|
}
|
||||||
|
#elif defined(Q_OS_UNIX)
|
||||||
|
#include <cstdio>
|
||||||
|
void QsDebugOutput::output( const QString& message )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", qPrintable(message));
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void QsLogging::DebugOutputDestination::write(const QString& message, Level)
|
||||||
|
{
|
||||||
|
QsDebugOutput::output(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QsLogging::DebugOutputDestination::isValid()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
52
QsLog/QsLogDestConsole.h
Normal file
52
QsLog/QsLogDestConsole.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (c) 2013, Razvan Petru
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
// * The name of the contributors may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef QSLOGDESTCONSOLE_H
|
||||||
|
#define QSLOGDESTCONSOLE_H
|
||||||
|
|
||||||
|
#include "QsLogDest.h"
|
||||||
|
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
class QsDebugOutput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void output(const QString& a_message);
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace QsLogging
|
||||||
|
{
|
||||||
|
|
||||||
|
// debugger sink
|
||||||
|
class DebugOutputDestination : public Destination
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void write(const QString& message, Level level);
|
||||||
|
virtual bool isValid();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QSLOGDESTCONSOLE_H
|
155
QsLog/QsLogDestFile.cpp
Normal file
155
QsLog/QsLogDestFile.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
// Copyright (c) 2013, Razvan Petru
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
// * The name of the contributors may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "QsLogDestFile.h"
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
const int QsLogging::SizeRotationStrategy::MaxBackupCount = 10;
|
||||||
|
|
||||||
|
QsLogging::RotationStrategy::~RotationStrategy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QsLogging::SizeRotationStrategy::SizeRotationStrategy()
|
||||||
|
: mCurrentSizeInBytes(0)
|
||||||
|
, mMaxSizeInBytes(0)
|
||||||
|
, mBackupsCount(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QsLogging::SizeRotationStrategy::setInitialInfo(const QFile &file)
|
||||||
|
{
|
||||||
|
mFileName = file.fileName();
|
||||||
|
mCurrentSizeInBytes = file.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QsLogging::SizeRotationStrategy::includeMessageInCalculation(const QString &message)
|
||||||
|
{
|
||||||
|
mCurrentSizeInBytes += message.toUtf8().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QsLogging::SizeRotationStrategy::shouldRotate()
|
||||||
|
{
|
||||||
|
return mCurrentSizeInBytes > mMaxSizeInBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Algorithm assumes backups will be named filename.X, where 1 <= X <= mBackupsCount.
|
||||||
|
// All X's will be shifted up.
|
||||||
|
void QsLogging::SizeRotationStrategy::rotate()
|
||||||
|
{
|
||||||
|
if (!mBackupsCount) {
|
||||||
|
if (!QFile::remove(mFileName))
|
||||||
|
std::cerr << "QsLog: backup delete failed " << qPrintable(mFileName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. find the last existing backup than can be shifted up
|
||||||
|
const QString logNamePattern = mFileName + QString::fromUtf8(".%1");
|
||||||
|
int lastExistingBackupIndex = 0;
|
||||||
|
for (int i = 1;i <= mBackupsCount;++i) {
|
||||||
|
const QString backupFileName = logNamePattern.arg(i);
|
||||||
|
if (QFile::exists(backupFileName))
|
||||||
|
lastExistingBackupIndex = qMin(i, mBackupsCount - 1);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. shift up
|
||||||
|
for (int i = lastExistingBackupIndex;i >= 1;--i) {
|
||||||
|
const QString oldName = logNamePattern.arg(i);
|
||||||
|
const QString newName = logNamePattern.arg(i + 1);
|
||||||
|
QFile::remove(newName);
|
||||||
|
const bool renamed = QFile::rename(oldName, newName);
|
||||||
|
if (!renamed) {
|
||||||
|
std::cerr << "QsLog: could not rename backup " << qPrintable(oldName)
|
||||||
|
<< " to " << qPrintable(newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. rename current log file
|
||||||
|
const QString newName = logNamePattern.arg(1);
|
||||||
|
if (QFile::exists(newName))
|
||||||
|
QFile::remove(newName);
|
||||||
|
if (!QFile::rename(mFileName, newName)) {
|
||||||
|
std::cerr << "QsLog: could not rename log " << qPrintable(mFileName)
|
||||||
|
<< " to " << qPrintable(newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QIODevice::OpenMode QsLogging::SizeRotationStrategy::recommendedOpenModeFlag()
|
||||||
|
{
|
||||||
|
return QIODevice::Append;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QsLogging::SizeRotationStrategy::setMaximumSizeInBytes(qint64 size)
|
||||||
|
{
|
||||||
|
Q_ASSERT(size >= 0);
|
||||||
|
mMaxSizeInBytes = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QsLogging::SizeRotationStrategy::setBackupCount(int backups)
|
||||||
|
{
|
||||||
|
Q_ASSERT(backups >= 0);
|
||||||
|
mBackupsCount = qMin(backups, SizeRotationStrategy::MaxBackupCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QsLogging::FileDestination::FileDestination(const QString& filePath, RotationStrategyPtr rotationStrategy)
|
||||||
|
: mRotationStrategy(rotationStrategy)
|
||||||
|
{
|
||||||
|
mFile.setFileName(filePath);
|
||||||
|
if (!mFile.open(QFile::WriteOnly | QFile::Text | mRotationStrategy->recommendedOpenModeFlag()))
|
||||||
|
std::cerr << "QsLog: could not open log file " << qPrintable(filePath);
|
||||||
|
mOutputStream.setDevice(&mFile);
|
||||||
|
mOutputStream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
||||||
|
mRotationStrategy->setInitialInfo(mFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QsLogging::FileDestination::write(const QString& message, Level)
|
||||||
|
{
|
||||||
|
mRotationStrategy->includeMessageInCalculation(message);
|
||||||
|
if (mRotationStrategy->shouldRotate()) {
|
||||||
|
mOutputStream.setDevice(NULL);
|
||||||
|
mFile.close();
|
||||||
|
mRotationStrategy->rotate();
|
||||||
|
if (!mFile.open(QFile::WriteOnly | QFile::Text | mRotationStrategy->recommendedOpenModeFlag()))
|
||||||
|
std::cerr << "QsLog: could not reopen log file " << qPrintable(mFile.fileName());
|
||||||
|
mRotationStrategy->setInitialInfo(mFile);
|
||||||
|
mOutputStream.setDevice(&mFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
mOutputStream << message << endl;
|
||||||
|
mOutputStream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QsLogging::FileDestination::isValid()
|
||||||
|
{
|
||||||
|
return mFile.isOpen();
|
||||||
|
}
|
||||||
|
|
101
QsLog/QsLogDestFile.h
Normal file
101
QsLog/QsLogDestFile.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Copyright (c) 2013, Razvan Petru
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
// * The name of the contributors may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef QSLOGDESTFILE_H
|
||||||
|
#define QSLOGDESTFILE_H
|
||||||
|
|
||||||
|
#include "QsLogDest.h"
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
|
namespace QsLogging
|
||||||
|
{
|
||||||
|
class RotationStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~RotationStrategy();
|
||||||
|
|
||||||
|
virtual void setInitialInfo(const QFile &file) = 0;
|
||||||
|
virtual void includeMessageInCalculation(const QString &message) = 0;
|
||||||
|
virtual bool shouldRotate() = 0;
|
||||||
|
virtual void rotate() = 0;
|
||||||
|
virtual QIODevice::OpenMode recommendedOpenModeFlag() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Never rotates file, overwrites existing file.
|
||||||
|
class NullRotationStrategy : public RotationStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void setInitialInfo(const QFile &) {}
|
||||||
|
virtual void includeMessageInCalculation(const QString &) {}
|
||||||
|
virtual bool shouldRotate() { return false; }
|
||||||
|
virtual void rotate() {}
|
||||||
|
virtual QIODevice::OpenMode recommendedOpenModeFlag() { return QIODevice::Truncate; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rotates after a size is reached, keeps a number of <= 10 backups, appends to existing file.
|
||||||
|
class SizeRotationStrategy : public RotationStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SizeRotationStrategy();
|
||||||
|
static const int MaxBackupCount;
|
||||||
|
|
||||||
|
virtual void setInitialInfo(const QFile &file);
|
||||||
|
virtual void includeMessageInCalculation(const QString &message);
|
||||||
|
virtual bool shouldRotate();
|
||||||
|
virtual void rotate();
|
||||||
|
virtual QIODevice::OpenMode recommendedOpenModeFlag();
|
||||||
|
|
||||||
|
void setMaximumSizeInBytes(qint64 size);
|
||||||
|
void setBackupCount(int backups);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString mFileName;
|
||||||
|
qint64 mCurrentSizeInBytes;
|
||||||
|
qint64 mMaxSizeInBytes;
|
||||||
|
int mBackupsCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef QSharedPointer<RotationStrategy> RotationStrategyPtr;
|
||||||
|
|
||||||
|
// file message sink
|
||||||
|
class FileDestination : public Destination
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileDestination(const QString& filePath, RotationStrategyPtr rotationStrategy);
|
||||||
|
virtual void write(const QString& message, Level level);
|
||||||
|
virtual bool isValid();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QFile mFile;
|
||||||
|
QTextStream mOutputStream;
|
||||||
|
QSharedPointer<RotationStrategy> mRotationStrategy;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QSLOGDESTFILE_H
|
22
QsLog/QsLogDisableForThisFile.h
Normal file
22
QsLog/QsLogDisableForThisFile.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef QSLOGDISABLEFORTHISFILE_H
|
||||||
|
#define QSLOGDISABLEFORTHISFILE_H
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
// When included AFTER QsLog.h, this file will disable logging in that C++ file. When included
|
||||||
|
// before, it will lead to compiler warnings or errors about macro redefinitions.
|
||||||
|
|
||||||
|
#undef QLOG_TRACE
|
||||||
|
#undef QLOG_DEBUG
|
||||||
|
#undef QLOG_INFO
|
||||||
|
#undef QLOG_WARN
|
||||||
|
#undef QLOG_ERROR
|
||||||
|
#undef QLOG_FATAL
|
||||||
|
|
||||||
|
#define QLOG_TRACE() if (1) {} else qDebug()
|
||||||
|
#define QLOG_DEBUG() if (1) {} else qDebug()
|
||||||
|
#define QLOG_INFO() if (1) {} else qDebug()
|
||||||
|
#define QLOG_WARN() if (1) {} else qDebug()
|
||||||
|
#define QLOG_ERROR() if (1) {} else qDebug()
|
||||||
|
#define QLOG_FATAL() if (1) {} else qDebug()
|
||||||
|
|
||||||
|
#endif // QSLOGDISABLEFORTHISFILE_H
|
45
QsLog/QsLogLevel.h
Normal file
45
QsLog/QsLogLevel.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright (c) 2013, Razvan Petru
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
// * The name of the contributors may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef QSLOGLEVEL_H
|
||||||
|
#define QSLOGLEVEL_H
|
||||||
|
|
||||||
|
namespace QsLogging
|
||||||
|
{
|
||||||
|
|
||||||
|
enum Level
|
||||||
|
{
|
||||||
|
TraceLevel = 0,
|
||||||
|
DebugLevel,
|
||||||
|
InfoLevel,
|
||||||
|
WarnLevel,
|
||||||
|
ErrorLevel,
|
||||||
|
FatalLevel,
|
||||||
|
OffLevel
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QSLOGLEVEL_H
|
30
QsLog/QsLogSharedLibrary.pro
Normal file
30
QsLog/QsLogSharedLibrary.pro
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# This pro file will build QsLog as a shared library
|
||||||
|
include(QsLog.pri)
|
||||||
|
|
||||||
|
TARGET = QsLog
|
||||||
|
VERSION = "2.0.0"
|
||||||
|
QT -= gui
|
||||||
|
CONFIG -= console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
CONFIG += shared
|
||||||
|
TEMPLATE = lib
|
||||||
|
|
||||||
|
DESTDIR = $$PWD/build-QsLogShared
|
||||||
|
OBJECTS_DIR = $$DESTDIR/obj
|
||||||
|
|
||||||
|
unix:!macx {
|
||||||
|
# make install will install the shared object in the appropriate folders
|
||||||
|
headers.files = QsLog.h QsLogDest.h QsLogLevel.h
|
||||||
|
headers.path = /usr/include/$(QMAKE_TARGET)
|
||||||
|
|
||||||
|
other_files.files = *.txt
|
||||||
|
other_files.path = /usr/local/share/$(QMAKE_TARGET)
|
||||||
|
|
||||||
|
contains(QT_ARCH, x86_64) {
|
||||||
|
target.path = /usr/lib64
|
||||||
|
} else {
|
||||||
|
target.path = /usr/lib
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTALLS += headers target other_files
|
||||||
|
}
|
@ -125,6 +125,7 @@ include(./server/server.pri)
|
|||||||
include(../custom_widgets/custom_widgets_yacreaderlibrary.pri)
|
include(../custom_widgets/custom_widgets_yacreaderlibrary.pri)
|
||||||
include(../compressed_archive/wrapper.pri)
|
include(../compressed_archive/wrapper.pri)
|
||||||
include(./comic_vine/comic_vine.pri)
|
include(./comic_vine/comic_vine.pri)
|
||||||
|
include(../QsLog/QsLog.pri)
|
||||||
|
|
||||||
RESOURCES += images.qrc files.qrc
|
RESOURCES += images.qrc files.qrc
|
||||||
win32:RESOURCES += images_win.qrc
|
win32:RESOURCES += images_win.qrc
|
||||||
|
@ -4,99 +4,54 @@
|
|||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QTextStream>
|
|
||||||
#include <QtDebug>
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDateTime>
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#else
|
#else
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "yacreader_global.h"
|
#include "yacreader_global.h"
|
||||||
#include "startup.h"
|
#include "startup.h"
|
||||||
#include "yacreader_local_server.h"
|
#include "yacreader_local_server.h"
|
||||||
#include "comic_db.h"
|
#include "comic_db.h"
|
||||||
|
|
||||||
|
#include "QsLog.h"
|
||||||
|
#include "QsLogDest.h"
|
||||||
|
|
||||||
#define PICTUREFLOW_QT4 1
|
#define PICTUREFLOW_QT4 1
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
void yacreaderMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
|
||||||
{
|
|
||||||
|
|
||||||
QString txt;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case QtDebugMsg:
|
|
||||||
txt = QString("Debug: %1").arg(msg);
|
|
||||||
break;
|
|
||||||
case QtWarningMsg:
|
|
||||||
txt = QString("Warning: %1").arg(msg);
|
|
||||||
break;
|
|
||||||
case QtCriticalMsg:
|
|
||||||
txt = QString("Critical: %1").arg(msg);
|
|
||||||
break;
|
|
||||||
case QtFatalMsg:
|
|
||||||
txt = QString("Fatal: %1").arg(msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
|
|
||||||
|
|
||||||
QFile outFile(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)+"/yacreaderlibrary.log");
|
|
||||||
|
|
||||||
outFile.open(QIODevice::WriteOnly | QIODevice::Append);
|
|
||||||
QTextStream ts(&outFile);
|
|
||||||
ts << QDateTime::currentDateTime().toString() << " - " << txt << endl;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void yacreaderMessageHandler(QtMsgType type, const char * msg)
|
|
||||||
{
|
|
||||||
QString txt;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case QtDebugMsg:
|
|
||||||
txt = QString("Debug: %1").arg(msg);
|
|
||||||
break;
|
|
||||||
case QtWarningMsg:
|
|
||||||
txt = QString("Warning: %1").arg(msg);
|
|
||||||
break;
|
|
||||||
case QtCriticalMsg:
|
|
||||||
txt = QString("Critical: %1").arg(msg);
|
|
||||||
break;
|
|
||||||
case QtFatalMsg:
|
|
||||||
txt = QString("Fatal: %1").arg(msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDir().mkpath(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
|
|
||||||
|
|
||||||
QFile outFile(QDesktopServices::storageLocation(QDesktopServices::DataLocation)+"/yacreaderlibrary.log");
|
|
||||||
|
|
||||||
outFile.open(QIODevice::WriteOnly | QIODevice::Append);
|
|
||||||
QTextStream ts(&outFile);
|
|
||||||
ts << QDateTime::currentDateTime().toString() << " - " << txt << endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//interfaz al servidor
|
//interfaz al servidor
|
||||||
Startup * s;
|
Startup * s;
|
||||||
|
|
||||||
|
using namespace QsLogging;
|
||||||
|
|
||||||
int main( int argc, char ** argv )
|
int main( int argc, char ** argv )
|
||||||
{
|
{
|
||||||
QApplication app( argc, argv );
|
QApplication app( argc, argv );
|
||||||
|
|
||||||
|
app.setApplicationName("YACReaderLibrary");
|
||||||
|
app.setOrganizationName("YACReader");
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
qInstallMessageHandler(yacreaderMessageHandler);
|
QString destLog = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)+"/yacreaderlibrary.log";
|
||||||
|
QString destErr = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)+"/yacreaderlibrary.err";
|
||||||
|
QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
qInstallMsgHandler(yacreaderMessageHandler);
|
QString destLog = QDesktopServices::storageLocation(QDesktopServices::DataLocation)+"/yacreaderlibrary.log";
|
||||||
|
QString destErr = QDesktopServices::storageLocation(QDesktopServices::DataLocation)+"/yacreaderlibrary.err";
|
||||||
|
QDir().mkpath(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qDebug() << "YACReaderLibrary started" << endl;
|
Logger& logger = Logger::instance();
|
||||||
|
logger.setLoggingLevel(QsLogging::TraceLevel);
|
||||||
|
|
||||||
|
DestinationPtr fileDestination(DestinationFactory::MakeFileDestination(
|
||||||
|
destLog, EnableLogRotation, MaxSizeBytes(2048), MaxOldLogCount(2)));
|
||||||
|
DestinationPtr debugDestination(DestinationFactory::MakeDebugOutputDestination());
|
||||||
|
logger.addDestination(debugDestination);
|
||||||
|
logger.addDestination(fileDestination);
|
||||||
|
|
||||||
QTranslator translator;
|
QTranslator translator;
|
||||||
QString sufix = QLocale::system().name();
|
QString sufix = QLocale::system().name();
|
||||||
@ -122,9 +77,14 @@ int main( int argc, char ** argv )
|
|||||||
s->start();
|
s->start();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
QLOG_INFO() << "YACReaderLibrary attempting to start";
|
||||||
if(YACReaderLocalServer::isRunning()) //sólo se permite una instancia de YACReaderLibrary
|
if(YACReaderLocalServer::isRunning()) //sólo se permite una instancia de YACReaderLibrary
|
||||||
|
{
|
||||||
|
QLOG_WARN() << "another instance of YACReaderLibrary is running";
|
||||||
|
QsLogging::Logger::destroyInstance();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
QLOG_INFO() << "YACReaderLibrary starting";
|
||||||
|
|
||||||
YACReaderLocalServer * localServer = new YACReaderLocalServer();
|
YACReaderLocalServer * localServer = new YACReaderLocalServer();
|
||||||
|
|
||||||
@ -135,8 +95,6 @@ int main( int argc, char ** argv )
|
|||||||
//connections to localServer
|
//connections to localServer
|
||||||
|
|
||||||
mw->show();
|
mw->show();
|
||||||
/*mw->resize(800,480);
|
|
||||||
mw->showMaximized();*/
|
|
||||||
|
|
||||||
int ret = app.exec();
|
int ret = app.exec();
|
||||||
|
|
||||||
@ -144,7 +102,9 @@ int main( int argc, char ** argv )
|
|||||||
s->stop();
|
s->stop();
|
||||||
delete s;
|
delete s;
|
||||||
|
|
||||||
qDebug() << "YACReaderLibrary closed" << endl;
|
QLOG_INFO() << "YACReaderLibrary closed";
|
||||||
|
|
||||||
|
QsLogging::Logger::destroyInstance();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user