pollymc/logger/QsLog.cpp

160 lines
3.9 KiB
C++
Raw Normal View History

2013-10-06 04:43:40 +05:30
// 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"};
2013-10-06 04:43:40 +05:30
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)
2013-10-06 04:43:40 +05:30
{
}
QMutex logMutex;
Level level;
DestinationList destList;
QDateTime startTime;
2013-10-06 04:43:40 +05:30
};
Logger::Logger() : d(new LoggerImpl)
{
d->startTime = QDateTime::currentDateTime();
2013-10-06 04:43:40 +05:30
}
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;
}
QDateTime Logger::timeOfStart() const
{
return d->startTime;
}
qint64 Logger::timeSinceStart() const
{
return d->startTime.msecsTo(QDateTime::currentDateTime());
}
2013-10-06 04:43:40 +05:30
//! creates the complete log message and passes it to the logger
void Logger::Helper::writeToLog()
{
const char *const levelName = LevelToText(level);
Logger &logger = Logger::instance();
qint64 msecstotal = logger.timeSinceStart();
qint64 seconds = msecstotal / 1000;
qint64 msecs = msecstotal % 1000;
QString foo;
char buf[1024];
::snprintf(buf, 1024, "%5lld.%03lld", seconds, msecs);
const QString completeMessage(QString("%1\t%2\t%3").arg(buf).arg(levelName, 5).arg(buffer));
2013-10-06 04:43:40 +05:30
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);
}
}
void Logger::removeDestination(Destination* destination)
{
d->destList.removeAll(destination);
}
2013-10-06 04:43:40 +05:30
} // end namespace