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

Generated on 31 Mar 2010 for Vidalia by  doxygen 1.6.1