Vidalia  0.2.21
Log.cpp
Go to the documentation of this file.
1 /*
2 ** This file is part of Vidalia, and is subject to the license terms in the
3 ** LICENSE file, found in the top level directory of this distribution. If you
4 ** did not receive the LICENSE file with this file, you may obtain it from the
5 ** Vidalia source package distributed by the Vidalia Project at
6 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7 ** including this file, may be copied, modified, propagated, or distributed
8 ** except according to the terms described in the LICENSE file.
9 */
10 
11 /*
12 ** \file Log.cpp
13 ** \brief Debug message logging
14 */
15 
16 #include "Log.h"
17 
18 #include <QDateTime>
19 #include <QTextStream>
20 
21 /** Open log files for appending as write-only text. */
22 #define LOGFILE_MODE \
23  (QIODevice::WriteOnly|QIODevice::Append|QIODevice::Text)
24 /** Format for log message timestamps. */
25 #define TIMESTAMP_FMT "MMM dd HH:mm:ss.zzz"
26 
27 
28 /** Default constructor. Logs at level Notice by default. */
30 {
31  _logLevel = Notice;
32 }
33 
34 /** Destructor. Closes the log file. */
36 {
37  close();
38 }
39 
40 /** Returns a list of strings representing available log levels. */
41 QStringList
43 {
44  return (QStringList() << "debug" << "info" << "notice"
45  << "warn" << "error");
46 }
47 
48 /** Sets the current log level to <b>level</b>. If <b>level</b> is Off, then
49  * the log file will be closed as well. If <b>level</b> is Unknown, no change
50  * to the current log level is made. */
51 void
53 {
54  if (level >= Debug && level < Unknown)
55  _logLevel = level;
56  if (level == Off)
57  _logFile.close();
58 }
59 
60 /** Opens <b>file</b> for appending, to which log messages will be written. */
61 bool
62 Log::open(FILE *file)
63 {
64  if (_logFile.isOpen())
65  close();
66 
67  _logFile.open(file, LOGFILE_MODE);
68  return isOpen();
69 }
70 
71 /** Opens <b>file</b> for appending, to which log messages will be written. */
72 bool
73 Log::open(QString file)
74 {
75  if (_logFile.isOpen())
76  close();
77 
78  _logFile.setFileName(file);
79  _logFile.open(LOGFILE_MODE);
80  return isOpen();
81 }
82 
83 /** Flushes any outstanding log messages and closes the log file. */
84 void
86 {
87  if (_logFile.isOpen()) {
88  _logFile.flush();
89  _logFile.close();
90  }
91 }
92 
93 /** Creates a log message with severity <b>level</b> and initial message
94  * contents <b>message</b>. The log message can be appended to until the
95  * returned LogMessage's destructor is called, at which point the complete
96  * message is written to the log file. */
97 inline Log::LogMessage
99 {
100  if (level < _logLevel)
101  return LogMessage(level, 0);
102  return LogMessage(level, &_logFile);
103 }
104 
105 /** Creates a log message with severity <b>level</b>. The log message can be
106  * appended to until the returned LogMessage's destructor is called, at
107  * which point the complete message is written to the log file. */
109 Log::log(LogLevel level, QString msg)
110 {
111  return log(level) << msg;
112 }
113 
114 /** Returns a string description of the given LogLevel <b>level</b>. */
115 inline QString
117 {
118  switch (level) {
119  case Debug: return "debug";
120  case Info: return "info";
121  case Notice: return "notice";
122  case Warn: return "warn";
123  case Error: return "error";
124  case Off: return "off";
125  default: return "unknown";
126  }
127 }
128 
129 /** Returns a LogLevel for the level given by <b>str</b>, or Unknown if the
130  * given string does not represent a valid LogLevel value. */
133 {
134  str = str.toLower();
135  if (str == "debug")
136  return Debug;
137  else if (str == "info")
138  return Info;
139  else if (str == "notice")
140  return Notice;
141  else if (str == "warn")
142  return Warn;
143  else if (str == "error")
144  return Error;
145  else if (str == "off")
146  return Off;
147  return Unknown;
148 }
149 
150 /** Returns a formatted log message, prefixed with a timestamp and the log
151  * message severity level. */
152 inline QString
154 {
155  QString msg = QDateTime::currentDateTime().toString(TIMESTAMP_FMT);
156  msg.append(" [" + Log::logLevelToString(stream->type) + "] ");
157  msg.append(stream->buf);
158  return msg;
159 }
160 
161 /** Destructor. Writes the buffered log message out to the log file specified
162  * in the constructor. */
164 {
165  if (!--stream->ref) {
166  if (stream->out && !stream->buf.isEmpty()) {
167  QTextStream log(stream->out);
168  log << toString() << endl;
169  log.flush();
170  }
171  delete stream;
172  }
173 }
174