diff options
Diffstat (limited to 'logger/QsLog.cpp')
-rw-r--r-- | logger/QsLog.cpp | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/logger/QsLog.cpp b/logger/QsLog.cpp new file mode 100644 index 00000000..8cf68a53 --- /dev/null +++ b/logger/QsLog.cpp @@ -0,0 +1,137 @@ +// 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) + { + } + QMutex logMutex; + Level level; + DestinationList destList; +}; + +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").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 |