15 #include <QTextStream>
34 retval.mChannel = channel;
40 return QString(
"%1/org.custusx.log.%2.txt").arg(mPath).arg(mChannel);
46 retval.mPath = QFileInfo(filename).path();
47 retval.mChannel = QFileInfo(filename).completeBaseName().split(
".").back();
54 QString formatInfo =
"[timestamp][source info][severity][thread] <text> ";
55 QString text = QString(
"-------> Logging initialized [%1], format: %2\n").arg(timestamp).arg(formatInfo);
56 bool success = this->appendToLogfile(this->
getFilename(), text);
62 QString text = this->formatMessage(message) +
"\n";
69 if (filename.isEmpty())
73 return file.open(QFile::WriteOnly | QFile::Append);
77 QString LogFile::timestampFormat()
const
79 return "hh:mm:ss.zzz";
82 QString LogFile::formatMessage(
Message msg)
87 retval += QString(
"[%1]").arg(msg.
getTimeStamp().toString(this->timestampFormat()));
91 retval += QString(
"[%1]").arg(msg.
mThread);
111 bool LogFile::appendToLogfile(QString filename, QString text)
113 if (filename.isEmpty())
116 QFile file(filename);
119 if (!file.open(QFile::WriteOnly | QFile::Append))
124 stream.setDevice(&file);
131 QRegExp LogFile::getRX_Timestamp()
const
133 return QRegExp(
"\\[(\\d\\d:\\d\\d:\\d\\d\\.\\d\\d\\d)\\]");
138 QString text = this->readFileTail();
141 if (text.endsWith(
"\n"))
144 QStringList lines = text.split(
"\n");
146 QRegExp rx_ts = this->getRX_Timestamp();
148 std::vector<Message> retval;
150 for (
int i=0; i<lines.size(); ++i)
152 QString line = lines[i];
154 QDateTime timestamp = this->readTimestampFromSessionStartLine(lines[i]);
155 if (timestamp.isValid())
157 mInitTimestamp = timestamp;
162 retval.push_back(msg);
166 if (line.count(rx_ts))
168 Message msg = this->readMessageFirstLine(lines[i]);
170 retval.push_back(msg);
175 retval.back().mText +=
"\n"+line;
182 Message LogFile::readMessageFirstLine(QString line)
184 MESSAGE_LEVEL level = this->readMessageLevel(line);
187 QString levelSymbol = QString(
"[%1]").arg(enum2string<MESSAGE_LEVEL>(level));
188 QStringList parts = line.split(levelSymbol);
193 QString description = parts[1];
194 QStringList fields = parts[0].split(
"\t");
196 Message retval(description, level);
198 this->parseTimestamp(this->getIndex(fields, 0), &retval);
199 this->parseThread(this->getIndex(fields, 1), &retval);
200 this->parseSourceFileLine(this->getIndex(fields, 2), &retval);
201 this->parseSourceFunction(this->getIndex(fields, 3), &retval);
206 QString LogFile::getIndex(
const QStringList& list,
int index)
208 if (0>index || index >= list.size())
210 QString field = list[index];
211 if (field.startsWith(
"["))
213 if (field.endsWith(
"]"))
218 void LogFile::parseTimestamp(QString text,
Message* retval)
224 QTime time = QTime::fromString(text, this->timestampFormat());
228 void LogFile::parseThread(QString text,
Message* retval)
233 void LogFile::parseSourceFileLine(QString text,
Message* retval)
235 if (!text.count(
":"))
238 QStringList parts = text.split(
":");
247 void LogFile::parseSourceFunction(QString text,
Message* retval)
249 if (!text.count(
"("))
254 MESSAGE_LEVEL LogFile::readMessageLevel(QString line)
257 for (
int i=0; i<mlCOUNT; ++i)
258 levels << enum2string<MESSAGE_LEVEL>((MESSAGE_LEVEL)(i));
259 QRegExp rx_level(QString(
"\\[(%1)\\]").arg(levels.join(
"|")));
261 int pos = rx_level.indexIn(line);
262 QStringList hits = rx_level.capturedTexts();
267 return string2enum<MESSAGE_LEVEL>(hits[1]);
270 QDateTime LogFile::readTimestampFromSessionStartLine(QString text)
272 QString sessionStartSymbol(
"------->");
273 if (!text.startsWith(sessionStartSymbol))
276 QRegExp rx_ts_start(
"\\[([^\\]]*)");
277 if (text.indexOf(rx_ts_start) < 0)
280 QString rawTime = rx_ts_start.cap(1);
282 QDateTime ts = QDateTime::fromString(rawTime, format);
287 QString LogFile::readFileTail()
290 file.open(QIODevice::ReadOnly);
292 file.seek(mFilePosition);
293 QString text = file.readAll();
294 mFilePosition = file.pos();