second take on using Qt logging filters

pull/135/head
Michael Zanetti 2018-09-27 01:50:10 +02:00
parent ed24c08528
commit 4d704a3f5c
2 changed files with 77 additions and 92 deletions

View File

@ -43,7 +43,6 @@
#include "nymeaapplication.h"
#include "loggingcategories.h"
static QHash<QString, bool> s_loggingFilters;
static QFile s_logFile;
static const char *const normal = "\033[0m";
@ -52,18 +51,6 @@ static const char *const error = "\e[31m";
using namespace nymeaserver;
static void loggingCategoryFilter(QLoggingCategory *category)
{
if (s_loggingFilters.contains(category->categoryName())) {
bool debugEnabled = s_loggingFilters.value(category->categoryName());
category->setEnabled(QtDebugMsg, debugEnabled);
category->setEnabled(QtWarningMsg, debugEnabled || s_loggingFilters.value("Warnings"));
} else {
category->setEnabled(QtDebugMsg, false);
category->setEnabled(QtWarningMsg, s_loggingFilters.value("qml") || s_loggingFilters.value("Warnings"));
}
}
static void consoleLogHandler(QtMsgType type, const QMessageLogContext& context, const QString& message)
{
QString messageString;
@ -110,43 +97,45 @@ int main(int argc, char *argv[])
application.setApplicationVersion(NYMEA_VERSION_STRING);
// logging filers for core and libnymea
s_loggingFilters.insert("Application", true);
s_loggingFilters.insert("Warnings", true);
s_loggingFilters.insert("DeviceManager", true);
s_loggingFilters.insert("RuleEngine", true);
s_loggingFilters.insert("RuleEngineDebug", false);
s_loggingFilters.insert("Hardware", false);
s_loggingFilters.insert("Bluetooth", false);
s_loggingFilters.insert("Connection", true);
s_loggingFilters.insert("LogEngine", false);
s_loggingFilters.insert("TcpServer", false);
s_loggingFilters.insert("TcpServerTraffic", false);
s_loggingFilters.insert("WebServer", false);
s_loggingFilters.insert("WebSocketServer", false);
s_loggingFilters.insert("WebSocketServerTraffic", false);
s_loggingFilters.insert("JsonRpc", false);
s_loggingFilters.insert("JsonRpcTraffic", false);
s_loggingFilters.insert("Rest", false);
s_loggingFilters.insert("OAuth2", false);
s_loggingFilters.insert("TimeManager", false);
s_loggingFilters.insert("Coap", false);
s_loggingFilters.insert("Avahi", false);
s_loggingFilters.insert("UPnP", false);
s_loggingFilters.insert("Cloud", true);
s_loggingFilters.insert("CloudTraffic", false);
s_loggingFilters.insert("NetworkManager", false);
s_loggingFilters.insert("UserManager", true);
s_loggingFilters.insert("AWS", false);
s_loggingFilters.insert("AWSTraffic", false);
s_loggingFilters.insert("Janus", false);
s_loggingFilters.insert("JanusTraffic", false);
s_loggingFilters.insert("BluetoothServer", true);
s_loggingFilters.insert("BluetoothServerTraffic", false);
QStringList loggingFilters = {
"Application",
"Warnings",
"DeviceManager",
"RuleEngine",
"RuleEngineDebug",
"Hardware",
"Bluetooth",
"Connection",
"LogEngine",
"TcpServer",
"TcpServerTraffic",
"WebServer",
"WebSocketServer",
"WebSocketServerTraffic",
"JsonRpc",
"JsonRpcTraffic",
"Rest",
"OAuth2",
"TimeManager",
"Coap",
"Avahi",
"UPnP",
"Cloud",
"CloudTraffic",
"NetworkManager",
"UserManager",
"AWS",
"AWSTraffic",
"Janus",
"JanusTraffic",
"BluetoothServer",
"BluetoothServerTraffic"
};
QHash<QString, bool> loggingFiltersPlugins;
QStringList loggingFiltersPlugins;
foreach (const QJsonObject &pluginMetadata, DeviceManager::pluginsMetadata()) {
QString pluginName = pluginMetadata.value("name").toString();
loggingFiltersPlugins.insert(pluginName.left(1).toUpper() + pluginName.mid(1), false);
loggingFiltersPlugins << pluginName.left(1).toUpper() + pluginName.mid(1);
}
// Translator for the server application
@ -178,24 +167,19 @@ int main(int argc, char *argv[])
QCommandLineOption foregroundOption(QStringList() << "n" << "no-daemon", QCoreApplication::translate("nymea", "Run nymead in the foreground, not as daemon."));
parser.addOption(foregroundOption);
QString debugDescription = QCoreApplication::translate("nymea", "Debug categories to enable. Prefix with \"No\" to disable. Warnings from all categories will be printed unless explicitly muted with \"NoWarnings\". \n\nCategories are:");
QString debugDescription = QCoreApplication::translate("nymea", "Debug categories to enable. Prefix with \"No\" to disable. Suffix with \"Warnings\" to address warnings.\nExamples:\n-d AWSTraffic\n-d NoDeviceManager\n-d NoBluetoothWarnings\n\nCategories are:");
// create sorted loggingFiler list
QStringList sortedFilterList = QStringList(s_loggingFilters.keys());
sortedFilterList.sort();
foreach (const QString &filterName, sortedFilterList)
debugDescription += "\n- " + filterName + " (" + (s_loggingFilters.value(filterName) ? "yes" : "no") + ")";
loggingFilters.sort();
foreach (const QString &filterName, loggingFilters)
debugDescription += "\n- " + filterName;
// create sorted plugin loggingFiler list
QStringList sortedPluginList = QStringList(loggingFiltersPlugins.keys());
sortedPluginList.sort();
loggingFiltersPlugins.sort();
debugDescription += "\n\nPlugin categories:\n";
foreach (const QString &filterName, sortedPluginList)
debugDescription += "\n- " + filterName + " (" + (s_loggingFilters.value(filterName) ? "yes" : "no") + ")";
foreach (const QString &filterName, loggingFiltersPlugins)
debugDescription += "\n- " + filterName;
QCommandLineOption allOption(QStringList() << "p" << "print-all", QCoreApplication::translate("nymea", "Enables all debug categories. Single debug categories can be disabled again with -d parameter."));
QCommandLineOption allOption(QStringList() << "p" << "print-all", QCoreApplication::translate("nymea", "Enables all debug categories except *Traffic and *Debug categories. Single debug categories can be disabled again with -d parameter."));
parser.addOption(allOption);
QCommandLineOption logOption({"l", "log"}, QCoreApplication::translate("nymea", "Specify a log file to write to, if this option is not specified, logs will be printed to the standard output."), "logfile", "/var/log/nymead.log");
@ -204,7 +188,7 @@ int main(int argc, char *argv[])
QCommandLineOption dbusOption(QStringList() << "session", QCoreApplication::translate("nymea", "If specified, all D-Bus interfaces will be bound to the session bus instead of the system bus."));
parser.addOption(dbusOption);
QCommandLineOption debugOption(QStringList() << "d" << "debug-category", debugDescription, "[No]DebugCategory");
QCommandLineOption debugOption(QStringList() << "d" << "debug-category", debugDescription, "[No]DebugCategory[Warnings]");
parser.addOption(debugOption);
parser.process(application);
@ -224,27 +208,28 @@ int main(int argc, char *argv[])
}
}
// add plugin metadata to the static hash
foreach (const QString &category, loggingFiltersPlugins.keys())
s_loggingFilters.insert(category, false);
// check debug area
QStringList filterRules;
if (parser.isSet(allOption)) {
foreach (const QString &debugArea, s_loggingFilters.keys()) {
s_loggingFilters[debugArea] = true;
}
filterRules << "*.debug=true";
filterRules << "*Traffic.debug=false";
filterRules << "*Debug.debug=false";
} else {
filterRules << "*.debug=false";
}
// And allow overriding individual values
foreach (QString debugArea, parser.values(debugOption)) {
bool enable = !debugArea.startsWith("No");
bool isWarning = debugArea.endsWith("Warnings");
debugArea.remove(QRegExp("^No"));
if (s_loggingFilters.contains(debugArea)) {
s_loggingFilters[debugArea] = enable;
debugArea.remove(QRegExp("Warnings$"));
if (loggingFilters.contains(debugArea) || loggingFiltersPlugins.contains(debugArea)) {
filterRules.append(QString("%1.%2=%3").arg(debugArea).arg(isWarning ? "warning" : "debug").arg(enable ? "true": "false"));
} else {
qCWarning(dcApplication) << QCoreApplication::translate("nymea", "No such debug category:") << debugArea;
}
}
QLoggingCategory::installFilter(loggingCategoryFilter);
QLoggingCategory::setFilterRules(filterRules.join('\n'));
if (parser.isSet(dbusOption)) {
NymeaDBusService::setBusType(QDBusConnection::SessionBus);
@ -260,24 +245,24 @@ int main(int argc, char *argv[])
fprintf(stdout, "Could not create nymea settings directory %s", qPrintable(NymeaSettings::settingsPath()));
exit(EXIT_FAILURE);
}
qCDebug(dcApplication) << "=====================================";
qCDebug(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started with user ID" << userId;
qCDebug(dcApplication) << "=====================================";
qCInfo(dcApplication) << "=====================================";
qCInfo(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started with user ID" << userId;
qCInfo(dcApplication) << "=====================================";
} else {
qCDebug(dcApplication) << "=====================================";
qCDebug(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started as root.";
qCDebug(dcApplication) << "=====================================";
qCInfo(dcApplication) << "=====================================";
qCInfo(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started as root.";
qCInfo(dcApplication) << "=====================================";
}
// If running in a snappy environment, print out some details about it.
if (!qgetenv("SNAP").isEmpty()) {
// Note: http://snapcraft.io/docs/reference/env
qCDebug(dcApplication) << "Snap name :" << qgetenv("SNAP_NAME");
qCDebug(dcApplication) << "Snap version :" << qgetenv("SNAP_VERSION");
qCDebug(dcApplication) << "Snap directory :" << qgetenv("SNAP");
qCDebug(dcApplication) << "Snap app data :" << qgetenv("SNAP_DATA");
qCDebug(dcApplication) << "Snap user data :" << qgetenv("SNAP_USER_DATA");
qCDebug(dcApplication) << "Snap app common :" << qgetenv("SNAP_COMMON");
qCInfo(dcApplication) << "Snap name :" << qgetenv("SNAP_NAME");
qCInfo(dcApplication) << "Snap version :" << qgetenv("SNAP_VERSION");
qCInfo(dcApplication) << "Snap directory :" << qgetenv("SNAP");
qCInfo(dcApplication) << "Snap app data :" << qgetenv("SNAP_DATA");
qCInfo(dcApplication) << "Snap user data :" << qgetenv("SNAP_USER_DATA");
qCInfo(dcApplication) << "Snap app common :" << qgetenv("SNAP_COMMON");
}
// create core instance

View File

@ -142,7 +142,7 @@ static void catchUnixSignals(const std::vector<int>& quitSignals, const std::vec
qCDebug(dcApplication) << "Cought SIGHUP quit signal...";
break;
case SIGSEGV: {
qCDebug(dcApplication) << "Cought SIGSEGV signal. Segmentation fault!";
qCWarning(dcApplication) << "Cought SIGSEGV signal. Segmentation fault!";
printBacktrace();
exit(1);
}
@ -185,9 +185,9 @@ static void catchUnixSignals(const std::vector<int>& quitSignals, const std::vec
return;
}
qCDebug(dcApplication) << "=====================================";
qCDebug(dcApplication) << "Shutting down nymea daemon";
qCDebug(dcApplication) << "=====================================";
qCInfo(dcApplication) << "=====================================";
qCInfo(dcApplication) << "Shutting down nymea daemon";
qCInfo(dcApplication) << "=====================================";
s_aboutToShutdown = true;
NymeaCore::instance()->destroy();