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

lib/bfLogging/src/filelogger.cpp

Go to the documentation of this file.
00001 
00006 #include "filelogger.h"
00007 #include <QTime>
00008 #include <QStringList>
00009 #include <QThread>
00010 #include <QtGlobal>
00011 #include <QFile>
00012 #include <QTimerEvent>
00013 #include <QDir>
00014 #include <QFileInfo>
00015 #include <stdio.h>
00016 
00017 void FileLogger::refreshSettings() {    
00018     mutex.lock();
00019     // Save old file name for later comparision with new settings
00020     QString oldFileName=fileName;
00021 
00022     // Load new config settings
00023     settings->sync();
00024     fileName=settings->value("fileName").toString();
00025     // Convert relative fileName to absolute, based on the directory of the config file.
00026 #ifdef Q_OS_WIN32
00027     if (QDir::isRelativePath(fileName) && settings->format()!=QSettings::NativeFormat)
00028 #else
00029     if (QDir::isRelativePath(fileName))
00030 #endif
00031     {
00032         QFileInfo configFile(settings->fileName());
00033         fileName=QFileInfo(configFile.absolutePath(),fileName).absoluteFilePath();
00034     }
00035     maxSize=settings->value("maxSize",0).toLongLong();
00036     maxBackups=settings->value("maxBackups",0).toInt();
00037     msgFormat=settings->value("msgFormat","{timestamp} {type} {msg}").toString();
00038     timestampFormat=settings->value("timestampFormat","{yyyy-MM-dd hh:mm:ss.zzz}").toString();
00039     minLevel=static_cast<QtMsgType>(settings->value("minLevel",0).toInt());
00040     bufferSize=settings->value("bufferSize",0).toInt();
00041     disabled=settings->value("disabled",false).toBool();
00042 
00043     // Create new file if the filename has been changed
00044     if (oldFileName!=fileName) {
00045         fprintf(stderr,"Logging to %s\n",qPrintable(fileName));
00046         close();
00047         open();
00048     }
00049     mutex.unlock();
00050 }
00051 
00052 
00053 FileLogger::FileLogger(QSettings* settings, const int refreshInterval, QObject* parent)
00054     : Logger(parent)
00055 {
00056     Q_ASSERT(settings!=0);
00057     Q_ASSERT(refreshInterval>=0);
00058     this->settings=settings;
00059     file=0;
00060     if (refreshInterval>0)
00061         refreshTimer.start(refreshInterval,this);
00062     flushTimer.start(1000,this);
00063     refreshSettings();
00064 }
00065 
00066 
00067 FileLogger::~FileLogger() {
00068     close();
00069 }
00070 
00071 
00072 void FileLogger::write(const LogMessage* logMessage) {
00073     // Write to the file
00074     if (!disabled) {
00075         // Try to write to the file
00076         if (file) {
00077 
00078             // Write the message
00079             file->write(qPrintable(logMessage->toString(msgFormat,timestampFormat)));
00080 
00081             // Flush error messages immediately, to ensure that no important message
00082             // gets lost when the program terinates abnormally.
00083             if (logMessage->getType()>=QtCriticalMsg) {
00084                 file->flush();
00085             }
00086 
00087             // Check for success
00088             if (file->error()) {
00089                 close();
00090                 qWarning("Cannot write to log file %s: %s",qPrintable(fileName),qPrintable(file->errorString()));
00091             }
00092 
00093         }
00094 
00095         // Fall-back to the super class method, if writing failed
00096         if (!file) {
00097             Logger::write(logMessage);
00098         }
00099     }
00100 
00101 }
00102 
00103 void FileLogger::open() {
00104     if (fileName.isEmpty()) {
00105         qWarning("Name of logFile is empty");
00106     }
00107     else {
00108         file=new QFile(fileName);
00109         if (!file->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
00110             qWarning("Cannot open log file %s: %s",qPrintable(fileName),qPrintable(file->errorString()));
00111             file=0;
00112         }
00113     }
00114 }
00115 
00116 
00117 void FileLogger::close() {
00118     if (file) {
00119         file->close();
00120         delete file;
00121         file=0;
00122     }
00123 }
00124 
00125 void FileLogger::rotate() {
00126     // count current number of existing backup files
00127     int count=0;
00128     forever {
00129         QFile bakFile(QString("%1.%2").arg(fileName).arg(count+1));
00130         if (bakFile.exists()) {
00131             ++count;
00132         }
00133         else {
00134             break;
00135         }
00136     }
00137 
00138     // Remove all old backup files that exceed the maximum number
00139     while (maxBackups>0 && count>=maxBackups) {
00140         QFile::remove(QString("%1.%2").arg(fileName).arg(count));
00141         --count;
00142     }
00143 
00144     // Rotate backup files
00145     for (int i=count; i>0; --i) {
00146         QFile::rename(QString("%1.%2").arg(fileName).arg(i),QString("%1.%2").arg(fileName).arg(i+1));
00147     }
00148 
00149     // Backup the current logfile
00150     QFile::rename(fileName,fileName+".1");
00151 }
00152 
00153 
00154 void FileLogger::timerEvent(QTimerEvent* event) {
00155     if (!event) {
00156         return;
00157     }
00158     else if (event->timerId()==refreshTimer.timerId()) {
00159         refreshSettings();
00160     }
00161     else if (event->timerId()==flushTimer.timerId() && file) {
00162         mutex.lock();
00163 
00164         // Flush the I/O buffer
00165         file->flush();
00166 
00167         // Rotate the file if it is too large
00168         if (maxSize>0 && file->size()>=maxSize) {
00169             close();
00170             rotate();
00171             open();
00172         }
00173 
00174         mutex.unlock();
00175     }
00176 }

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