LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
QsLog.cpp
Go to the documentation of this file.
1// Copyright (c) 2010, Razvan Petru
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
6// Redistribution and use in source and binary forms, with or without modification,
7// are permitted provided that the following conditions are met:
8
9// * Redistributions of source code must retain the above copyright notice, this
10// list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above copyright notice, this
12// list of conditions and the following disclaimer in the documentation and/or other
13// materials provided with the distribution.
14// * The name of the contributors may not be used to endorse or promote products
15// derived from this software without specific prior written permission.
16
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26// OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "QsLog.h"
29#include "QsLogDest.h"
30#include <QMutex>
31#include <QList>
32#include <QDateTime>
33#include <QtGlobal>
34#include <QThread>
35#include <cassert>
36#include <cstdlib>
37#include <stdexcept>
38
39LIMA_COMMONQSLOG_EXPORT QDebug& operator<< (QDebug& qd, const std::string& str )
40{
41 qd << str.c_str();
42 return qd;
43}
44
45namespace QsLogging
46{
47typedef std::shared_ptr<Destination> DestinationPtr;
48typedef QList< DestinationPtr > DestinationList;
49
50static const char TraceString[] = "TRACE";
51static const char DebugString[] = "DEBUG";
52static const char InfoString[] = "INFO";
53static const char WarnString[] = "WARN";
54static const char ErrorString[] = "ERROR";
55static const char FatalString[] = "FATAL";
56
57// not using Qt::ISODate because we need the milliseconds too
58Q_GLOBAL_STATIC_WITH_ARGS(QString, fmtDateTime, ("yyyy-MM-ddThh:mm:ss.zzz"));
59
60static const char* LevelToText(Level theLevel)
61{
62 switch( theLevel )
63 {
64 case TraceLevel:
65 return TraceString;
66 case DebugLevel:
67 return DebugString;
68 case InfoLevel:
69 return InfoString;
70 case WarnLevel:
71 return WarnString;
72 case ErrorLevel:
73 return ErrorString;
74 case FatalLevel:
75 return FatalString;
76 default:
77 {
78 assert(!"bad log level");
79 return InfoString;
80 }
81 }
82}
83
85{
86public:
87 LoggerImpl(const QString& aZone) :
88 level(InfoLevel), zone(aZone)
89 {
90
91 }
92 QMutex logMutex;
95 QString zone;
96};
97
98Logger::Logger(const QString& aZone) :
99 d(new LoggerImpl(aZone))
100{
101}
102
103Logger::~Logger()
104{
105 delete d;
106}
107
109{
110 // std::cerr << "Logger::addDestination " << destination << std::endl;
111 assert(destination);
112 d->destList.push_back(destination);
113}
114
116{
117 d->level = newLevel;
118}
119
121{
122 return d->level;
123}
124
126{
127 return d->level <= QsLogging::FatalLevel;
128}
129
132{
133 return d->level <= QsLogging::TraceLevel;
134}
137{
138 return d->level <= QsLogging::DebugLevel;
139}
142{
143 return d->level <= QsLogging::InfoLevel;
144}
147{
148 return d->level <= QsLogging::WarnLevel;
149}
152{
153 return d->level <= QsLogging::ErrorLevel;
154}
157{
158 return d->level <= QsLogging::FatalLevel;
159}
160
161
162const QString& Logger::zone() const
163{
164 return d->zone;
165}
166
168void Logger::Helper::writeToLog()
169{
170 const char* const levelName = LevelToText(level);
171 QString s;
172 QTextStream ts(&s);
173 ts << QThread::currentThread();
174 const QString completeMessage(QString(QLatin1String("%1 %2 %3 %4"))
175 .arg(QDateTime::currentDateTime().toString(*fmtDateTime))
176 .arg(levelName, 5)
177 .arg(s, buffer)
178 );
179
180 Logger& logger = Logger::instance(zone);
181 QMutexLocker lock(&logger.d->logMutex);
182 // std::cerr << "Logger::Helper::writeToLog " << completeMessage.toStdString() << std::endl;
183 logger.write(completeMessage);
184}
185
187{
188 // writeToLog can throw. Catch its exceptions to avoid throwing from
189 //destructor
190 try
191 {
192 writeToLog();
193 }
194 catch(...)
195 {
196 }
197}
198
200void Logger::write(const QString& message)
201{
202 // std::cerr << "Logger::write " << message.toStdString() << std::endl;
203 if (message.isNull())
204 {
205 std::cerr << "Logger::write null message for " << d->zone.toUtf8().constData() << std::endl << std::flush;
206 return;
207 }
208 for(DestinationList::iterator it = d->destList.begin(),
209 endIt = d->destList.end();it != endIt;++it)
210 {
211 if( !(*it) )
212 {
213 assert(!"null log destination");
214 continue;
215 }
216 (*it)->write(message, d->zone);
217 }
218}
219
220} // end namespace
221
LIMA_COMMONQSLOG_EXPORT QDebug & operator<<(QDebug &qd, const std::string &str)
Definition QsLog.cpp:39
#define LIMA_COMMONQSLOG_EXPORT
DestinationList destList
Definition QsLog.cpp:94
LoggerImpl(const QString &aZone)
Definition QsLog.cpp:87
bool isLoggingEnabled() const
Returns true if logging level is lower than or equal to FatalLevel.
Definition QsLog.cpp:125
bool isWarnEnabled() const
Returns true if logging level is lower than or equal to WarnLevel.
Definition QsLog.cpp:146
bool isErrorEnabled() const
Returns true if logging level is lower than or equal to ErrorLevel.
Definition QsLog.cpp:151
Level loggingLevel() const
The default level is INFO.
Definition QsLog.cpp:120
static Logger & instance(const QString &zone=QLatin1String(""))
Definition QsLog.h:63
bool isTraceEnabled() const
Returns true if logging level is lower than or equal to TraceLevel.
Definition QsLog.cpp:131
const QString & zone() const
Definition QsLog.cpp:162
bool isInfoEnabled() const
Returns true if logging level is lower than or equal to InfoLevel.
Definition QsLog.cpp:141
void setLoggingLevel(Level newLevel)
Logging at a level < 'newLevel' will be ignored.
Definition QsLog.cpp:115
bool isFatalEnabled() const
Returns true if logging level is lower than or equal to FatalLevel.
Definition QsLog.cpp:156
bool isDebugEnabled() const
Returns true if logging level is lower than or equal to DebugLevel.
Definition QsLog.cpp:136
void addDestination(std::shared_ptr< Destination > destination)
Adds a log message destination. Don't add null destinations.
Definition QsLog.cpp:108
static const char DebugString[]
Definition QsLog.cpp:51
Q_GLOBAL_STATIC_WITH_ARGS(QString, fmtDateTime,("yyyy-MM-ddThh:mm:ss.zzz"))
static const char ErrorString[]
Definition QsLog.cpp:54
QList< DestinationPtr > DestinationList
Definition QsLog.cpp:48
std::shared_ptr< Destination > DestinationPtr
Definition QsLog.cpp:47
@ TraceLevel
Definition QsLog.h:48
@ DebugLevel
Definition QsLog.h:49
@ ErrorLevel
Definition QsLog.h:52
@ InfoLevel
Definition QsLog.h:50
@ FatalLevel
Definition QsLog.h:53
@ WarnLevel
Definition QsLog.h:51
static const char InfoString[]
Definition QsLog.cpp:52
static const char TraceString[]
Definition QsLog.cpp:50
static const char WarnString[]
Definition QsLog.cpp:53
static const char FatalString[]
Definition QsLog.cpp:55
static const char * LevelToText(Level theLevel)
Definition QsLog.cpp:60