Load debug categories from settings and allow configuration using debug interface

pull/218/head
Simon Stürz 2019-10-07 18:22:25 +02:00
parent b4f32c073a
commit 191936e235
6 changed files with 161 additions and 27 deletions

View File

@ -92,7 +92,6 @@ function connectWebsocket() {
} catch (exception) {
console.error(exception);
}
}
@ -127,6 +126,65 @@ function copyLogsContent() {
}
function loadLoggingCategorySettings() {
// Request report file generation
var request = new XMLHttpRequest();
request.open("GET", "/debug/logging-categories", true);
request.send(null);
request.onreadystatechange = function() {
if (request.readyState == 4) {
console.log("Load logging category settings finished", request.status);
/* Check if the generation went fine */
if (request.status != 200) {
console.warn("Could not load logging category settings", request.status);
return;
}
console.log(request.responseText);
var responseMap = JSON.parse(request.responseText);
for (var loggingCategory in responseMap['loggingCategories']) {
console.warn(loggingCategory, responseMap['loggingCategories'][loggingCategory])
var loggingCategoryElement = document.getElementById("debug-category-" + loggingCategory)
loggingCategoryElement.checked = responseMap['loggingCategories'][loggingCategory]
}
for (var loggingCategory in responseMap['loggingCategoriesPlugins']) {
console.warn(loggingCategory, responseMap['loggingCategoriesPlugins'][loggingCategory])
var loggingCategoryElement = document.getElementById("debug-category-" + loggingCategory)
loggingCategoryElement.checked = responseMap['loggingCategoriesPlugins'][loggingCategory]
}
}
}
}
function toggleLoggingCategory(categoryName) {
var switchElement = document.getElementById("debug-category-" + categoryName)
console.log("Toggle logging category", categoryName, switchElement.checked)
var fileRequestUrl = "/debug/logging-categories?" + categoryName + "=" + (switchElement.checked ? "true" : "false");
// Request report file generation
var request = new XMLHttpRequest();
request.open("GET", fileRequestUrl, true);
request.send(null);
request.onreadystatechange = function() {
if (request.readyState == 4) {
console.log("Set logging category settings finished", request.status);
/* Check if the generation went fine */
if (request.status != 200) {
console.warn("Could not set logging category settings", request.status);
return;
}
}
}
}
/* ========================================================================*/
/* File download / show functions
@ -175,7 +233,7 @@ function pollReportResult() {
/* Check if the generation went fine */
if (reportGenerateRequest.status != 200) {
console.log("Report generation finished with error.");
console.warn("Report generation finished with error.");
clearTimeout(generateReportTimer);
textArea.value = "Something went wrong :(" + reportGenerateRequest.status;
button.disabled = false;
@ -366,5 +424,6 @@ function tracePathTimerTimeout() {
window.onload = function() {
console.log("Window loading finished.");
document.getElementById("informationTabButton").click();
loadLoggingCategorySettings();
};

View File

@ -71,6 +71,7 @@ textarea {
min-height: 100px;
text-align: left;
border-radius: 10px;
outline: none;
}
.tab {
@ -273,12 +274,12 @@ button::-moz-focus-inner { border: 0; }
justify-content: center;
align-items: center;
margin: 10px;
width: 25%;
width: 30%;
}
.debug-category p {
margin: 10px;
text-align: left;
text-align: right;
flex-grow: 1;
}
@ -357,8 +358,6 @@ input:checked + .slider:before {
border-radius: 50%;
}
.container {
min-height: 100%;
position:relative;

View File

@ -5,8 +5,7 @@ After=network.target
Wants=network-online.target
[Service]
Environment=QT_LOGGING_CONF=/etc/nymea/logging.conf
ExecStart=/usr/bin/nymead -n --print-all
ExecStart=/usr/bin/nymead -n
StandardOutput=journal
StandardError=journal
Restart=on-failure

View File

@ -5,4 +5,3 @@ usr/lib/@DEB_HOST_MULTIARCH@/libnymea-core.so.1.0.0
data/systemd/nymead.service /lib/systemd/system/
data/logrotate/nymead /etc/logrotate.d/
data/dbus-1/io.guh.nymead.conf /etc/dbus-1/system.d/
data/config/logging.conf /etc/nymea/

View File

@ -379,6 +379,61 @@ HttpReply *DebugServerHandler::processDebugRequest(const QString &requestPath, c
return m_tracePathReply;
}
if (requestPath.startsWith("/debug/logging-categories")) {
if (requestQuery.isEmpty()) {
// Return the list of debug category settings
NymeaSettings settings(NymeaSettings::SettingsRoleGlobal);
settings.beginGroup("LoggingRules");
qCDebug(dcDebugServer()) << "Request logging categories list";
QVariantMap dataMap;
QVariantMap loggingCategories;
foreach (const QString &loggingCategory, NymeaCore::loggingFilters()) {
loggingCategories.insert(loggingCategory, settings.value(QString("%1.debug").arg(loggingCategory), false).toBool());
}
dataMap.insert("loggingCategories", loggingCategories);
QVariantMap loggingCategoriesPlugins;
foreach (const QString &loggingCategory, NymeaCore::loggingFiltersPlugins()) {
loggingCategoriesPlugins.insert(loggingCategory, settings.value(QString("%1.debug").arg(loggingCategory), false).toBool());
}
dataMap.insert("loggingCategoriesPlugins", loggingCategoriesPlugins);
settings.endGroup();
HttpReply *reply = RestResource::createSuccessReply();
reply->setPayload(QJsonDocument::fromVariant(dataMap).toJson(QJsonDocument::Indented));
return reply;
} else {
NymeaSettings settings(NymeaSettings::SettingsRoleGlobal);
settings.beginGroup("LoggingRules");
for (int i = 0; i < requestQuery.queryItems().count(); i++) {
QString category = requestQuery.queryItems().at(i).first;
if (!NymeaCore::loggingFilters().contains(category) && !NymeaCore::loggingFiltersPlugins().contains(category)) {
qCWarning(dcDebugServer()) << "Invalid logging category in request query" << requestQuery.toString() << category;
continue;
}
bool enabled = QVariant(requestQuery.queryItems().at(i).second).toBool();
qCDebug(dcDebugServer()) << "Category" << category << enabled;
settings.setValue(QString("%1.debug").arg(category), (enabled ? "true" : "false"));
}
// Update logging filter rules according to the nw settings
QStringList loggingRules;
loggingRules << "*.debug=false";
// Load the rules from nymead.conf file and append them to the rules
foreach (const QString &category, settings.childKeys()) {
loggingRules << QString("%1=%2").arg(category).arg(settings.value(category, "false").toString());
}
settings.endGroup();
QLoggingCategory::setFilterRules(loggingRules.join('\n'));
return RestResource::createSuccessReply();
}
}
if (requestPath.startsWith("/debug/report")) {
// The client can poll this url in order to get information about the current report generating process.
@ -562,12 +617,10 @@ void DebugServerHandler::onWebsocketClientConnected()
if (s_websocketClients.isEmpty()) {
qCDebug(dcDebugServer()) << "Install debug message handler for live logs.";
//QLoggingCategory::setFilterRules("*.debug=true");
s_oldLogMessageHandler = qInstallMessageHandler(&logMessageHandler);
}
// Enable the log categories depending on the current debug configuration
s_websocketClients.append(client);
qCDebug(dcDebugServer()) << "New websocket client connected:" << client->peerAddress().toString();
@ -1738,7 +1791,9 @@ QByteArray DebugServerHandler::createDebugXmlDocument()
writer.writeStartElement("label");
writer.writeAttribute("class", "switch");
writer.writeStartElement("input");
writer.writeAttribute("id", QString("debug-category-%1").arg(loggingCategory));
writer.writeAttribute("type", "checkbox");
writer.writeAttribute("onclick", QString("toggleLoggingCategory('%1')").arg(loggingCategory));
writer.writeEndElement(); // input
writer.writeStartElement("span");
writer.writeAttribute("class", "slider round");
@ -1767,7 +1822,9 @@ QByteArray DebugServerHandler::createDebugXmlDocument()
writer.writeStartElement("label");
writer.writeAttribute("class", "switch");
writer.writeStartElement("input");
writer.writeAttribute("id", QString("debug-category-%1").arg(loggingCategory));
writer.writeAttribute("type", "checkbox");
writer.writeAttribute("onclick", QString("toggleLoggingCategory('%1')").arg(loggingCategory));
writer.writeEndElement(); // input
writer.writeStartElement("span");
writer.writeAttribute("class", "slider round");

View File

@ -171,29 +171,50 @@ int main(int argc, char *argv[])
}
}
QStringList filterRules;
/* The logging rules will be evaluated sequentially
* 1. All debug categories off
* 2. The stored categories from the nymead.conf will be appended
* 3. The Command line parameters will be added (-p and -d)
* 4. QT_LOGGING_CONF
* 5. QT_LOGGING_RULES
*
* The final filter rules will be set.
*/
QStringList loggingRules;
loggingRules << "*.debug=false";
// Load the rules from nymead.conf file and append them to the rules
NymeaSettings nymeaSettings(NymeaSettings::SettingsRoleGlobal);
nymeaSettings.beginGroup("LoggingRules");
foreach (const QString &category, nymeaSettings.childKeys()) {
loggingRules << QString("%1=%2").arg(category).arg(nymeaSettings.value(category, "false").toString());
}
nymeaSettings.endGroup();
// Append the rules depending on the application parameter
if (parser.isSet(allOption)) {
filterRules << "*.debug=true";
filterRules << "*Traffic.debug=false";
filterRules << "*Debug.debug=false";
} else {
filterRules << "*.debug=false";
loggingRules << "*.debug=true";
loggingRules << "*Traffic.debug=false";
loggingRules << "*Debug.debug=false";
}
// And allow overriding individual values
// And allow overriding individual values with application parameter
foreach (QString debugArea, parser.values(debugOption)) {
bool enable = !debugArea.startsWith("No");
bool isWarning = debugArea.endsWith("Warnings");
debugArea.remove(QRegExp("^No"));
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"));
loggingRules.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::setFilterRules(filterRules.join('\n'));
QLoggingCategory::setFilterRules(loggingRules.join('\n'));
// Parse DBus option
if (parser.isSet(dbusOption)) {
NymeaDBusService::setBusType(QDBusConnection::SessionBus);
}
@ -208,13 +229,13 @@ int main(int argc, char *argv[])
fprintf(stdout, "Could not create nymea settings directory %s", qPrintable(NymeaSettings::settingsPath()));
exit(EXIT_FAILURE);
}
qCInfo(dcApplication) << "=====================================";
qCInfo(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started with user ID" << userId;
qCInfo(dcApplication) << "=====================================";
qCInfo(dcApplication()) << "=====================================";
qCInfo(dcApplication()) << "nymead" << NYMEA_VERSION_STRING << "started with user ID" << userId;
qCInfo(dcApplication()) << "=====================================";
} else {
qCInfo(dcApplication) << "=====================================";
qCInfo(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started as root.";
qCInfo(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.