• Main Page
  • Classes
  • Files
  • File List
  • File Members

lib/bfLogging/src/logger.cpp

Go to the documentation of this file.
00001 
00006 #include "logger.h"
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <QMutex>
00010 #include <QDateTime>
00011 #include <QThread>
00012 
00013 Logger* Logger::defaultLogger=0;
00014 
00015 
00016 QThreadStorage<QHash<QString,QString>*> Logger::logVars;
00017 
00018 
00019 QThreadStorage<QList<LogMessage*>*> Logger::buffers;
00020 
00021 
00022 QMutex Logger::mutex;
00023 
00024 
00025 Logger::Logger(QObject* parent)
00026     : QObject(parent),
00027     msgFormat("{timestamp} {type} {msg}"),
00028     timestampFormat("dd.MM.yyyy hh:mm:ss.zzz"),
00029     minLevel(QtDebugMsg),
00030     bufferSize(0)
00031     {}
00032 
00033 
00034 Logger::Logger(const QString msgFormat, const QString timestampFormat, const QtMsgType minLevel, const int bufferSize, QObject* parent)
00035     :QObject(parent) {
00036     this->msgFormat=msgFormat;
00037     this->timestampFormat=timestampFormat;
00038     this->minLevel=minLevel;
00039     this->bufferSize=bufferSize;
00040 }
00041 
00042 
00043 void Logger::msgHandler(const QtMsgType type, const char* message) {
00044     static QMutex recursiveMutex(QMutex::Recursive);
00045     static QMutex nonRecursiveMutex(QMutex::NonRecursive);
00046 
00047     // Prevent multiple threads from calling this method simultaneoulsy.
00048     // But allow recursive calls, which is required to prevent a deadlock
00049     // if the logger itself produces an error message.
00050     recursiveMutex.lock();
00051 
00052     // Fall back to stderr when this method has been called recursively.
00053     if (defaultLogger && nonRecursiveMutex.tryLock()) {
00054         defaultLogger->log(type,message);
00055         nonRecursiveMutex.unlock();
00056     }
00057     else {
00058         fputs(message,stderr);
00059         fflush(stderr);
00060     }
00061 
00062     // Abort the program after logging a fatal message
00063     if (type>=QtFatalMsg) {
00064         abort();
00065     }
00066 
00067     recursiveMutex.unlock();
00068 }
00069 
00070 
00071 
00072 
00073 Logger::~Logger() {
00074     if (defaultLogger==this) {
00075         qInstallMsgHandler(0);
00076         defaultLogger=0;
00077     }
00078 }
00079 
00080 
00081 void Logger::write(const LogMessage* logMessage) {
00082     fputs(qPrintable(logMessage->toString(msgFormat,timestampFormat)),stderr);
00083     fflush(stderr);
00084 }
00085 
00086 
00087 void Logger::installMsgHandler() {
00088     defaultLogger=this;
00089     qInstallMsgHandler(msgHandler);
00090 }
00091 
00092 
00093 void Logger::set(const QString& name, const QString& value) {
00094     mutex.lock();
00095     if (!logVars.hasLocalData()) {
00096         logVars.setLocalData(new QHash<QString,QString>);
00097     }
00098     logVars.localData()->insert(name,value);
00099     mutex.unlock();
00100 }
00101 
00102 
00103 void Logger::clear(const bool buffer, const bool variables) {
00104     mutex.lock();
00105     if (buffer && buffers.hasLocalData()) {
00106         QList<LogMessage*>* buffer=buffers.localData();
00107         while (buffer && !buffer->isEmpty()) {
00108             LogMessage* logMessage=buffer->takeLast();
00109             delete logMessage;
00110         }
00111     }
00112     if (variables && logVars.hasLocalData()) {
00113         logVars.localData()->clear();
00114     }
00115     mutex.unlock();
00116 }
00117 
00118 
00119 void Logger::log(const QtMsgType type, const QString& message) {
00120     mutex.lock();
00121 
00122     // If the buffer is enabled, write the message into it
00123     if (bufferSize>0) {
00124         // Create new thread local buffer, if necessary
00125         if (!buffers.hasLocalData()) {
00126             buffers.setLocalData(new QList<LogMessage*>());
00127         }
00128         QList<LogMessage*>* buffer=buffers.localData();
00129         // Append the decorated log message
00130         LogMessage* logMessage=new LogMessage(type,message,logVars.localData());
00131         buffer->append(logMessage);
00132         // Delete oldest message if the buffer became too large
00133         if (buffer->size()>bufferSize) {
00134             delete buffer->takeFirst();
00135         }
00136         // If the type of the message is high enough, print the whole buffer
00137         if (type>=minLevel) {
00138             while (!buffer->isEmpty()) {
00139                 LogMessage* logMessage=buffer->takeFirst();
00140                 write(logMessage);
00141                 delete logMessage;
00142             }
00143         }
00144     }
00145 
00146     // Buffer is disabled, print the message if the type is high enough
00147     else {
00148         if (type>=minLevel) {
00149             LogMessage logMessage(type,message,logVars.localData());
00150             write(&logMessage);
00151         }
00152     }
00153     mutex.unlock();
00154 }

Generated on Mon Dec 26 2011 12:09:22 for QtWebApp by  doxygen 1.7.1