second take on using Qt logging filters
This commit is contained in:
parent
ed24c08528
commit
4d704a3f5c
161
server/main.cpp
161
server/main.cpp
@ -43,7 +43,6 @@
|
|||||||
#include "nymeaapplication.h"
|
#include "nymeaapplication.h"
|
||||||
#include "loggingcategories.h"
|
#include "loggingcategories.h"
|
||||||
|
|
||||||
static QHash<QString, bool> s_loggingFilters;
|
|
||||||
static QFile s_logFile;
|
static QFile s_logFile;
|
||||||
|
|
||||||
static const char *const normal = "\033[0m";
|
static const char *const normal = "\033[0m";
|
||||||
@ -52,18 +51,6 @@ static const char *const error = "\e[31m";
|
|||||||
|
|
||||||
using namespace nymeaserver;
|
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)
|
static void consoleLogHandler(QtMsgType type, const QMessageLogContext& context, const QString& message)
|
||||||
{
|
{
|
||||||
QString messageString;
|
QString messageString;
|
||||||
@ -110,43 +97,45 @@ int main(int argc, char *argv[])
|
|||||||
application.setApplicationVersion(NYMEA_VERSION_STRING);
|
application.setApplicationVersion(NYMEA_VERSION_STRING);
|
||||||
|
|
||||||
// logging filers for core and libnymea
|
// logging filers for core and libnymea
|
||||||
s_loggingFilters.insert("Application", true);
|
QStringList loggingFilters = {
|
||||||
s_loggingFilters.insert("Warnings", true);
|
"Application",
|
||||||
s_loggingFilters.insert("DeviceManager", true);
|
"Warnings",
|
||||||
s_loggingFilters.insert("RuleEngine", true);
|
"DeviceManager",
|
||||||
s_loggingFilters.insert("RuleEngineDebug", false);
|
"RuleEngine",
|
||||||
s_loggingFilters.insert("Hardware", false);
|
"RuleEngineDebug",
|
||||||
s_loggingFilters.insert("Bluetooth", false);
|
"Hardware",
|
||||||
s_loggingFilters.insert("Connection", true);
|
"Bluetooth",
|
||||||
s_loggingFilters.insert("LogEngine", false);
|
"Connection",
|
||||||
s_loggingFilters.insert("TcpServer", false);
|
"LogEngine",
|
||||||
s_loggingFilters.insert("TcpServerTraffic", false);
|
"TcpServer",
|
||||||
s_loggingFilters.insert("WebServer", false);
|
"TcpServerTraffic",
|
||||||
s_loggingFilters.insert("WebSocketServer", false);
|
"WebServer",
|
||||||
s_loggingFilters.insert("WebSocketServerTraffic", false);
|
"WebSocketServer",
|
||||||
s_loggingFilters.insert("JsonRpc", false);
|
"WebSocketServerTraffic",
|
||||||
s_loggingFilters.insert("JsonRpcTraffic", false);
|
"JsonRpc",
|
||||||
s_loggingFilters.insert("Rest", false);
|
"JsonRpcTraffic",
|
||||||
s_loggingFilters.insert("OAuth2", false);
|
"Rest",
|
||||||
s_loggingFilters.insert("TimeManager", false);
|
"OAuth2",
|
||||||
s_loggingFilters.insert("Coap", false);
|
"TimeManager",
|
||||||
s_loggingFilters.insert("Avahi", false);
|
"Coap",
|
||||||
s_loggingFilters.insert("UPnP", false);
|
"Avahi",
|
||||||
s_loggingFilters.insert("Cloud", true);
|
"UPnP",
|
||||||
s_loggingFilters.insert("CloudTraffic", false);
|
"Cloud",
|
||||||
s_loggingFilters.insert("NetworkManager", false);
|
"CloudTraffic",
|
||||||
s_loggingFilters.insert("UserManager", true);
|
"NetworkManager",
|
||||||
s_loggingFilters.insert("AWS", false);
|
"UserManager",
|
||||||
s_loggingFilters.insert("AWSTraffic", false);
|
"AWS",
|
||||||
s_loggingFilters.insert("Janus", false);
|
"AWSTraffic",
|
||||||
s_loggingFilters.insert("JanusTraffic", false);
|
"Janus",
|
||||||
s_loggingFilters.insert("BluetoothServer", true);
|
"JanusTraffic",
|
||||||
s_loggingFilters.insert("BluetoothServerTraffic", false);
|
"BluetoothServer",
|
||||||
|
"BluetoothServerTraffic"
|
||||||
|
};
|
||||||
|
|
||||||
QHash<QString, bool> loggingFiltersPlugins;
|
QStringList loggingFiltersPlugins;
|
||||||
foreach (const QJsonObject &pluginMetadata, DeviceManager::pluginsMetadata()) {
|
foreach (const QJsonObject &pluginMetadata, DeviceManager::pluginsMetadata()) {
|
||||||
QString pluginName = pluginMetadata.value("name").toString();
|
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
|
// Translator for the server application
|
||||||
@ -164,10 +153,10 @@ int main(int argc, char *argv[])
|
|||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
parser.addVersionOption();
|
parser.addVersionOption();
|
||||||
QString applicationDescription = QCoreApplication::translate("nymea", "\nnymea is an open source IoT (Internet of Things) server, \n"
|
QString applicationDescription = QCoreApplication::translate("nymea", "\nnymea is an open source IoT (Internet of Things) server, \n"
|
||||||
"which allows to control a lot of different devices from many different \n"
|
"which allows to control a lot of different devices from many different \n"
|
||||||
"manufacturers. With the powerful rule engine you are able to connect any \n"
|
"manufacturers. With the powerful rule engine you are able to connect any \n"
|
||||||
"device available in the system and create individual scenes and behaviors \n"
|
"device available in the system and create individual scenes and behaviors \n"
|
||||||
"for your environment.\n\n");
|
"for your environment.\n\n");
|
||||||
|
|
||||||
applicationDescription.append(QString("nymead %1 %2 2014-2018 guh GmbH\n"
|
applicationDescription.append(QString("nymead %1 %2 2014-2018 guh GmbH\n"
|
||||||
"Released under the GNU GENERAL PUBLIC LICENSE Version 2.\n\n"
|
"Released under the GNU GENERAL PUBLIC LICENSE Version 2.\n\n"
|
||||||
@ -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."));
|
QCommandLineOption foregroundOption(QStringList() << "n" << "no-daemon", QCoreApplication::translate("nymea", "Run nymead in the foreground, not as daemon."));
|
||||||
parser.addOption(foregroundOption);
|
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
|
loggingFilters.sort();
|
||||||
QStringList sortedFilterList = QStringList(s_loggingFilters.keys());
|
foreach (const QString &filterName, loggingFilters)
|
||||||
sortedFilterList.sort();
|
debugDescription += "\n- " + filterName;
|
||||||
foreach (const QString &filterName, sortedFilterList)
|
|
||||||
debugDescription += "\n- " + filterName + " (" + (s_loggingFilters.value(filterName) ? "yes" : "no") + ")";
|
|
||||||
|
|
||||||
|
|
||||||
// create sorted plugin loggingFiler list
|
loggingFiltersPlugins.sort();
|
||||||
QStringList sortedPluginList = QStringList(loggingFiltersPlugins.keys());
|
|
||||||
sortedPluginList.sort();
|
|
||||||
debugDescription += "\n\nPlugin categories:\n";
|
debugDescription += "\n\nPlugin categories:\n";
|
||||||
foreach (const QString &filterName, sortedPluginList)
|
foreach (const QString &filterName, loggingFiltersPlugins)
|
||||||
debugDescription += "\n- " + filterName + " (" + (s_loggingFilters.value(filterName) ? "yes" : "no") + ")";
|
debugDescription += "\n- " + filterName;
|
||||||
|
|
||||||
|
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."));
|
||||||
QCommandLineOption allOption(QStringList() << "p" << "print-all", QCoreApplication::translate("nymea", "Enables all debug categories. Single debug categories can be disabled again with -d parameter."));
|
|
||||||
parser.addOption(allOption);
|
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");
|
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."));
|
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);
|
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.addOption(debugOption);
|
||||||
|
|
||||||
parser.process(application);
|
parser.process(application);
|
||||||
@ -224,27 +208,28 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add plugin metadata to the static hash
|
QStringList filterRules;
|
||||||
foreach (const QString &category, loggingFiltersPlugins.keys())
|
|
||||||
s_loggingFilters.insert(category, false);
|
|
||||||
|
|
||||||
// check debug area
|
|
||||||
if (parser.isSet(allOption)) {
|
if (parser.isSet(allOption)) {
|
||||||
foreach (const QString &debugArea, s_loggingFilters.keys()) {
|
filterRules << "*.debug=true";
|
||||||
s_loggingFilters[debugArea] = true;
|
filterRules << "*Traffic.debug=false";
|
||||||
}
|
filterRules << "*Debug.debug=false";
|
||||||
|
} else {
|
||||||
|
filterRules << "*.debug=false";
|
||||||
}
|
}
|
||||||
|
|
||||||
// And allow overriding individual values
|
// And allow overriding individual values
|
||||||
foreach (QString debugArea, parser.values(debugOption)) {
|
foreach (QString debugArea, parser.values(debugOption)) {
|
||||||
bool enable = !debugArea.startsWith("No");
|
bool enable = !debugArea.startsWith("No");
|
||||||
|
bool isWarning = debugArea.endsWith("Warnings");
|
||||||
debugArea.remove(QRegExp("^No"));
|
debugArea.remove(QRegExp("^No"));
|
||||||
if (s_loggingFilters.contains(debugArea)) {
|
debugArea.remove(QRegExp("Warnings$"));
|
||||||
s_loggingFilters[debugArea] = enable;
|
if (loggingFilters.contains(debugArea) || loggingFiltersPlugins.contains(debugArea)) {
|
||||||
|
filterRules.append(QString("%1.%2=%3").arg(debugArea).arg(isWarning ? "warning" : "debug").arg(enable ? "true": "false"));
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcApplication) << QCoreApplication::translate("nymea", "No such debug category:") << debugArea;
|
qCWarning(dcApplication) << QCoreApplication::translate("nymea", "No such debug category:") << debugArea;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QLoggingCategory::installFilter(loggingCategoryFilter);
|
QLoggingCategory::setFilterRules(filterRules.join('\n'));
|
||||||
|
|
||||||
if (parser.isSet(dbusOption)) {
|
if (parser.isSet(dbusOption)) {
|
||||||
NymeaDBusService::setBusType(QDBusConnection::SessionBus);
|
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()));
|
fprintf(stdout, "Could not create nymea settings directory %s", qPrintable(NymeaSettings::settingsPath()));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
qCDebug(dcApplication) << "=====================================";
|
qCInfo(dcApplication) << "=====================================";
|
||||||
qCDebug(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started with user ID" << userId;
|
qCInfo(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started with user ID" << userId;
|
||||||
qCDebug(dcApplication) << "=====================================";
|
qCInfo(dcApplication) << "=====================================";
|
||||||
} else {
|
} else {
|
||||||
qCDebug(dcApplication) << "=====================================";
|
qCInfo(dcApplication) << "=====================================";
|
||||||
qCDebug(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started as root.";
|
qCInfo(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started as root.";
|
||||||
qCDebug(dcApplication) << "=====================================";
|
qCInfo(dcApplication) << "=====================================";
|
||||||
}
|
}
|
||||||
|
|
||||||
// If running in a snappy environment, print out some details about it.
|
// If running in a snappy environment, print out some details about it.
|
||||||
if (!qgetenv("SNAP").isEmpty()) {
|
if (!qgetenv("SNAP").isEmpty()) {
|
||||||
// Note: http://snapcraft.io/docs/reference/env
|
// Note: http://snapcraft.io/docs/reference/env
|
||||||
qCDebug(dcApplication) << "Snap name :" << qgetenv("SNAP_NAME");
|
qCInfo(dcApplication) << "Snap name :" << qgetenv("SNAP_NAME");
|
||||||
qCDebug(dcApplication) << "Snap version :" << qgetenv("SNAP_VERSION");
|
qCInfo(dcApplication) << "Snap version :" << qgetenv("SNAP_VERSION");
|
||||||
qCDebug(dcApplication) << "Snap directory :" << qgetenv("SNAP");
|
qCInfo(dcApplication) << "Snap directory :" << qgetenv("SNAP");
|
||||||
qCDebug(dcApplication) << "Snap app data :" << qgetenv("SNAP_DATA");
|
qCInfo(dcApplication) << "Snap app data :" << qgetenv("SNAP_DATA");
|
||||||
qCDebug(dcApplication) << "Snap user data :" << qgetenv("SNAP_USER_DATA");
|
qCInfo(dcApplication) << "Snap user data :" << qgetenv("SNAP_USER_DATA");
|
||||||
qCDebug(dcApplication) << "Snap app common :" << qgetenv("SNAP_COMMON");
|
qCInfo(dcApplication) << "Snap app common :" << qgetenv("SNAP_COMMON");
|
||||||
}
|
}
|
||||||
|
|
||||||
// create core instance
|
// create core instance
|
||||||
|
|||||||
@ -142,7 +142,7 @@ static void catchUnixSignals(const std::vector<int>& quitSignals, const std::vec
|
|||||||
qCDebug(dcApplication) << "Cought SIGHUP quit signal...";
|
qCDebug(dcApplication) << "Cought SIGHUP quit signal...";
|
||||||
break;
|
break;
|
||||||
case SIGSEGV: {
|
case SIGSEGV: {
|
||||||
qCDebug(dcApplication) << "Cought SIGSEGV signal. Segmentation fault!";
|
qCWarning(dcApplication) << "Cought SIGSEGV signal. Segmentation fault!";
|
||||||
printBacktrace();
|
printBacktrace();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -185,9 +185,9 @@ static void catchUnixSignals(const std::vector<int>& quitSignals, const std::vec
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcApplication) << "=====================================";
|
qCInfo(dcApplication) << "=====================================";
|
||||||
qCDebug(dcApplication) << "Shutting down nymea daemon";
|
qCInfo(dcApplication) << "Shutting down nymea daemon";
|
||||||
qCDebug(dcApplication) << "=====================================";
|
qCInfo(dcApplication) << "=====================================";
|
||||||
|
|
||||||
s_aboutToShutdown = true;
|
s_aboutToShutdown = true;
|
||||||
NymeaCore::instance()->destroy();
|
NymeaCore::instance()->destroy();
|
||||||
|
|||||||
Reference in New Issue
Block a user