Load debug categories from settings and allow configuration using debug interface
This commit is contained in:
parent
b4f32c073a
commit
191936e235
@ -92,7 +92,6 @@ function connectWebsocket() {
|
|||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
console.error(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
|
/* File download / show functions
|
||||||
@ -175,7 +233,7 @@ function pollReportResult() {
|
|||||||
|
|
||||||
/* Check if the generation went fine */
|
/* Check if the generation went fine */
|
||||||
if (reportGenerateRequest.status != 200) {
|
if (reportGenerateRequest.status != 200) {
|
||||||
console.log("Report generation finished with error.");
|
console.warn("Report generation finished with error.");
|
||||||
clearTimeout(generateReportTimer);
|
clearTimeout(generateReportTimer);
|
||||||
textArea.value = "Something went wrong :(" + reportGenerateRequest.status;
|
textArea.value = "Something went wrong :(" + reportGenerateRequest.status;
|
||||||
button.disabled = false;
|
button.disabled = false;
|
||||||
@ -366,5 +424,6 @@ function tracePathTimerTimeout() {
|
|||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
console.log("Window loading finished.");
|
console.log("Window loading finished.");
|
||||||
document.getElementById("informationTabButton").click();
|
document.getElementById("informationTabButton").click();
|
||||||
|
loadLoggingCategorySettings();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -71,6 +71,7 @@ textarea {
|
|||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab {
|
.tab {
|
||||||
@ -273,12 +274,12 @@ button::-moz-focus-inner { border: 0; }
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
width: 25%;
|
width: 30%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.debug-category p {
|
.debug-category p {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
text-align: left;
|
text-align: right;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,8 +358,6 @@ input:checked + .slider:before {
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
position:relative;
|
position:relative;
|
||||||
|
|||||||
@ -5,8 +5,7 @@ After=network.target
|
|||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Environment=QT_LOGGING_CONF=/etc/nymea/logging.conf
|
ExecStart=/usr/bin/nymead -n
|
||||||
ExecStart=/usr/bin/nymead -n --print-all
|
|
||||||
StandardOutput=journal
|
StandardOutput=journal
|
||||||
StandardError=journal
|
StandardError=journal
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
|
|||||||
1
debian/nymead.install.in
vendored
1
debian/nymead.install.in
vendored
@ -5,4 +5,3 @@ usr/lib/@DEB_HOST_MULTIARCH@/libnymea-core.so.1.0.0
|
|||||||
data/systemd/nymead.service /lib/systemd/system/
|
data/systemd/nymead.service /lib/systemd/system/
|
||||||
data/logrotate/nymead /etc/logrotate.d/
|
data/logrotate/nymead /etc/logrotate.d/
|
||||||
data/dbus-1/io.guh.nymead.conf /etc/dbus-1/system.d/
|
data/dbus-1/io.guh.nymead.conf /etc/dbus-1/system.d/
|
||||||
data/config/logging.conf /etc/nymea/
|
|
||||||
|
|||||||
@ -379,6 +379,61 @@ HttpReply *DebugServerHandler::processDebugRequest(const QString &requestPath, c
|
|||||||
return m_tracePathReply;
|
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")) {
|
if (requestPath.startsWith("/debug/report")) {
|
||||||
|
|
||||||
// The client can poll this url in order to get information about the current report generating process.
|
// 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()) {
|
if (s_websocketClients.isEmpty()) {
|
||||||
qCDebug(dcDebugServer()) << "Install debug message handler for live logs.";
|
qCDebug(dcDebugServer()) << "Install debug message handler for live logs.";
|
||||||
|
//QLoggingCategory::setFilterRules("*.debug=true");
|
||||||
s_oldLogMessageHandler = qInstallMessageHandler(&logMessageHandler);
|
s_oldLogMessageHandler = qInstallMessageHandler(&logMessageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable the log categories depending on the current debug configuration
|
|
||||||
|
|
||||||
|
|
||||||
s_websocketClients.append(client);
|
s_websocketClients.append(client);
|
||||||
qCDebug(dcDebugServer()) << "New websocket client connected:" << client->peerAddress().toString();
|
qCDebug(dcDebugServer()) << "New websocket client connected:" << client->peerAddress().toString();
|
||||||
|
|
||||||
@ -1738,7 +1791,9 @@ QByteArray DebugServerHandler::createDebugXmlDocument()
|
|||||||
writer.writeStartElement("label");
|
writer.writeStartElement("label");
|
||||||
writer.writeAttribute("class", "switch");
|
writer.writeAttribute("class", "switch");
|
||||||
writer.writeStartElement("input");
|
writer.writeStartElement("input");
|
||||||
|
writer.writeAttribute("id", QString("debug-category-%1").arg(loggingCategory));
|
||||||
writer.writeAttribute("type", "checkbox");
|
writer.writeAttribute("type", "checkbox");
|
||||||
|
writer.writeAttribute("onclick", QString("toggleLoggingCategory('%1')").arg(loggingCategory));
|
||||||
writer.writeEndElement(); // input
|
writer.writeEndElement(); // input
|
||||||
writer.writeStartElement("span");
|
writer.writeStartElement("span");
|
||||||
writer.writeAttribute("class", "slider round");
|
writer.writeAttribute("class", "slider round");
|
||||||
@ -1767,7 +1822,9 @@ QByteArray DebugServerHandler::createDebugXmlDocument()
|
|||||||
writer.writeStartElement("label");
|
writer.writeStartElement("label");
|
||||||
writer.writeAttribute("class", "switch");
|
writer.writeAttribute("class", "switch");
|
||||||
writer.writeStartElement("input");
|
writer.writeStartElement("input");
|
||||||
|
writer.writeAttribute("id", QString("debug-category-%1").arg(loggingCategory));
|
||||||
writer.writeAttribute("type", "checkbox");
|
writer.writeAttribute("type", "checkbox");
|
||||||
|
writer.writeAttribute("onclick", QString("toggleLoggingCategory('%1')").arg(loggingCategory));
|
||||||
writer.writeEndElement(); // input
|
writer.writeEndElement(); // input
|
||||||
writer.writeStartElement("span");
|
writer.writeStartElement("span");
|
||||||
writer.writeAttribute("class", "slider round");
|
writer.writeAttribute("class", "slider round");
|
||||||
|
|||||||
@ -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)) {
|
if (parser.isSet(allOption)) {
|
||||||
filterRules << "*.debug=true";
|
loggingRules << "*.debug=true";
|
||||||
filterRules << "*Traffic.debug=false";
|
loggingRules << "*Traffic.debug=false";
|
||||||
filterRules << "*Debug.debug=false";
|
loggingRules << "*Debug.debug=false";
|
||||||
} else {
|
|
||||||
filterRules << "*.debug=false";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// And allow overriding individual values
|
// And allow overriding individual values with application parameter
|
||||||
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");
|
bool isWarning = debugArea.endsWith("Warnings");
|
||||||
debugArea.remove(QRegExp("^No"));
|
debugArea.remove(QRegExp("^No"));
|
||||||
debugArea.remove(QRegExp("Warnings$"));
|
debugArea.remove(QRegExp("Warnings$"));
|
||||||
if (loggingFilters.contains(debugArea) || loggingFiltersPlugins.contains(debugArea)) {
|
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 {
|
} else {
|
||||||
qCWarning(dcApplication) << QCoreApplication::translate("nymea", "No such debug category:") << debugArea;
|
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)) {
|
if (parser.isSet(dbusOption)) {
|
||||||
NymeaDBusService::setBusType(QDBusConnection::SessionBus);
|
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()));
|
fprintf(stdout, "Could not create nymea settings directory %s", qPrintable(NymeaSettings::settingsPath()));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
qCInfo(dcApplication) << "=====================================";
|
qCInfo(dcApplication()) << "=====================================";
|
||||||
qCInfo(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started with user ID" << userId;
|
qCInfo(dcApplication()) << "nymead" << NYMEA_VERSION_STRING << "started with user ID" << userId;
|
||||||
qCInfo(dcApplication) << "=====================================";
|
qCInfo(dcApplication()) << "=====================================";
|
||||||
} else {
|
} else {
|
||||||
qCInfo(dcApplication) << "=====================================";
|
qCInfo(dcApplication()) << "=====================================";
|
||||||
qCInfo(dcApplication) << "nymead" << NYMEA_VERSION_STRING << "started as root.";
|
qCInfo(dcApplication()) << "nymead" << NYMEA_VERSION_STRING << "started as root.";
|
||||||
qCInfo(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.
|
||||||
|
|||||||
Reference in New Issue
Block a user