3#include <QtCore/QMutex>
4#include <QtCore/QSettings>
5#include <QtCore/QStringList>
6#include <QtQml/QJSEngine>
14static
int severityRank(
int qtMsgType)
17 case QtDebugMsg:
return 0;
18 case QtInfoMsg:
return 1;
19 case QtWarningMsg:
return 2;
20 case QtCriticalMsg:
return 3;
21 case QtFatalMsg:
return 4;
26QLoggingCategory::CategoryFilter QGCLoggingCategoryManager::s_previousFilter =
nullptr;
42 static QStringList* p =
new QStringList;
51void QGCLoggingCategoryManager::init()
67QGCLoggingCategoryManager::QGCLoggingCategoryManager() : QObject()
74 _filteredFlatModel.setSourceModel(_flatModel);
76 _filteredFlatModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
79 settings.beginGroup(kFilterRulesSettingsGroup);
80 for (
const QString& key : settings.childKeys()) {
81 const QVariant val = settings.value(key);
82 if (val.typeId() == QMetaType::Bool) {
84 _categoryLevels.insert(key, val.toBool() ? QtDebugMsg : QtWarningMsg);
86 _categoryLevels.insert(key, val.toInt());
95 registerCategory(cat);
103void QGCLoggingCategoryManager::registerCategory(
const QString& fullCategory)
105 const QStringList segments = fullCategory.split(QLatin1Char(
'.'), Qt::SkipEmptyParts);
106 if (segments.isEmpty()) {
110 const QString shortName = segments.last();
114 QReadLocker locker(&_filterLock);
115 level = _resolvedLevel(fullCategory);
122void QGCLoggingCategoryManager::setCategoryLevel(
const QString& fullCategoryName,
int qtMsgLevel)
124 qCDebug(QGCLoggingCategoryRegisterLog) <<
"Set category level" << fullCategoryName << qtMsgLevel;
126 const bool isDefault = severityRank(qtMsgLevel) >= severityRank(kDefaultLevel);
128 QWriteLocker locker(&_filterLock);
130 _categoryLevels.remove(fullCategoryName);
132 _categoryLevels.insert(fullCategoryName, qtMsgLevel);
137 settings.beginGroup(kFilterRulesSettingsGroup);
139 settings.remove(fullCategoryName);
141 settings.setValue(fullCategoryName, qtMsgLevel);
144 QLoggingCategory::installFilter(_categoryFilter);
147void QGCLoggingCategoryManager::setCategoryEnabled(
const QString& fullCategoryName,
bool enable)
149 setCategoryLevel(fullCategoryName, enable ? QtDebugMsg : kDefaultLevel);
152bool QGCLoggingCategoryManager::isCategoryEnabled(
const QString& fullCategoryName)
const
154 QReadLocker locker(&_filterLock);
155 return severityRank(_resolvedLevel(fullCategoryName)) < severityRank(kDefaultLevel);
158int QGCLoggingCategoryManager::categoryLevel(
const QString& fullCategoryName)
const
160 QReadLocker locker(&_filterLock);
161 return _resolvedLevel(fullCategoryName);
164void QGCLoggingCategoryManager::installFilter(
const QString& commandLineLoggingOptions)
166 if (!commandLineLoggingOptions.isEmpty()) {
167 const QStringList categoryList = commandLineLoggingOptions.split(
',', Qt::SkipEmptyParts);
169 QWriteLocker locker(&_filterLock);
170 if (!categoryList.isEmpty() && categoryList.first() == QStringLiteral(
"full")) {
171 _commandLineFullLogging =
true;
173 for (
const QString& category : categoryList) {
174 _commandLineCategories.insert(category.trimmed());
180 QReadLocker locker(&_filterLock);
181 for (
int i = 0; i < _flatModel->
count(); ++i) {
182 auto* item = _flatModel->
at(i);
187 s_previousFilter = QLoggingCategory::installFilter(_categoryFilter);
189 qCDebug(QGCLoggingCategoryRegisterLog) <<
"Category filter installed";
192int QGCLoggingCategoryManager::_resolvedLevel(
const QString& fullCategoryName)
const
194 if (_commandLineFullLogging) {
198 const QString normalized =
199 fullCategoryName.endsWith(
'.') ? fullCategoryName.left(fullCategoryName.size() - 1) : fullCategoryName;
201 for (
const QString& cmdCat : std::as_const(_commandLineCategories)) {
202 if (normalized == cmdCat || normalized.startsWith(cmdCat +
'.')) {
208 auto it = _categoryLevels.constFind(normalized);
209 if (it != _categoryLevels.constEnd()) {
214 for (
auto pit = _categoryLevels.constBegin(); pit != _categoryLevels.constEnd(); ++pit) {
215 if (pit.key().endsWith(
'.')) {
216 const QString prefix = pit.key().left(pit.key().size() - 1);
217 if (normalized == prefix || normalized.startsWith(prefix +
'.')) {
223 return kDefaultLevel;
226void QGCLoggingCategoryManager::_categoryFilter(QLoggingCategory* category)
228 if (s_previousFilter) {
229 s_previousFilter(category);
232 const QString categoryName = QString::fromLatin1(category->categoryName());
234 if (categoryName.startsWith(QLatin1String(
"qt."))) {
235 if (categoryName.startsWith(QLatin1String(
"qt.qml.connections"))) {
236 category->setEnabled(QtDebugMsg,
false);
237 category->setEnabled(QtWarningMsg,
false);
242 if (categoryName == QLatin1String(
"default")) {
246 auto* manager = instance();
248 QReadLocker locker(&manager->_filterLock);
249 const int rank = severityRank(manager->_resolvedLevel(categoryName));
251 category->setEnabled(QtDebugMsg, rank <= 0);
252 category->setEnabled(QtInfoMsg, rank <= 1);
253 category->setEnabled(QtWarningMsg, rank <= 2);
254 category->setEnabled(QtCriticalMsg, rank <= 3);
257void QGCLoggingCategoryManager::disableAllCategories()
259 qCDebug(QGCLoggingCategoryRegisterLog) <<
"Disabling all categories";
262 QWriteLocker locker(&_filterLock);
263 _categoryLevels.clear();
267 settings.beginGroup(kFilterRulesSettingsGroup);
268 settings.remove(QString());
270 for (
int i = 0; i < _flatModel->
count(); ++i) {
274 QLoggingCategory::installFilter(_categoryFilter);
277void QGCLoggingCategoryManager::setFilterText(
const QString& text)
279 _filteredFlatModel.setFilterFixedString(text);
287 int logLevel_, QObject* parent)
288 : QObject(parent), shortCategory(shortCategory_), fullCategory(fullCategory_), _logLevel(logLevel_)
291 if (!_updatingFromManager) {
292 QGCLoggingCategoryManager::instance()->setCategoryLevel(
fullCategory, _logLevel);
304 if (level != _logLevel) {
305 const bool wasEnabled =
enabled();
311 if (!_updatingFromManager) {
312 QGCLoggingCategoryManager::instance()->setCategoryLevel(
fullCategory, level);
319 if (level != _logLevel) {
320 const bool wasEnabled =
enabled();
321 _updatingFromManager =
true;
327 _updatingFromManager =
false;
QMutex & qgcLoggingEarlyMutex()
static QGCLoggingCategoryManager * s_managerInstance
QStringList *& qgcLoggingEarlyPending()
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void insertSorted(QGCLoggingCategoryItem *item)
QGCLoggingCategoryItem * at(int i) const
void insertCategory(const QStringList &pathSegments, const QString &fullCategory, QGCLoggingCategoryItem *item)
QGCLoggingCategoryItem(const QString &shortCategory_, const QString &fullCategory_, int logLevel_, QObject *parent=nullptr)
void setEnabled(bool enabled)
void setLogLevelFromManager(int level)
void setLogLevel(int level)