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