log.h

Go to the documentation of this file.
00001 /****************************************************************
00002  *  Vidalia is distributed under the following license:
00003  *
00004  *  Copyright (C) 2007,  Matt Edman, Justin Hipple
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; either version 2
00009  *  of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00019  *  Boston, MA  02110-1301, USA.
00020  ****************************************************************/
00021 
00022 /** 
00023  * \file log.h
00024  * \version $Id: log.h 1648 2007-02-24 18:32:28Z edmanm $
00025  * \brief Debug message logging
00026  */
00027 
00028 #ifndef _LOG_H
00029 #define _LOG_H
00030 
00031 #include <QObject>
00032 #include <QFile>
00033 #include <QStringList>
00034 #include <QIODevice>
00035 #include <QHostAddress>
00036 
00037 
00038 /** The Log class is similar to the QDebug class provided with Qt, but with
00039  * finer-grained logging levels, slightly different output (for example, not
00040  * everything is wrapped in double quotes), supports using .arg(), and can 
00041  * still be used even if Qt was compiled with QT_NO_DEBUG_STREAM. */
00042 class Log
00043 {
00044 public:
00045   /** Logging severity levels. */
00046   enum LogLevel {
00047     Debug = 0,  /**< Verbose debugging output. */
00048     Info,       /**< Primarily program flow output. */
00049     Notice,     /**< Non-failure (but important) events. */
00050     Warn,       /**< Recoverable failure conditions. */
00051     Error,      /**< Critical, non-recoverable errors. */
00052     Off,        /**< No logging output. */
00053     Unknown     /**< Unknown/invalid log level. */
00054   };
00055   class LogMessage;
00056   
00057   /** Default constructor. */
00058   Log();
00059   /** Destructor. */
00060   ~Log();
00061 
00062   /** Opens a file on disk (or stdout or stderr) to which log messages will be
00063    * written. */
00064   bool open(FILE *file);
00065   /** Opens a file on disk to which log messages will be written. */
00066   bool open(QString file);
00067   /** Closes the log file. */ 
00068   void close();
00069   /** Returns true if the log file is open and ready for writing. */
00070   bool isOpen() { return _logFile.isOpen() && _logFile.isWritable(); }
00071   /** Returns a string description of the last file error encountered. */
00072   QString errorString() { return _logFile.errorString(); }
00073   
00074   /** Sets the current log level to <b>level</b>. */
00075   void setLogLevel(LogLevel level);
00076   /** Returns a list of strings representing valid log levels. */
00077   static QStringList logLevels();
00078   /** Returns a string description of the given LogLevel <b>level</b>. */
00079   static inline QString logLevelToString(LogLevel level);
00080   /** Returns a LogLevel for the level given by <b>str</b>. */
00081   static LogLevel stringToLogLevel(QString str);
00082   
00083   /** Creates a log message with severity <b>level</b> and initial message
00084    * contents <b>message</b>. The log message can be appended to until the
00085    * returned LogMessage's destructor is called, at which point the complete
00086    * message is written to the log file. */
00087   LogMessage log(LogLevel level, QString message);
00088   /** Creates a log message with severity <b>level</b>. The log message can be
00089    * appended to until the returned LogMessage's destructor is called, at
00090    * which point the complete message is written to the log file. */
00091   inline LogMessage log(LogLevel level);
00092   
00093 private:
00094   LogLevel _logLevel; /**< Minimum log severity level. */
00095   QFile _logFile;     /**< Log output destination. */
00096 };
00097 
00098 /** This internal class represents a single message that is to be written to 
00099  * the log destination. The message is buffered until it is written to the
00100  * log in this class's destructor. */
00101 class Log::LogMessage
00102 {
00103 public:
00104   struct Stream {
00105     Stream(Log::LogLevel t, QIODevice *o) 
00106       : type(t), out(o), ref(1) {}
00107     Log::LogLevel type;
00108     QIODevice *out;
00109     int ref;
00110     QString buf;
00111   } *stream;
00112  
00113   inline LogMessage(Log::LogLevel t, QIODevice *o)
00114     : stream(new Stream(t,o)) {}
00115   inline LogMessage(const LogMessage &o) 
00116     : stream(o.stream) { ++stream->ref; }
00117   inline QString toString() const;
00118   ~LogMessage();
00119  
00120   /* Support both the << and .arg() methods */
00121   inline LogMessage &operator<<(const QString &t) 
00122     { stream->buf += t; return *this; }
00123   inline LogMessage arg(const QString &a)
00124     { stream->buf = stream->buf.arg(a); return *this; }
00125   inline LogMessage &operator<<(const QHostAddress &a)
00126     { stream->buf += a.toString(); return *this; }
00127   inline LogMessage arg(const QHostAddress &a)
00128     { stream->buf = stream->buf.arg(a.toString()); return *this; }
00129   inline LogMessage &operator<<(short a)
00130     { stream->buf += QString::number(a); return *this; }
00131   inline LogMessage arg(short a)
00132     { stream->buf = stream->buf.arg(a); return *this; }
00133   inline LogMessage &operator<<(ushort a)
00134     { stream->buf += QString::number(a); return *this; }
00135   inline LogMessage arg(ushort a)
00136     { stream->buf = stream->buf.arg(a); return *this; }
00137   inline LogMessage &operator<<(int a)
00138     { stream->buf += QString::number(a); return *this; }
00139   inline LogMessage arg(int a)
00140     { stream->buf = stream->buf.arg(a); return *this; }
00141   inline LogMessage &operator<<(uint a)
00142     { stream->buf += QString::number(a); return *this; }
00143   inline LogMessage arg(uint a)
00144     { stream->buf = stream->buf.arg(a); return *this; }
00145   inline LogMessage &operator<<(long a)
00146     { stream->buf += QString::number(a); return *this; }
00147   inline LogMessage arg(long a)
00148     { stream->buf = stream->buf.arg(a); return *this; }
00149   inline LogMessage &operator<<(ulong a)
00150     { stream->buf += QString::number(a); return *this; }
00151   inline LogMessage arg(ulong a)
00152     { stream->buf = stream->buf.arg(a); return *this; }
00153   inline LogMessage &operator<<(qlonglong a)
00154     { stream->buf += QString::number(a); return *this; }
00155   inline LogMessage arg(qlonglong a)
00156     { stream->buf = stream->buf.arg(a); return *this; }
00157   inline LogMessage &operator<<(qulonglong a)
00158     { stream->buf += QString::number(a); return *this; }
00159   inline LogMessage arg(qulonglong a)
00160     { stream->buf = stream->buf.arg(a); return *this; }
00161 };
00162 
00163 #endif
00164 

Generated on Wed Sep 5 15:49:27 2007 for Vidalia by  doxygen 1.5.3