Vidalia 0.2.12

Log.h

Go to the documentation of this file.
00001 /*
00002 **  This file is part of Vidalia, and is subject to the license terms in the
00003 **  LICENSE file, found in the top level directory of this distribution. If you
00004 **  did not receive the LICENSE file with this file, you may obtain it from the
00005 **  Vidalia source package distributed by the Vidalia Project at
00006 **  http://www.vidalia-project.net/. No part of Vidalia, including this file,
00007 **  may be copied, modified, propagated, or distributed except according to the
00008 **  terms described in the LICENSE file.
00009 */
00010 
00011 /*
00012 ** \file Log.h
00013 ** \brief Debug message logging
00014 */
00015 
00016 #ifndef _LOG_H
00017 #define _LOG_H
00018 
00019 #include <QObject>
00020 #include <QFile>
00021 #include <QStringList>
00022 #include <QIODevice>
00023 #include <QHostAddress>
00024 
00025 
00026 /** The Log class is similar to the QDebug class provided with Qt, but with
00027  * finer-grained logging levels, slightly different output (for example, not
00028  * everything is wrapped in double quotes), supports using .arg(), and can 
00029  * still be used even if Qt was compiled with QT_NO_DEBUG_STREAM. */
00030 class Log
00031 {
00032 public:
00033   /** Logging severity levels. */
00034   enum LogLevel {
00035     Debug = 0,  /**< Verbose debugging output. */
00036     Info,       /**< Primarily program flow output. */
00037     Notice,     /**< Non-failure (but important) events. */
00038     Warn,       /**< Recoverable failure conditions. */
00039     Error,      /**< Critical, non-recoverable errors. */
00040     Off,        /**< No logging output. */
00041     Unknown     /**< Unknown/invalid log level. */
00042   };
00043   class LogMessage;
00044   
00045   /** Default constructor. */
00046   Log();
00047   /** Destructor. */
00048   ~Log();
00049 
00050   /** Opens a file on disk (or stdout or stderr) to which log messages will be
00051    * written. */
00052   bool open(FILE *file);
00053   /** Opens a file on disk to which log messages will be written. */
00054   bool open(QString file);
00055   /** Closes the log file. */ 
00056   void close();
00057   /** Returns true if the log file is open and ready for writing. */
00058   bool isOpen() { return _logFile.isOpen() && _logFile.isWritable(); }
00059   /** Returns a string description of the last file error encountered. */
00060   QString errorString() { return _logFile.errorString(); }
00061   
00062   /** Sets the current log level to <b>level</b>. */
00063   void setLogLevel(LogLevel level);
00064   /** Returns a list of strings representing valid log levels. */
00065   static QStringList logLevels();
00066   /** Returns a string description of the given LogLevel <b>level</b>. */
00067   static inline QString logLevelToString(LogLevel level);
00068   /** Returns a LogLevel for the level given by <b>str</b>. */
00069   static LogLevel stringToLogLevel(QString str);
00070   
00071   /** Creates a log message with severity <b>level</b> and initial message
00072    * contents <b>message</b>. The log message can be appended to until the
00073    * returned LogMessage's destructor is called, at which point the complete
00074    * message is written to the log file. */
00075   LogMessage log(LogLevel level, QString message);
00076   /** Creates a log message with severity <b>level</b>. The log message can be
00077    * appended to until the returned LogMessage's destructor is called, at
00078    * which point the complete message is written to the log file. */
00079   inline LogMessage log(LogLevel level);
00080   
00081 private:
00082   LogLevel _logLevel; /**< Minimum log severity level. */
00083   QFile _logFile;     /**< Log output destination. */
00084 };
00085 
00086 /** This internal class represents a single message that is to be written to 
00087  * the log destination. The message is buffered until it is written to the
00088  * log in this class's destructor. */
00089 class Log::LogMessage
00090 {
00091 public:
00092   struct Stream {
00093     Stream(Log::LogLevel t, QIODevice *o) 
00094       : type(t), out(o), ref(1) {}
00095     Log::LogLevel type;
00096     QIODevice *out;
00097     int ref;
00098     QString buf;
00099   } *stream;
00100  
00101   inline LogMessage(Log::LogLevel t, QIODevice *o)
00102     : stream(new Stream(t,o)) {}
00103   inline LogMessage(const LogMessage &o) 
00104     : stream(o.stream) { ++stream->ref; }
00105   inline QString toString() const;
00106   ~LogMessage();
00107  
00108   /* Support both the << and .arg() methods */
00109   inline LogMessage &operator<<(const QString &t) 
00110     { stream->buf += t; return *this; }
00111   inline LogMessage arg(const QString &a)
00112     { stream->buf = stream->buf.arg(a); return *this; }
00113   inline LogMessage &operator<<(const QStringList &a)
00114     { stream->buf += a.join(","); return *this; }
00115   inline LogMessage arg(const QStringList &a)
00116     { stream->buf = stream->buf.arg(a.join(",")); return *this; }
00117   inline LogMessage &operator<<(const QHostAddress &a)
00118     { stream->buf += a.toString(); return *this; }
00119   inline LogMessage arg(const QHostAddress &a)
00120     { stream->buf = stream->buf.arg(a.toString()); return *this; }
00121   inline LogMessage &operator<<(short a)
00122     { stream->buf += QString::number(a); return *this; }
00123   inline LogMessage arg(short a)
00124     { stream->buf = stream->buf.arg(a); return *this; }
00125   inline LogMessage &operator<<(ushort a)
00126     { stream->buf += QString::number(a); return *this; }
00127   inline LogMessage arg(ushort a)
00128     { stream->buf = stream->buf.arg(a); return *this; }
00129   inline LogMessage &operator<<(int a)
00130     { stream->buf += QString::number(a); return *this; }
00131   inline LogMessage arg(int a)
00132     { stream->buf = stream->buf.arg(a); return *this; }
00133   inline LogMessage &operator<<(uint a)
00134     { stream->buf += QString::number(a); return *this; }
00135   inline LogMessage arg(uint a)
00136     { stream->buf = stream->buf.arg(a); return *this; }
00137   inline LogMessage &operator<<(long a)
00138     { stream->buf += QString::number(a); return *this; }
00139   inline LogMessage arg(long a)
00140     { stream->buf = stream->buf.arg(a); return *this; }
00141   inline LogMessage &operator<<(ulong a)
00142     { stream->buf += QString::number(a); return *this; }
00143   inline LogMessage arg(ulong a)
00144     { stream->buf = stream->buf.arg(a); return *this; }
00145   inline LogMessage &operator<<(qlonglong a)
00146     { stream->buf += QString::number(a); return *this; }
00147   inline LogMessage arg(qlonglong a)
00148     { stream->buf = stream->buf.arg(a); return *this; }
00149   inline LogMessage &operator<<(qulonglong a)
00150     { stream->buf += QString::number(a); return *this; }
00151   inline LogMessage arg(qulonglong a)
00152     { stream->buf = stream->buf.arg(a); return *this; }
00153 };
00154 
00155 #endif
00156