Skip to content

Commit 2c37ad6

Browse files
Merge branch 'logging' of git://github.com/Ashatta/trikRuntime
2 parents 0aaa3da + 0e08a58 commit 2c37ad6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1552
-50
lines changed

qslog/LICENSE.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Copyright (c) 2014, Razvan Petru
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without modification,
5+
are permitted provided that the following conditions are met:
6+
7+
* Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
* Redistributions in binary form must reproduce the above copyright notice, this
10+
list of conditions and the following disclaimer in the documentation and/or other
11+
materials provided with the distribution.
12+
* The name of the contributors may not be used to endorse or promote products
13+
derived from this software without specific prior written permission.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
19+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
24+
OF THE POSSIBILITY OF SUCH DAMAGE.

qslog/QsLog.cpp

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
// Copyright (c) 2013, Razvan Petru
2+
// All rights reserved.
3+
4+
// Redistribution and use in source and binary forms, with or without modification,
5+
// are permitted provided that the following conditions are met:
6+
7+
// * Redistributions of source code must retain the above copyright notice, this
8+
// list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above copyright notice, this
10+
// list of conditions and the following disclaimer in the documentation and/or other
11+
// materials provided with the distribution.
12+
// * The name of the contributors may not be used to endorse or promote products
13+
// derived from this software without specific prior written permission.
14+
15+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16+
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18+
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
19+
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20+
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23+
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
24+
// OF THE POSSIBILITY OF SUCH DAMAGE.
25+
26+
#include "QsLog.h"
27+
#include "QsLogDest.h"
28+
#include <QThreadPool>
29+
#include <QRunnable>
30+
#include <QMutex>
31+
#include <QVector>
32+
#include <QDateTime>
33+
#include <QtGlobal>
34+
#include <cassert>
35+
#include <cstdlib>
36+
#include <stdexcept>
37+
38+
namespace QsLogging
39+
{
40+
typedef QVector<DestinationPtr> DestinationList;
41+
42+
static const char TraceString[] = "TRACE";
43+
static const char DebugString[] = "DEBUG";
44+
static const char InfoString[] = "INFO ";
45+
static const char WarnString[] = "WARN ";
46+
static const char ErrorString[] = "ERROR";
47+
static const char FatalString[] = "FATAL";
48+
49+
// not using Qt::ISODate because we need the milliseconds too
50+
static const QString fmtDateTime("yyyy-MM-ddThh:mm:ss.zzz");
51+
52+
static Logger* sInstance = 0;
53+
54+
static const char* LevelToText(Level theLevel)
55+
{
56+
switch (theLevel) {
57+
case TraceLevel:
58+
return TraceString;
59+
case DebugLevel:
60+
return DebugString;
61+
case InfoLevel:
62+
return InfoString;
63+
case WarnLevel:
64+
return WarnString;
65+
case ErrorLevel:
66+
return ErrorString;
67+
case FatalLevel:
68+
return FatalString;
69+
case OffLevel:
70+
return "";
71+
default: {
72+
assert(!"bad log level");
73+
return InfoString;
74+
}
75+
}
76+
}
77+
78+
class LogWriterRunnable : public QRunnable
79+
{
80+
public:
81+
LogWriterRunnable(QString message, Level level);
82+
virtual void run();
83+
84+
private:
85+
QString mMessage;
86+
Level mLevel;
87+
};
88+
89+
class LoggerImpl
90+
{
91+
public:
92+
LoggerImpl();
93+
94+
QThreadPool threadPool;
95+
QMutex logMutex;
96+
Level level;
97+
DestinationList destList;
98+
};
99+
100+
LogWriterRunnable::LogWriterRunnable(QString message, Level level)
101+
: QRunnable()
102+
, mMessage(message)
103+
, mLevel(level)
104+
{
105+
}
106+
107+
void LogWriterRunnable::run()
108+
{
109+
Logger::instance().write(mMessage, mLevel);
110+
}
111+
112+
113+
LoggerImpl::LoggerImpl()
114+
: level(InfoLevel)
115+
{
116+
// assume at least file + console
117+
destList.reserve(2);
118+
threadPool.setMaxThreadCount(1);
119+
threadPool.setExpiryTimeout(-1);
120+
}
121+
122+
123+
Logger::Logger()
124+
: d(new LoggerImpl)
125+
{
126+
}
127+
128+
Logger& Logger::instance()
129+
{
130+
if (!sInstance)
131+
sInstance = new Logger;
132+
133+
return *sInstance;
134+
}
135+
136+
void Logger::destroyInstance()
137+
{
138+
delete sInstance;
139+
sInstance = 0;
140+
}
141+
142+
// tries to extract the level from a string log message. If available, conversionSucceeded will
143+
// contain the conversion result.
144+
Level Logger::levelFromLogMessage(const QString& logMessage, bool* conversionSucceeded)
145+
{
146+
if (conversionSucceeded)
147+
*conversionSucceeded = true;
148+
149+
if (logMessage.startsWith(QLatin1String(TraceString)))
150+
return TraceLevel;
151+
if (logMessage.startsWith(QLatin1String(DebugString)))
152+
return DebugLevel;
153+
if (logMessage.startsWith(QLatin1String(InfoString)))
154+
return InfoLevel;
155+
if (logMessage.startsWith(QLatin1String(WarnString)))
156+
return WarnLevel;
157+
if (logMessage.startsWith(QLatin1String(ErrorString)))
158+
return ErrorLevel;
159+
if (logMessage.startsWith(QLatin1String(FatalString)))
160+
return FatalLevel;
161+
162+
if (conversionSucceeded)
163+
*conversionSucceeded = false;
164+
return OffLevel;
165+
}
166+
167+
Logger::~Logger()
168+
{
169+
d->threadPool.waitForDone();
170+
delete d;
171+
d = 0;
172+
}
173+
174+
void Logger::addDestination(DestinationPtr destination)
175+
{
176+
assert(destination.data());
177+
d->destList.push_back(destination);
178+
}
179+
180+
void Logger::setLoggingLevel(Level newLevel)
181+
{
182+
d->level = newLevel;
183+
}
184+
185+
Level Logger::loggingLevel() const
186+
{
187+
return d->level;
188+
}
189+
190+
/// creates the complete log message and passes it to the logger
191+
void Logger::Helper::writeToLog()
192+
{
193+
const char* const levelName = LevelToText(level);
194+
const QString completeMessage(QString("%1 %2 %3")
195+
.arg(levelName)
196+
.arg(QDateTime::currentDateTime().toString(fmtDateTime))
197+
.arg(buffer)
198+
);
199+
200+
Logger::instance().enqueueWrite(completeMessage, level);
201+
}
202+
203+
Logger::Helper::~Helper()
204+
{
205+
try {
206+
writeToLog();
207+
}
208+
catch(std::exception&) {
209+
// you shouldn't throw exceptions from a sink
210+
assert(!"exception in logger helper destructor");
211+
throw;
212+
}
213+
}
214+
215+
/// directs the message to the task queue or writes it directly
216+
void Logger::enqueueWrite(const QString& message, Level level)
217+
{
218+
LogWriterRunnable *r = new LogWriterRunnable(message, level);
219+
d->threadPool.start(r);
220+
}
221+
222+
/// Sends the message to all the destinations. The level for this message is passed in case
223+
/// it's useful for processing in the destination.
224+
void Logger::write(const QString& message, Level level)
225+
{
226+
QMutexLocker lock(&d->logMutex);
227+
for (DestinationList::iterator it = d->destList.begin(),
228+
endIt = d->destList.end();it != endIt;++it) {
229+
(*it)->write(message, level);
230+
}
231+
}
232+
233+
} // end namespace

qslog/QsLog.h

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright (c) 2013, Razvan Petru
2+
// All rights reserved.
3+
4+
// Redistribution and use in source and binary forms, with or without modification,
5+
// are permitted provided that the following conditions are met:
6+
7+
// * Redistributions of source code must retain the above copyright notice, this
8+
// list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above copyright notice, this
10+
// list of conditions and the following disclaimer in the documentation and/or other
11+
// materials provided with the distribution.
12+
// * The name of the contributors may not be used to endorse or promote products
13+
// derived from this software without specific prior written permission.
14+
15+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16+
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18+
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
19+
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20+
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23+
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
24+
// OF THE POSSIBILITY OF SUCH DAMAGE.
25+
26+
#pragma once
27+
28+
#include "QsLogLevel.h"
29+
#include "QsLogDest.h"
30+
#include <QDebug>
31+
#include <QString>
32+
33+
#define QS_LOG_VERSION "2.0b3"
34+
35+
namespace QsLogging
36+
{
37+
class Destination;
38+
class LoggerImpl; // d pointer
39+
40+
class QSLOG_SHARED_OBJECT Logger
41+
{
42+
public:
43+
static Logger& instance();
44+
static void destroyInstance();
45+
static Level levelFromLogMessage(const QString& logMessage, bool* conversionSucceeded = 0);
46+
47+
~Logger();
48+
49+
/// Adds a log message destination. Don't add null destinations.
50+
void addDestination(DestinationPtr destination);
51+
/// Logging at a level < 'newLevel' will be ignored
52+
void setLoggingLevel(Level newLevel);
53+
/// The default level is INFO
54+
Level loggingLevel() const;
55+
56+
/// The helper forwards the streaming to QDebug and builds the final
57+
/// log message.
58+
class QSLOG_SHARED_OBJECT Helper
59+
{
60+
public:
61+
explicit Helper(Level logLevel) :
62+
level(logLevel),
63+
qtDebug(&buffer) {}
64+
~Helper();
65+
QDebug& stream(){ return qtDebug; }
66+
67+
private:
68+
void writeToLog();
69+
70+
Level level;
71+
QString buffer;
72+
QDebug qtDebug;
73+
};
74+
75+
private:
76+
Logger();
77+
Logger(const Logger&); // not available
78+
Logger& operator=(const Logger&); // not available
79+
80+
void enqueueWrite(const QString& message, Level level);
81+
void write(const QString& message, Level level);
82+
83+
LoggerImpl* d;
84+
85+
friend class LogWriterRunnable;
86+
};
87+
88+
} // end namespace
89+
90+
/// WARNING: Here was some piece of code that enabled or disabled file and line info logging.
91+
/// It was removed, so the version from the repo differs from out one.
92+
#define QLOG_TRACE() \
93+
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::TraceLevel) {} \
94+
else QsLogging::Logger::Helper(QsLogging::TraceLevel).stream() << __FILE__ << '@' << __LINE__
95+
#define QLOG_DEBUG() \
96+
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::DebugLevel) {} \
97+
else QsLogging::Logger::Helper(QsLogging::DebugLevel).stream() << __FILE__ << '@' << __LINE__
98+
#define QLOG_INFO() \
99+
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::InfoLevel) {} \
100+
else QsLogging::Logger::Helper(QsLogging::InfoLevel).stream() << __FILE__ << '@' << __LINE__
101+
#define QLOG_WARN() \
102+
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::WarnLevel) {} \
103+
else QsLogging::Logger::Helper(QsLogging::WarnLevel).stream() << __FILE__ << '@' << __LINE__
104+
#define QLOG_ERROR() \
105+
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::ErrorLevel) {} \
106+
else QsLogging::Logger::Helper(QsLogging::ErrorLevel).stream() << __FILE__ << '@' << __LINE__
107+
#define QLOG_FATAL() \
108+
if (QsLogging::Logger::instance().loggingLevel() > QsLogging::FatalLevel) {} \
109+
else QsLogging::Logger::Helper(QsLogging::FatalLevel).stream() << __FILE__ << '@' << __LINE__
110+
111+
#ifdef QS_LOG_DISABLE
112+
#include "QsLogDisableForThisFile.h"
113+
#endif

qslog/QsLog.pri

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
INCLUDEPATH += $$PWD
2+
3+
# WARNING: QS_LOG_LINE_NUMBERS and QS_LOG_SEPARATE_THREAD were removed from repo version and made enabled by default
4+
#DEFINES += QS_LOG_DISABLE # logging code is replaced with a no-op
5+
6+
SOURCES += $$PWD/QsLogDest.cpp \
7+
$$PWD/QsLog.cpp \
8+
$$PWD/QsLogDestConsole.cpp \
9+
$$PWD/QsLogDestFile.cpp \
10+
$$PWD/QsLogDestFunctor.cpp
11+
12+
HEADERS += $$PWD/QsLogDest.h \
13+
$$PWD/QsLog.h \
14+
$$PWD/QsLogDestConsole.h \
15+
$$PWD/QsLogLevel.h \
16+
$$PWD/QsLogDestFile.h \
17+
$$PWD/QsLogDisableForThisFile.h \
18+
$$PWD/QsLogDestFunctor.h
19+
20+
OTHER_FILES += \
21+
$$PWD/QsLogChanges.txt \
22+
$$PWD/QsLogReadme.txt \
23+
$$PWD/LICENSE.txt

0 commit comments

Comments
 (0)