Support setting a default severity level for QLoggingCategory
Allow to alter the default configuration for categories by passing a message type: All message types with lower severity are disabled in this category. This is useful for libraries, which shouldn't mess with the category registry itself: Setting rules, a category filter ... might cause conflicts and ordering problems, so this API should be reserved to the specific application. For the Qt categories, we have code in the default category filter that disables the 'debug' category. However, this is hardcoded, and there's no way so far for other libraries to get the same behavior. With this patch one can get the same behavior: Q_LOGGING_CATEGORY(DRIVER_USB_EVENTS, "driver.usb.events", QtWarningMsg); [ChangeLog][QtCore][Logging] Added QtMsgType argument to QLoggingCategory constructor and Q_LOGGING_CATEGORY macro that controls the default category configuration. Change-Id: Ib2902f755f9f7285d79888ec30e8f3cef95ae628 Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
This commit is contained in:
parent
c4a2d6ca1e
commit
ea34893b8f
@ -49,6 +49,9 @@ Q_DECLARE_LOGGING_CATEGORY(driverUsb)
|
||||
Q_LOGGING_CATEGORY(driverUsb, "driver.usb")
|
||||
//![1]
|
||||
|
||||
//![5]
|
||||
Q_LOGGING_CATEGORY(driverUsbEvents, "driver.usb.events", QtWarningMsg)
|
||||
//![5]
|
||||
|
||||
// Completely made up example, inspired by en.wikipedia.org/wiki/USB :)
|
||||
struct UsbEntry {
|
||||
|
@ -101,13 +101,21 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
|
||||
|
||||
\section1 Default category configuration
|
||||
|
||||
In the default configuration \l isWarningEnabled() , \l isDebugEnabled() and
|
||||
\l isCriticalEnabled() will return \c true.
|
||||
Both the QLoggingCategory constructor and the Q_LOGGING_CATEGORY() macro
|
||||
accept an optional QtMsgType argument, which disables all message types with
|
||||
a lower severity. That is, a category declared with
|
||||
|
||||
\snippet qloggingcategory/main.cpp 5
|
||||
|
||||
will log messages of type \c QtWarningMsg, \c QtCriticalMsg, \c QtFatalMsg, but will
|
||||
ignore messages of type \c QtDebugMsg.
|
||||
|
||||
If no argument is passed, all messages will be logged.
|
||||
|
||||
\section1 Configuring Categories
|
||||
|
||||
Categories can be centrally configured by either setting logging rules,
|
||||
or by installing a custom filter.
|
||||
The default configuration of categories can be overridden either by setting logging
|
||||
rules, or by installing a custom filter.
|
||||
|
||||
\section2 Logging Rules
|
||||
|
||||
@ -183,13 +191,33 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
|
||||
|
||||
/*!
|
||||
Constructs a QLoggingCategory object with the provided \a category name.
|
||||
The object becomes the local identifier for the category.
|
||||
All message types for this category are enabled by default.
|
||||
|
||||
If \a category is \c{0}, the category name is changed to \c "default".
|
||||
*/
|
||||
QLoggingCategory::QLoggingCategory(const char *category)
|
||||
: d(0),
|
||||
name(0)
|
||||
{
|
||||
init(category, QtDebugMsg);
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a QLoggingCategory object with the provided \a category name,
|
||||
and enables all messages with types more severe or equal than \a enableForLevel.
|
||||
|
||||
If \a category is \c{0}, the category name is changed to \c "default".
|
||||
|
||||
\since 5.4
|
||||
*/
|
||||
QLoggingCategory::QLoggingCategory(const char *category, QtMsgType enableForLevel)
|
||||
: d(0),
|
||||
name(0)
|
||||
{
|
||||
init(category, enableForLevel);
|
||||
}
|
||||
|
||||
void QLoggingCategory::init(const char *category, QtMsgType severityLevel)
|
||||
{
|
||||
enabled.store(0x01010101); // enabledDebug = enabledWarning = enabledCritical = true;
|
||||
|
||||
@ -198,14 +226,13 @@ QLoggingCategory::QLoggingCategory(const char *category)
|
||||
|
||||
// normalize "default" category name, so that we can just do
|
||||
// pointer comparison in QLoggingRegistry::updateCategory
|
||||
if (isDefaultCategory) {
|
||||
if (isDefaultCategory)
|
||||
name = qtDefaultCategoryName;
|
||||
} else {
|
||||
else
|
||||
name = category;
|
||||
}
|
||||
|
||||
if (QLoggingRegistry *reg = QLoggingRegistry::instance())
|
||||
reg->registerCategory(this);
|
||||
reg->registerCategory(this, severityLevel);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -522,7 +549,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
||||
\since 5.2
|
||||
|
||||
Defines a logging category \a name, and makes it configurable under the
|
||||
\a string identifier.
|
||||
\a string identifier. By default, all message types are enabled.
|
||||
|
||||
Only one translation unit in a library or executable can define a category
|
||||
with a specific name.
|
||||
@ -530,4 +557,21 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
||||
This macro must be used outside of a class or method.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro Q_LOGGING_CATEGORY(name, string, msgType)
|
||||
\sa Q_DECLARE_LOGGING_CATEGORY()
|
||||
\relates QLoggingCategory
|
||||
\since 5.4
|
||||
|
||||
Defines a logging category \a name, and makes it configurable under the
|
||||
\a string identifier. By default, messages of QtMsgType \a msgType
|
||||
and more severe are enabled, types with a lower severity are disabled.
|
||||
|
||||
Only one translation unit in a library or executable can define a category
|
||||
with a specific name.
|
||||
|
||||
This macro must be used outside of a class or method. It is only defined
|
||||
if variadic macros are supported.
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -51,7 +51,9 @@ class Q_CORE_EXPORT QLoggingCategory
|
||||
{
|
||||
Q_DISABLE_COPY(QLoggingCategory)
|
||||
public:
|
||||
// ### Qt 6: Merge constructors
|
||||
explicit QLoggingCategory(const char *category);
|
||||
QLoggingCategory(const char *category, QtMsgType severityLevel);
|
||||
~QLoggingCategory();
|
||||
|
||||
bool isEnabled(QtMsgType type) const;
|
||||
@ -80,6 +82,8 @@ public:
|
||||
static void setFilterRules(const QString &rules);
|
||||
|
||||
private:
|
||||
void init(const char *category, QtMsgType severityLevel);
|
||||
|
||||
Q_DECL_UNUSED_MEMBER void *d; // reserved for future use
|
||||
const char *name;
|
||||
|
||||
@ -106,16 +110,14 @@ private:
|
||||
#define Q_DECLARE_LOGGING_CATEGORY(name) \
|
||||
extern const QLoggingCategory &name();
|
||||
|
||||
// relies on QLoggingCategory(QString) being thread safe!
|
||||
#define Q_LOGGING_CATEGORY(name, string) \
|
||||
#if defined(Q_COMPILER_VARIADIC_MACROS) || defined(Q_MOC_RUN)
|
||||
|
||||
#define Q_LOGGING_CATEGORY(name, ...) \
|
||||
const QLoggingCategory &name() \
|
||||
{ \
|
||||
static const QLoggingCategory category(string); \
|
||||
static const QLoggingCategory category(__VA_ARGS__); \
|
||||
return category; \
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_VARIADIC_MACROS
|
||||
|
||||
#define qCDebug(category, ...) \
|
||||
for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \
|
||||
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).debug(__VA_ARGS__)
|
||||
@ -126,14 +128,22 @@ private:
|
||||
for (bool qt_category_enabled = category().isCriticalEnabled(); qt_category_enabled; qt_category_enabled = false) \
|
||||
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).critical(__VA_ARGS__)
|
||||
|
||||
#else
|
||||
#else // defined(Q_COMPILER_VARIADIC_MACROS) || defined(Q_MOC_RUN)
|
||||
|
||||
// Optional msgType argument not supported
|
||||
#define Q_LOGGING_CATEGORY(name, string) \
|
||||
const QLoggingCategory &name() \
|
||||
{ \
|
||||
static const QLoggingCategory category(string); \
|
||||
return category; \
|
||||
}
|
||||
|
||||
// check for enabled category inside QMessageLogger.
|
||||
#define qCDebug qDebug
|
||||
#define qCWarning qWarning
|
||||
#define qCCritical qCritical
|
||||
|
||||
#endif // Q_COMPILER_VARIADIC_MACROS
|
||||
#endif // Q_COMPILER_VARIADIC_MACROS || defined(Q_MOC_RUN)
|
||||
|
||||
#if defined(QT_NO_DEBUG_OUTPUT)
|
||||
# undef qCDebug
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -307,12 +307,12 @@ void QLoggingRegistry::init()
|
||||
|
||||
This method might be called concurrently for the same category object.
|
||||
*/
|
||||
void QLoggingRegistry::registerCategory(QLoggingCategory *cat)
|
||||
void QLoggingRegistry::registerCategory(QLoggingCategory *cat, QtMsgType enableForLevel)
|
||||
{
|
||||
QMutexLocker locker(®istryMutex);
|
||||
|
||||
if (!categories.contains(cat)) {
|
||||
categories.append(cat);
|
||||
categories.insert(cat, enableForLevel);
|
||||
(*categoryFilter)(cat);
|
||||
}
|
||||
}
|
||||
@ -324,8 +324,7 @@ void QLoggingRegistry::registerCategory(QLoggingCategory *cat)
|
||||
void QLoggingRegistry::unregisterCategory(QLoggingCategory *cat)
|
||||
{
|
||||
QMutexLocker locker(®istryMutex);
|
||||
|
||||
categories.removeOne(cat);
|
||||
categories.remove(cat);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -361,7 +360,7 @@ void QLoggingRegistry::updateRules()
|
||||
|
||||
rules = configRules + apiRules + envRules;
|
||||
|
||||
foreach (QLoggingCategory *cat, categories)
|
||||
foreach (QLoggingCategory *cat, categories.keys())
|
||||
(*categoryFilter)(cat);
|
||||
}
|
||||
|
||||
@ -380,7 +379,7 @@ QLoggingRegistry::installFilter(QLoggingCategory::CategoryFilter filter)
|
||||
QLoggingCategory::CategoryFilter old = categoryFilter;
|
||||
categoryFilter = filter;
|
||||
|
||||
foreach (QLoggingCategory *cat, categories)
|
||||
foreach (QLoggingCategory *cat, categories.keys())
|
||||
(*categoryFilter)(cat);
|
||||
|
||||
return old;
|
||||
@ -397,18 +396,22 @@ QLoggingRegistry *QLoggingRegistry::instance()
|
||||
*/
|
||||
void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
|
||||
{
|
||||
// QLoggingCategory() normalizes "default" strings
|
||||
// to qtDefaultCategoryName
|
||||
bool debug = true;
|
||||
QLoggingRegistry *reg = QLoggingRegistry::instance();
|
||||
Q_ASSERT(reg->categories.contains(cat));
|
||||
QtMsgType enableForLevel = reg->categories.value(cat);
|
||||
|
||||
bool debug = (enableForLevel == QtDebugMsg) ? true : false;
|
||||
bool warning = (enableForLevel <= QtWarningMsg) ? true : false;
|
||||
bool critical = (enableForLevel <= QtCriticalMsg) ? true : false;
|
||||
|
||||
// hard-wired implementation of
|
||||
// qt.*.debug=false
|
||||
// qt.debug=false
|
||||
char c;
|
||||
if (!memcmp(cat->categoryName(), "qt", 2) && (!(c = cat->categoryName()[2]) || c == '.'))
|
||||
debug = false;
|
||||
|
||||
bool warning = true;
|
||||
bool critical = true;
|
||||
|
||||
QString categoryName = QLatin1String(cat->categoryName());
|
||||
QLoggingRegistry *reg = QLoggingRegistry::instance();
|
||||
foreach (const QLoggingRule &item, reg->rules) {
|
||||
int filterpass = item.pass(categoryName, QtDebugMsg);
|
||||
if (filterpass != 0)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -113,7 +113,7 @@ public:
|
||||
|
||||
void init();
|
||||
|
||||
void registerCategory(QLoggingCategory *category);
|
||||
void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel);
|
||||
void unregisterCategory(QLoggingCategory *category);
|
||||
|
||||
void setApiRules(const QString &content);
|
||||
@ -134,7 +134,7 @@ private:
|
||||
QVector<QLoggingRule> envRules;
|
||||
QVector<QLoggingRule> apiRules;
|
||||
QVector<QLoggingRule> rules;
|
||||
QList<QLoggingCategory*> categories;
|
||||
QHash<QLoggingCategory*,QtMsgType> categories;
|
||||
QLoggingCategory::CategoryFilter categoryFilter;
|
||||
|
||||
friend class ::tst_QLoggingRegistry;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
@ -44,7 +44,6 @@
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_LOGGING_CATEGORY(TST_LOG, "tst.log")
|
||||
Q_LOGGING_CATEGORY(TST_LOG1, "tst.log1")
|
||||
Q_LOGGING_CATEGORY(Digia_Oslo_Office_com, "Digia.Oslo.Office.com")
|
||||
Q_LOGGING_CATEGORY(Digia_Oulu_Office_com, "Digia.Oulu.Office.com")
|
||||
Q_LOGGING_CATEGORY(Digia_Berlin_Office_com, "Digia.Berlin.Office.com")
|
||||
@ -278,6 +277,14 @@ private slots:
|
||||
QCOMPARE(customCategory.isCriticalEnabled(), true);
|
||||
QCOMPARE(customCategory.isEnabled(QtCriticalMsg), true);
|
||||
|
||||
QLoggingCategory onlyWarningsCategory("withType", QtWarningMsg);
|
||||
QCOMPARE(onlyWarningsCategory.isDebugEnabled(), false);
|
||||
QCOMPARE(onlyWarningsCategory.isEnabled(QtDebugMsg), false);
|
||||
QCOMPARE(onlyWarningsCategory.isWarningEnabled(), true);
|
||||
QCOMPARE(onlyWarningsCategory.isEnabled(QtWarningMsg), true);
|
||||
QCOMPARE(onlyWarningsCategory.isCriticalEnabled(), true);
|
||||
QCOMPARE(onlyWarningsCategory.isEnabled(QtCriticalMsg), true);
|
||||
|
||||
// make sure nothing has printed warnings
|
||||
QVERIFY(logMessage.isEmpty());
|
||||
}
|
||||
@ -367,6 +374,35 @@ private slots:
|
||||
QCOMPARE(logMessage, buf);
|
||||
}
|
||||
|
||||
Q_LOGGING_CATEGORY(TST_MACRO_1, "tst.macro.1")
|
||||
#ifdef Q_COMPILER_VARIADIC_MACROS
|
||||
Q_LOGGING_CATEGORY(TST_MACRO_2, "tst.macro.2", QtDebugMsg)
|
||||
Q_LOGGING_CATEGORY(TST_MACRO_3, "tst.macro.3", QtFatalMsg)
|
||||
#endif
|
||||
|
||||
void QLoggingCategoryMacro()
|
||||
{
|
||||
const QLoggingCategory &cat1 = TST_MACRO_1();
|
||||
QCOMPARE(cat1.categoryName(), "tst.macro.1");
|
||||
QCOMPARE(cat1.isDebugEnabled(), true);
|
||||
QCOMPARE(cat1.isWarningEnabled(), true);
|
||||
QCOMPARE(cat1.isCriticalEnabled(), true);
|
||||
|
||||
#ifdef Q_COMPILER_VARIADIC_MACROS
|
||||
const QLoggingCategory &cat2 = TST_MACRO_2();
|
||||
QCOMPARE(cat2.categoryName(), "tst.macro.2");
|
||||
QCOMPARE(cat2.isDebugEnabled(), true);
|
||||
QCOMPARE(cat2.isWarningEnabled(), true);
|
||||
QCOMPARE(cat2.isCriticalEnabled(), true);
|
||||
|
||||
const QLoggingCategory &cat3 = TST_MACRO_3();
|
||||
QCOMPARE(cat3.categoryName(), "tst.macro.3");
|
||||
QCOMPARE(cat3.isDebugEnabled(), false);
|
||||
QCOMPARE(cat3.isWarningEnabled(), false);
|
||||
QCOMPARE(cat3.isCriticalEnabled(), false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void qCDebugMacros()
|
||||
{
|
||||
QString buf;
|
||||
|
Loading…
Reference in New Issue
Block a user