142 lines
3.7 KiB
C++
142 lines
3.7 KiB
C++
// Copyright (c) 2010, 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"
|
|
#include <QMutex>
|
|
#include <QList>
|
|
#include <QDateTime>
|
|
#include <QtGlobal>
|
|
#include <cassert>
|
|
#include <cstdlib>
|
|
#include <stdexcept>
|
|
|
|
namespace QsLogging
|
|
{
|
|
typedef QList<Destination *> DestinationList;
|
|
|
|
static const char *LevelStrings[] = {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
|
|
"UNKNOWN"};
|
|
|
|
// not using Qt::ISODate because we need the milliseconds too
|
|
static const QString fmtDateTime("hhhh:mm:ss.zzz");
|
|
|
|
static const char *LevelToText(Level theLevel)
|
|
{
|
|
if (theLevel > FatalLevel)
|
|
{
|
|
assert(!"bad log level");
|
|
return LevelStrings[UnknownLevel];
|
|
}
|
|
return LevelStrings[theLevel];
|
|
}
|
|
|
|
class LoggerImpl
|
|
{
|
|
public:
|
|
LoggerImpl() : level(InfoLevel), start_time(QDateTime::currentDateTime())
|
|
{
|
|
}
|
|
QMutex logMutex;
|
|
Level level;
|
|
DestinationList destList;
|
|
QDateTime start_time;
|
|
};
|
|
|
|
Logger::Logger() : d(new LoggerImpl)
|
|
{
|
|
}
|
|
|
|
Logger::~Logger()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
void Logger::addDestination(Destination *destination)
|
|
{
|
|
assert(destination);
|
|
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\t%2\t%3")
|
|
.arg(QDateTime::currentDateTime().toString(fmtDateTime))
|
|
.arg(levelName, 5)
|
|
.arg(buffer));
|
|
|
|
Logger &logger = Logger::instance();
|
|
QMutexLocker lock(&logger.d->logMutex);
|
|
logger.write(completeMessage);
|
|
}
|
|
|
|
Logger::Helper::Helper(Level logLevel) : level(logLevel), qtDebug(&buffer)
|
|
{
|
|
}
|
|
|
|
Logger::Helper::~Helper()
|
|
{
|
|
try
|
|
{
|
|
writeToLog();
|
|
}
|
|
catch (std::exception &e)
|
|
{
|
|
// you shouldn't throw exceptions from a sink
|
|
Q_UNUSED(e);
|
|
assert(!"exception in logger helper destructor");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
//! sends the message to all the destinations
|
|
void Logger::write(const QString &message)
|
|
{
|
|
for (DestinationList::iterator it = d->destList.begin(), endIt = d->destList.end();
|
|
it != endIt; ++it)
|
|
{
|
|
if (!(*it))
|
|
{
|
|
assert(!"null log destination");
|
|
continue;
|
|
}
|
|
(*it)->write(message);
|
|
}
|
|
}
|
|
|
|
} // end namespace
|