1 /****************************************************************************
2 **
3 ** Copyright (C) 2017 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qloggingcategory.h"
41 #include "qloggingregistry_p.h"
42 
43 QT_BEGIN_NAMESPACE
44 
45 const char qtDefaultCategoryName[] = "default";
46 
47 Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
48                           (qtDefaultCategoryName))
49 
50 #ifndef Q_ATOMIC_INT8_IS_SUPPORTED
setBoolLane(QBasicAtomicInt * atomic,bool enable,int shift)51 static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
52 {
53     const int bit = 1 << shift;
54 
55     if (enable)
56         atomic->fetchAndOrRelaxed(bit);
57     else
58         atomic->fetchAndAndRelaxed(~bit);
59 }
60 #endif
61 
62 /*!
63     \class QLoggingCategory
64     \inmodule QtCore
65     \since 5.2
66     \threadsafe
67 
68     \brief The QLoggingCategory class represents a category, or 'area' in the
69     logging infrastructure.
70 
71     QLoggingCategory represents a certain logging category - identified by a
72     string - at runtime. A category can be configured to enable or disable
73     logging of messages per message type.
74 
75     To check whether a message type is enabled or not, use one of these methods:
76     \l isDebugEnabled(), \l isInfoEnabled(), \l isWarningEnabled(), and
77     \l isCriticalEnabled().
78 
79     All objects are meant to be configured by a common registry, as described in
80     \l{Configuring Categories}. Different objects can also represent the same
81     category. Therefore, it's \b{not} recommended to export objects across
82     module boundaries, to manipulate the objects directly, or to inherit from
83     QLoggingCategory.
84 
85     \section1 Creating Category Objects
86 
87     The Q_DECLARE_LOGGING_CATEGORY() and Q_LOGGING_CATEGORY() macros
88     conveniently declare and create QLoggingCategory objects:
89 
90     \snippet qloggingcategory/main.cpp 1
91 
92     Category names are free text; to configure categories using \l{Logging Rules}, their
93     names should follow this convention:
94     \list
95        \li Use letters and numbers only.
96        \li Use dots to further structure categories into common areas.
97        \li Avoid the category names: \c{debug}, \c{info}, \c{warning}, and \c{critical}.
98        \li Category names with the \c{qt} prefix are solely reserved for Qt modules.
99     \endlist
100 
101     QLoggingCategory objects that are implicitly defined by Q_LOGGING_CATEGORY()
102     are created on first use, in a thread-safe manner.
103 
104     \section1 Checking Category Configuration
105 
106     QLoggingCategory provides \l isDebugEnabled(), \l isInfoEnabled(),
107     \l isWarningEnabled(), \l isCriticalEnabled(), as well as \l isEnabled()
108     to check whether messages for the given message type should be logged.
109 
110     The qCDebug(), qCWarning(), and qCCritical() macros prevent arguments from
111     being evaluated if the respective message types are not enabled for the
112     category, so explicit checking is not needed:
113 
114     \snippet qloggingcategory/main.cpp 4
115 
116     \section1 Default Category Configuration
117 
118     Both the QLoggingCategory constructor and the Q_LOGGING_CATEGORY() macro
119     accept an optional QtMsgType argument, which disables all message types with
120     a lower severity. That is, a category declared with
121 
122     \snippet qloggingcategory/main.cpp 5
123 
124     logs messages of type \c QtWarningMsg, \c QtCriticalMsg, \c QtFatalMsg, but
125     ignores messages of type \c QtDebugMsg and \c QtInfoMsg.
126 
127     If no argument is passed, all messages are logged.
128 
129     \section1 Configuring Categories
130 
131     You can override the default configuration for categories either by setting
132     logging rules, or by installing a custom filter.
133 
134     \section2 Logging Rules
135 
136     Logging rules let you enable or disable logging for categories in a flexible
137     way. Rules are specified in text, where every line must have the format:
138 
139     \snippet code/src_corelib_io_qloggingcategory.cpp 0
140 
141     \c <category> is the name of the category, potentially with \c{*} as a
142     wildcard symbol for the first or last character; or at both positions.
143     The optional \c <type> must be \c debug, \c info, \c warning, or \c critical.
144     Lines that don't fit this scheme are ignored.
145 
146     Rules are evaluated in text order, from first to last. That is, if two rules
147     apply to a category/type, the rule that comes later is applied.
148 
149     Rules can be set via \l setFilterRules():
150 
151     \snippet code/src_corelib_io_qloggingcategory.cpp 1
152 
153     Logging rules are automatically loaded from the \c [Rules] section in a logging
154     configuration file. These configuration files are looked up in the QtProject
155     configuration directory, or explicitly set in a \c QT_LOGGING_CONF environment
156     variable:
157 
158     \snippet code/src_corelib_io_qloggingcategory.cpp 2
159 
160     Logging rules can also be specified in a \c QT_LOGGING_RULES environment variable;
161     multiple rules can also be separated by semicolons:
162 
163     \snippet code/src_corelib_io_qloggingcategory.cpp 3
164 
165     Rules set by \l setFilterRules() take precedence over rules specified in the
166     QtProject configuration directory. In turn, these rules can be overwritten by those
167     from the configuration file specified by \c QT_LOGGING_CONF, and those set by
168     \c QT_LOGGING_RULES.
169 
170     The order of evaluation is as follows:
171     \list 1
172         \li [QLibraryInfo::DataPath]/qtlogging.ini
173         \li QtProject/qtlogging.ini
174         \li \l setFilterRules()
175         \li \c QT_LOGGING_CONF
176         \li \c QT_LOGGING_RULES
177     \endlist
178 
179     The \c QtProject/qtlogging.ini file is looked up in all directories returned
180     by QStandardPaths::GenericConfigLocation.
181 
182     Set the \c QT_LOGGING_DEBUG environment variable to find out where your logging
183     rules are loaded from.
184 
185     \section2 Installing a Custom Filter
186 
187     As a lower-level alternative to the text rules, you can also implement a
188     custom filter via \l installFilter(). All filter rules are ignored in this
189     case.
190 
191     \section1 Printing the Category
192 
193     Use the \c %{category} placeholder to print the category in the default
194     message handler:
195 
196     \snippet qloggingcategory/main.cpp 3
197 */
198 
199 /*!
200     Constructs a QLoggingCategory object with the provided \a category name.
201     All message types for this category are enabled by default.
202 
203     If \a category is \c{0}, the category name is changed to \c "default".
204 
205     \note \a category must be kept valid during the lifetime of this object.
206 */
QLoggingCategory(const char * category)207 QLoggingCategory::QLoggingCategory(const char *category)
208     : d(nullptr),
209       name(nullptr)
210 {
211     init(category, QtDebugMsg);
212 }
213 
214 /*!
215     Constructs a QLoggingCategory object with the provided \a category name,
216     and enables all messages with types more severe or equal than \a enableForLevel.
217 
218     If \a category is \c{0}, the category name is changed to \c "default".
219 
220     \note \a category must be kept valid during the lifetime of this object.
221 
222     \since 5.4
223 */
QLoggingCategory(const char * category,QtMsgType enableForLevel)224 QLoggingCategory::QLoggingCategory(const char *category, QtMsgType enableForLevel)
225     : d(nullptr),
226       name(nullptr)
227 {
228     init(category, enableForLevel);
229 }
230 
init(const char * category,QtMsgType severityLevel)231 void QLoggingCategory::init(const char *category, QtMsgType severityLevel)
232 {
233     enabled.storeRelaxed(0x01010101);   // enabledDebug = enabledWarning = enabledCritical = true;
234 
235     if (category)
236         name = category;
237     else
238         name = qtDefaultCategoryName;
239 
240     if (QLoggingRegistry *reg = QLoggingRegistry::instance())
241         reg->registerCategory(this, severityLevel);
242 }
243 
244 /*!
245     Destroys a QLoggingCategory object.
246 */
~QLoggingCategory()247 QLoggingCategory::~QLoggingCategory()
248 {
249     if (QLoggingRegistry *reg = QLoggingRegistry::instance())
250         reg->unregisterCategory(this);
251 }
252 
253 /*!
254    \fn const char *QLoggingCategory::categoryName() const
255 
256     Returns the name of the category.
257 */
258 
259 /*!
260     \fn bool QLoggingCategory::isDebugEnabled() const
261 
262     Returns \c true if debug messages should be shown for this category;
263     \c false otherwise.
264 
265     \note The \l qCDebug() macro already does this check before running any
266     code. However, calling this method may be useful to avoid the
267     expensive generation of data for debug output only.
268 */
269 
270 
271 /*!
272     \fn bool QLoggingCategory::isInfoEnabled() const
273 
274     Returns \c true if informational messages should be shown for this category;
275     \c false otherwise.
276 
277     \note The \l qCInfo() macro already does this check before executing any
278     code. However, calling this method may be useful to avoid the
279     expensive generation of data for debug output only.
280 
281     \since 5.5
282 */
283 
284 
285 /*!
286     \fn bool QLoggingCategory::isWarningEnabled() const
287 
288     Returns \c true if warning messages should be shown for this category;
289     \c false otherwise.
290 
291     \note The \l qCWarning() macro already does this check before executing any
292     code. However, calling this method may be useful to avoid the
293     expensive generation of data for debug output only.
294 */
295 
296 /*!
297     \fn bool QLoggingCategory::isCriticalEnabled() const
298 
299     Returns \c true if critical messages should be shown for this category;
300     \c false otherwise.
301 
302     \note The \l qCCritical() macro already does this check before executing any
303     code. However, calling this method may be useful to avoid the
304     expensive generation of data for debug output only.
305 */
306 
307 /*!
308     Returns \c true if a message of type \a msgtype for the category should be
309     shown; \c false otherwise.
310 */
isEnabled(QtMsgType msgtype) const311 bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
312 {
313     switch (msgtype) {
314     case QtDebugMsg: return isDebugEnabled();
315     case QtInfoMsg: return isInfoEnabled();
316     case QtWarningMsg: return isWarningEnabled();
317     case QtCriticalMsg: return isCriticalEnabled();
318     case QtFatalMsg: return true;
319     }
320     return false;
321 }
322 
323 /*!
324     Changes the message type \a type for the category to \a enable.
325 
326     This method is meant for use only from inside a filter installed with
327     \l installFilter(). For an overview on how to configure categories globally,
328     see \l {Configuring Categories}.
329 
330     \note \c QtFatalMsg cannot be changed; it will always remain \c true.
331 */
setEnabled(QtMsgType type,bool enable)332 void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
333 {
334     switch (type) {
335 #ifdef Q_ATOMIC_INT8_IS_SUPPORTED
336     case QtDebugMsg: bools.enabledDebug.storeRelaxed(enable); break;
337     case QtInfoMsg: bools.enabledInfo.storeRelaxed(enable); break;
338     case QtWarningMsg: bools.enabledWarning.storeRelaxed(enable); break;
339     case QtCriticalMsg: bools.enabledCritical.storeRelaxed(enable); break;
340 #else
341     case QtDebugMsg: setBoolLane(&enabled, enable, DebugShift); break;
342     case QtInfoMsg: setBoolLane(&enabled, enable, InfoShift); break;
343     case QtWarningMsg: setBoolLane(&enabled, enable, WarningShift); break;
344     case QtCriticalMsg: setBoolLane(&enabled, enable, CriticalShift); break;
345 #endif
346     case QtFatalMsg: break;
347     }
348 }
349 
350 /*!
351     \fn QLoggingCategory &QLoggingCategory::operator()()
352 
353     Returns the object itself. This allows for both: a QLoggingCategory variable, and
354     a factory method that returns a QLoggingCategory, to be used in \l qCDebug(),
355     \l qCWarning(), or \l qCCritical() macros.
356  */
357 
358 /*!
359     \fn const QLoggingCategory &QLoggingCategory::operator()() const
360 
361     Returns the object itself. This allows for both: a QLoggingCategory variable, and
362     a factory method that returns a QLoggingCategory, to be used in \l qCDebug(),
363     \l qCWarning(), or \l qCCritical() macros.
364  */
365 
366 /*!
367     Returns a pointer to the global category \c "default" that is used, for
368     example, by qDebug(), qInfo(), qWarning(), qCritical(), or qFatal().
369 
370     \note The pointer returned may be null during destruction of static objects.
371     Also, don't \c delete this pointer, as ownership of the category isn't transferred.
372 
373  */
defaultCategory()374 QLoggingCategory *QLoggingCategory::defaultCategory()
375 {
376     return qtDefaultCategory();
377 }
378 
379 /*!
380     \typedef QLoggingCategory::CategoryFilter
381 
382     This is a typedef for a pointer to a function with the following signature:
383 
384     \snippet qloggingcategory/main.cpp 20
385 
386     A function with this signature can be installed with \l installFilter().
387 */
388 
389 /*!
390     Installs a function \a filter that is used to determine which categories
391     and message types should be enabled. Returns a pointer to the previous
392     installed filter.
393 
394     Every QLoggingCategory object created is passed to the filter, and the
395     filter is free to change the respective category configuration with
396     \l setEnabled().
397 
398     When you define your filter, note that it can be called from different threads; but never
399     concurrently. This filter cannot call any static functions from QLoggingCategory.
400 
401     Example:
402     \snippet qloggingcategory/main.cpp 21
403 
404     Alternatively, you can configure the default filter via \l setFilterRules().
405  */
406 QLoggingCategory::CategoryFilter
installFilter(QLoggingCategory::CategoryFilter filter)407 QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
408 {
409     return QLoggingRegistry::instance()->installFilter(filter);
410 }
411 
412 /*!
413     Configures which categories and message types should be enabled through a
414     set of \a rules.
415 
416     Example:
417 
418     \snippet qloggingcategory/main.cpp 2
419 
420     \note The rules might be ignored if a custom category filter is installed
421     with \l installFilter(), or if the user has defined the \c QT_LOGGING_CONF
422     or the \c QT_LOGGING_RULES environment variable.
423 */
setFilterRules(const QString & rules)424 void QLoggingCategory::setFilterRules(const QString &rules)
425 {
426     QLoggingRegistry::instance()->setApiRules(rules);
427 }
428 
429 /*!
430     \macro qCDebug(category)
431     \relates QLoggingCategory
432     \threadsafe
433     \since 5.2
434 
435     Returns an output stream for debug messages in the logging category,
436     \a category.
437 
438     The macro expands to code that checks whether
439     \l QLoggingCategory::isDebugEnabled() evaluates to \c true.
440     If so, the stream arguments are processed and sent to the message handler.
441 
442     Example:
443 
444     \snippet qloggingcategory/main.cpp 10
445 
446     \note Arguments aren't processed if the debug output for that \a category is not
447     enabled, so don't rely on any side effects.
448 
449     \sa qDebug()
450 */
451 
452 /*!
453     \macro qCDebug(category, const char *message, ...)
454     \relates QLoggingCategory
455     \threadsafe
456     \since 5.3
457 
458     Logs a debug message, \a message, in the logging category, \a category.
459     \a message may contain place holders to be replaced by additional arguments,
460     similar to the C printf() function.
461 
462     Example:
463 
464     \snippet qloggingcategory/main.cpp 13
465 
466     \note Arguments aren't processed if the debug output for that \a category is not
467     enabled, so don't rely on any side effects.
468 
469     \sa qDebug()
470 */
471 
472 /*!
473     \macro qCInfo(category)
474     \relates QLoggingCategory
475     \threadsafe
476     \since 5.5
477 
478     Returns an output stream for informational messages in the logging category,
479     \a category.
480 
481     The macro expands to code that checks whether
482     \l QLoggingCategory::isInfoEnabled() evaluates to \c true.
483     If so, the stream arguments are processed and sent to the message handler.
484 
485     Example:
486 
487     \snippet qloggingcategory/main.cpp qcinfo_stream
488 
489     \note If the debug output for a particular category isn't enabled, arguments
490     won't be processed, so don't rely on any side effects.
491 
492     \sa qInfo()
493 */
494 
495 /*!
496     \macro qCInfo(category, const char *message, ...)
497     \relates QLoggingCategory
498     \threadsafe
499     \since 5.5
500 
501     Logs an informational message, \a message, in the logging category, \a category.
502     \a message may contain place holders to be replaced by additional arguments,
503     similar to the C printf() function.
504 
505     Example:
506 
507     \snippet qloggingcategory/main.cpp qcinfo_printf
508 
509     \note If the debug output for a particular category isn't enabled, arguments
510     won't be processed, so don't rely on any side effects.
511 
512     \sa qInfo()
513 */
514 
515 /*!
516     \macro qCWarning(category)
517     \relates QLoggingCategory
518     \threadsafe
519     \since 5.2
520 
521     Returns an output stream for warning messages in the logging category,
522     \a category.
523 
524     The macro expands to code that checks whether
525     \l QLoggingCategory::isWarningEnabled() evaluates to \c true.
526     If so, the stream arguments are processed and sent to the message handler.
527 
528     Example:
529 
530     \snippet qloggingcategory/main.cpp 11
531 
532     \note If the warning output for a particular category isn't enabled, arguments
533     won't be processed, so don't rely on any side effects.
534 
535     \sa qWarning()
536 */
537 
538 /*!
539     \macro qCWarning(category, const char *message, ...)
540     \relates QLoggingCategory
541     \threadsafe
542     \since 5.3
543 
544     Logs a warning message, \a message, in the logging category, \a category.
545     \a message may contain place holders to be replaced by additional arguments,
546     similar to the C printf() function.
547 
548     Example:
549 
550     \snippet qloggingcategory/main.cpp 14
551 
552     \note If the warning output for a particular category isn't enabled, arguments
553     won't be processed, so don't rely on any side effects.
554 
555     \sa qWarning()
556 */
557 
558 /*!
559     \macro qCCritical(category)
560     \relates QLoggingCategory
561     \threadsafe
562     \since 5.2
563 
564     Returns an output stream for critical messages in the logging category,
565     \a category.
566 
567     The macro expands to code that checks whether
568     \l QLoggingCategory::isCriticalEnabled() evaluates to \c true.
569     If so, the stream arguments are processed and sent to the message handler.
570 
571     Example:
572 
573     \snippet qloggingcategory/main.cpp 12
574 
575 
576     \note If the critical output for a particular category isn't enabled, arguments
577     won't be processed, so don't rely on any side effects.
578 
579     \sa qCritical()
580 */
581 
582 /*!
583     \macro qCCritical(category, const char *message, ...)
584     \relates QLoggingCategory
585     \threadsafe
586     \since 5.3
587 
588     Logs a critical message, \a message, in the logging category, \a category.
589     \a message may contain place holders to be replaced by additional arguments,
590     similar to the C printf() function.
591 
592     Example:
593 
594     \snippet qloggingcategory/main.cpp 15
595 
596     \note If the critical output for a particular category isn't enabled, arguments
597     won't be processed, so don't rely on any side effects.
598 
599     \sa qCritical()
600 */
601 /*!
602     \macro Q_DECLARE_LOGGING_CATEGORY(name)
603     \sa Q_LOGGING_CATEGORY()
604     \relates QLoggingCategory
605     \since 5.2
606 
607     Declares a logging category \a name. The macro can be used to declare
608     a common logging category shared in different parts of the program.
609 
610     This macro must be used outside of a class or method.
611 */
612 
613 /*!
614     \macro Q_LOGGING_CATEGORY(name, string)
615     \sa Q_DECLARE_LOGGING_CATEGORY()
616     \relates QLoggingCategory
617     \since 5.2
618 
619     Defines a logging category \a name, and makes it configurable under the
620     \a string identifier. By default, all message types are enabled.
621 
622     Only one translation unit in a library or executable can define a category
623     with a specific name. The implicitly-defined QLoggingCategory object is
624     created on first use, in a thread-safe manner.
625 
626     This macro must be used outside of a class or method.
627 */
628 
629 /*!
630     \macro Q_LOGGING_CATEGORY(name, string, msgType)
631     \sa Q_DECLARE_LOGGING_CATEGORY()
632     \relates QLoggingCategory
633     \since 5.4
634 
635     Defines a logging category \a name, and makes it configurable under the
636     \a string identifier. By default, messages of QtMsgType \a msgType
637     and more severe are enabled, types with a lower severity are disabled.
638 
639     Only one translation unit in a library or executable can define a category
640     with a specific name. The implicitly-defined QLoggingCategory object is
641     created on first use, in a thread-safe manner.
642 
643     This macro must be used outside of a class or method. It is only defined
644     if variadic macros are supported.
645 */
646 
647 QT_END_NAMESPACE
648