QLoggingRegistry: add the ability to have environment variable overrides

Quite a lot of our code in Qt predating QLoggingCategory has manual
environment variable controls. For compatibility with established
documentation and tips-and-tricks out there, we should keep them working
when switching to categorized logging.

Change-Id: I3eb1bd30e0124f89a052fffd16a6c151d3e9d552
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Thiago Macieira 2021-09-20 23:07:52 -07:00
parent 0c0892a3e2
commit 806545fcc8
2 changed files with 56 additions and 1 deletions

View File

@ -370,6 +370,20 @@ void QLoggingRegistry::unregisterCategory(QLoggingCategory *cat)
categories.remove(cat);
}
/*!
\since 6.3
\internal
Registers the environment variable \a environment as the control variable
for enabling debugging by default for category \a categoryName. The
category name must start with "qt."
*/
void QLoggingRegistry::registerEnvironmentOverrideForCategory(QByteArrayView categoryName,
QByteArrayView environment)
{
qtCategoryEnvironmentOverrides.insert(categoryName, environment);
}
/*!
\internal
Installs logging rules as specified in \a content.
@ -451,8 +465,16 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
// qt.debug=false
if (const char *categoryName = cat->categoryName()) {
// == "qt" or startsWith("qt.")
if (strcmp(categoryName, "qt") == 0 || strncmp(categoryName, "qt.", 3) == 0)
if (strcmp(categoryName, "qt") == 0) {
debug = false;
} else if (strncmp(categoryName, "qt.", 3) == 0) {
// may be overridden
auto it = reg->qtCategoryEnvironmentOverrides.find(categoryName);
if (it == reg->qtCategoryEnvironmentOverrides.end())
debug = false;
else
debug = qEnvironmentVariableIntValue(it.value().data());
}
}
const auto categoryName = QLatin1String(cat->categoryName());

View File

@ -63,6 +63,16 @@ class tst_QLoggingRegistry;
QT_BEGIN_NAMESPACE
#define Q_LOGGING_CATEGORY_WITH_ENV_OVERRIDE(name, env, categoryName) \
const QLoggingCategory &name() \
{ \
static constexpr char cname[] = categoryName; \
static_assert(cname[0] == 'q' && cname[1] == 't' && cname[2] == '.' \
&& cname[4] != '\0', "Category name must start with 'qt.'"); \
static const QLoggingCategoryWithEnvironmentOverride category(cname, env); \
return category; \
}
class Q_AUTOTEST_EXPORT QLoggingRule
{
public:
@ -118,6 +128,11 @@ public:
void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel);
void unregisterCategory(QLoggingCategory *category);
#ifndef QT_BUILD_INTERNAL
Q_CORE_EXPORT // always export from QtCore
#endif
void registerEnvironmentOverrideForCategory(QByteArrayView categoryName, QByteArrayView environment);
void setApiRules(const QString &content);
QLoggingCategory::CategoryFilter
@ -146,10 +161,28 @@ private:
QList<QLoggingRule> ruleSets[NumRuleSets];
QHash<QLoggingCategory *, QtMsgType> categories;
QLoggingCategory::CategoryFilter categoryFilter;
QMap<QByteArrayView, QByteArrayView> qtCategoryEnvironmentOverrides;
friend class ::tst_QLoggingRegistry;
};
class QLoggingCategoryWithEnvironmentOverride : public QLoggingCategory
{
public:
QLoggingCategoryWithEnvironmentOverride(const char *category, const char *env)
: QLoggingCategory(registerOverride(category, env), QtInfoMsg)
{}
private:
static const char *registerOverride(QByteArrayView categoryName, QByteArrayView environment)
{
QLoggingRegistry *c = QLoggingRegistry::instance();
if (c)
c->registerEnvironmentOverrideForCategory(categoryName, environment);
return categoryName.data();
}
};
QT_END_NAMESPACE
#endif // QLOGGINGREGISTRY_P_H