Vidalia
0.2.17
|
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.torproject.org/projects/vidalia.html. No part of Vidalia, 00007 ** including this file, may be copied, modified, propagated, or distributed 00008 ** except according to the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file Log.cpp 00013 ** \brief Debug message logging 00014 */ 00015 00016 #include "Log.h" 00017 00018 #include <QDateTime> 00019 #include <QTextStream> 00020 00021 /** Open log files for appending as write-only text. */ 00022 #define LOGFILE_MODE \ 00023 (QIODevice::WriteOnly|QIODevice::Append|QIODevice::Text) 00024 /** Format for log message timestamps. */ 00025 #define TIMESTAMP_FMT "MMM dd HH:mm:ss.zzz" 00026 00027 00028 /** Default constructor. Logs at level Notice by default. */ 00029 Log::Log() 00030 { 00031 _logLevel = Notice; 00032 } 00033 00034 /** Destructor. Closes the log file. */ 00035 Log::~Log() 00036 { 00037 close(); 00038 } 00039 00040 /** Returns a list of strings representing available log levels. */ 00041 QStringList 00042 Log::logLevels() 00043 { 00044 return (QStringList() << "debug" << "info" << "notice" 00045 << "warn" << "error"); 00046 } 00047 00048 /** Sets the current log level to <b>level</b>. If <b>level</b> is Off, then 00049 * the log file will be closed as well. If <b>level</b> is Unknown, no change 00050 * to the current log level is made. */ 00051 void 00052 Log::setLogLevel(LogLevel level) 00053 { 00054 if (level >= Debug && level < Unknown) 00055 _logLevel = level; 00056 if (level == Off) 00057 _logFile.close(); 00058 } 00059 00060 /** Opens <b>file</b> for appending, to which log messages will be written. */ 00061 bool 00062 Log::open(FILE *file) 00063 { 00064 if (_logFile.isOpen()) 00065 close(); 00066 00067 _logFile.open(file, LOGFILE_MODE); 00068 return isOpen(); 00069 } 00070 00071 /** Opens <b>file</b> for appending, to which log messages will be written. */ 00072 bool 00073 Log::open(QString file) 00074 { 00075 if (_logFile.isOpen()) 00076 close(); 00077 00078 _logFile.setFileName(file); 00079 _logFile.open(LOGFILE_MODE); 00080 return isOpen(); 00081 } 00082 00083 /** Flushes any outstanding log messages and closes the log file. */ 00084 void 00085 Log::close() 00086 { 00087 if (_logFile.isOpen()) { 00088 _logFile.flush(); 00089 _logFile.close(); 00090 } 00091 } 00092 00093 /** Creates a log message with severity <b>level</b> and initial message 00094 * contents <b>message</b>. The log message can be appended to until the 00095 * returned LogMessage's destructor is called, at which point the complete 00096 * message is written to the log file. */ 00097 inline Log::LogMessage 00098 Log::log(LogLevel level) 00099 { 00100 if (level < _logLevel) 00101 return LogMessage(level, 0); 00102 return LogMessage(level, &_logFile); 00103 } 00104 00105 /** Creates a log message with severity <b>level</b>. The log message can be 00106 * appended to until the returned LogMessage's destructor is called, at 00107 * which point the complete message is written to the log file. */ 00108 Log::LogMessage 00109 Log::log(LogLevel level, QString msg) 00110 { 00111 return log(level) << msg; 00112 } 00113 00114 /** Returns a string description of the given LogLevel <b>level</b>. */ 00115 inline QString 00116 Log::logLevelToString(LogLevel level) 00117 { 00118 switch (level) { 00119 case Debug: return "debug"; 00120 case Info: return "info"; 00121 case Notice: return "notice"; 00122 case Warn: return "warn"; 00123 case Error: return "error"; 00124 case Off: return "off"; 00125 default: return "unknown"; 00126 } 00127 } 00128 00129 /** Returns a LogLevel for the level given by <b>str</b>, or Unknown if the 00130 * given string does not represent a valid LogLevel value. */ 00131 Log::LogLevel 00132 Log::stringToLogLevel(QString str) 00133 { 00134 str = str.toLower(); 00135 if (str == "debug") 00136 return Debug; 00137 else if (str == "info") 00138 return Info; 00139 else if (str == "notice") 00140 return Notice; 00141 else if (str == "warn") 00142 return Warn; 00143 else if (str == "error") 00144 return Error; 00145 else if (str == "off") 00146 return Off; 00147 return Unknown; 00148 } 00149 00150 /** Returns a formatted log message, prefixed with a timestamp and the log 00151 * message severity level. */ 00152 inline QString 00153 Log::LogMessage::toString() const 00154 { 00155 QString msg = QDateTime::currentDateTime().toString(TIMESTAMP_FMT); 00156 msg.append(" [" + Log::logLevelToString(stream->type) + "] "); 00157 msg.append(stream->buf); 00158 return msg; 00159 } 00160 00161 /** Destructor. Writes the buffered log message out to the log file specified 00162 * in the constructor. */ 00163 Log::LogMessage::~LogMessage() 00164 { 00165 if (!--stream->ref) { 00166 if (stream->out && !stream->buf.isEmpty()) { 00167 QTextStream log(stream->out); 00168 log << toString() << endl; 00169 log.flush(); 00170 } 00171 delete stream; 00172 } 00173 } 00174