mirror of
https://github.com/tbnobody/OpenDTU.git
synced 2025-12-10 16:59:52 +01:00
Feature: Allow setting the log level for the different modules at runtime
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
#include <mutex>
|
||||
|
||||
#define CONFIG_FILENAME "/config.json"
|
||||
#define CONFIG_VERSION 0x00011d00 // 0.1.29 // make sure to clean all after change
|
||||
#define CONFIG_VERSION 0x00011e00 // 0.1.30 // make sure to clean all after change
|
||||
|
||||
#define WIFI_MAX_SSID_STRLEN 32
|
||||
#define WIFI_MAX_PASSWORD_STRLEN 64
|
||||
@@ -35,6 +35,9 @@
|
||||
#define DEV_MAX_MAPPING_NAME_STRLEN 63
|
||||
#define LOCALE_STRLEN 2
|
||||
|
||||
#define LOG_MODULE_COUNT 16
|
||||
#define LOG_MODULE_NAME_STRLEN 32
|
||||
|
||||
struct CHANNEL_CONFIG_T {
|
||||
uint16_t MaxChannelPower;
|
||||
char Name[CHAN_MAX_NAME_STRLEN];
|
||||
@@ -161,6 +164,14 @@ struct CONFIG_T {
|
||||
|
||||
INVERTER_CONFIG_T Inverter[INV_MAX_COUNT];
|
||||
char Dev_PinMapping[DEV_MAX_MAPPING_NAME_STRLEN + 1];
|
||||
|
||||
struct {
|
||||
int8_t Default;
|
||||
struct {
|
||||
char Name[LOG_MODULE_NAME_STRLEN + 1];
|
||||
int8_t Level;
|
||||
} Modules[LOG_MODULE_COUNT];
|
||||
} Logging;
|
||||
};
|
||||
|
||||
class ConfigurationClass {
|
||||
@@ -187,6 +198,8 @@ public:
|
||||
INVERTER_CONFIG_T* getInverterConfig(const uint64_t serial);
|
||||
void deleteInverterById(const uint8_t id);
|
||||
|
||||
int8_t getIndexForLogModule(const String& moduleName) const;
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
|
||||
17
include/Logging.h
Normal file
17
include/Logging.h
Normal file
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <WString.h>
|
||||
#include <vector>
|
||||
|
||||
class LoggingClass {
|
||||
public:
|
||||
LoggingClass();
|
||||
void applyLogLevels();
|
||||
const std::vector<String>& getConfigurableModules() const;
|
||||
|
||||
private:
|
||||
std::vector<String> _configurableModules;
|
||||
};
|
||||
|
||||
extern LoggingClass Logging;
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "WebApi_i18n.h"
|
||||
#include "WebApi_inverter.h"
|
||||
#include "WebApi_limit.h"
|
||||
#include "WebApi_logging.h"
|
||||
#include "WebApi_maintenance.h"
|
||||
#include "WebApi_mqtt.h"
|
||||
#include "WebApi_network.h"
|
||||
@@ -57,6 +58,7 @@ private:
|
||||
WebApiI18nClass _webApiI18n;
|
||||
WebApiInverterClass _webApiInverter;
|
||||
WebApiLimitClass _webApiLimit;
|
||||
WebApiLoggingClass _webApiLogging;
|
||||
WebApiMaintenanceClass _webApiMaintenance;
|
||||
WebApiMqttClass _webApiMqtt;
|
||||
WebApiNetworkClass _webApiNetwork;
|
||||
|
||||
14
include/WebApi_logging.h
Normal file
14
include/WebApi_logging.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiLoggingClass {
|
||||
public:
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onLoggingAdminGet(AsyncWebServerRequest* request);
|
||||
void onLoggingAdminPost(AsyncWebServerRequest* request);
|
||||
};
|
||||
@@ -22,6 +22,7 @@
|
||||
"MQTTSettings": "MQTT Ρυθμίσεις",
|
||||
"InverterSettings": "Ρυθμίσεις Μετατροπέα",
|
||||
"SecuritySettings": "Ρυθμίσεις Ασφάλειας",
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"DTUSettings": "DTU Ρυθμίσεις",
|
||||
"DeviceManager": "Διαχείριση Συσκευών",
|
||||
"ConfigManagement": "Διαχείριση διαμόρφωσης",
|
||||
@@ -700,6 +701,19 @@
|
||||
"format_herf_valid": "Μορφή E-Star HERF (θα αποθηκευτεί μετατρεπόμενη): {serial}",
|
||||
"format_herf_invalid": "Μορφή E-Star HERF: Μη έγκυρο άθροισμα ελέγχου",
|
||||
"format_unknown": "Άγνωστη μορφή"
|
||||
},
|
||||
"loggingadmin": {
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"LogLevel": "Log Level",
|
||||
"DefaultLevel": "Default log level",
|
||||
"Module": "Module",
|
||||
"log_inherit": "Inherit from default",
|
||||
"log_none": "None",
|
||||
"log_error": "(E) Error",
|
||||
"log_warn": "(W) Warning",
|
||||
"log_info": "(I) Info",
|
||||
"log_debug": "(D) Debug",
|
||||
"log_verbose": "(V) Verbose"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"MQTTSettings": "Ajustes MQTT",
|
||||
"InverterSettings": "Ajustes Inversor",
|
||||
"SecuritySettings": "Ajustes Seguridad",
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"DTUSettings": "Ajustes DTU",
|
||||
"DeviceManager": "Administrador Dispositivos",
|
||||
"ConfigManagement": "Gestión configuración",
|
||||
@@ -700,6 +701,19 @@
|
||||
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
|
||||
"format_unknown": "Unknown format"
|
||||
},
|
||||
"loggingadmin": {
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"LogLevel": "Log Level",
|
||||
"DefaultLevel": "Default log level",
|
||||
"Module": "Module",
|
||||
"log_inherit": "Inherit from default",
|
||||
"log_none": "None",
|
||||
"log_error": "(E) Error",
|
||||
"log_warn": "(W) Warning",
|
||||
"log_info": "(I) Info",
|
||||
"log_debug": "(D) Debug",
|
||||
"log_verbose": "(V) Verbose"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"MQTTSettings": "Impostazioni MQTT",
|
||||
"InverterSettings": "Impostazioni Inverter",
|
||||
"SecuritySettings": "Impostazioni di Sicurezza",
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"DTUSettings": "Impostazioni DTU",
|
||||
"DeviceManager": "Gestione Dispositivi",
|
||||
"ConfigManagement": "Gestione Configurazione",
|
||||
@@ -700,6 +701,19 @@
|
||||
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
|
||||
"format_unknown": "Unknown format"
|
||||
},
|
||||
"loggingadmin": {
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"LogLevel": "Log Level",
|
||||
"DefaultLevel": "Default log level",
|
||||
"Module": "Module",
|
||||
"log_inherit": "Inherit from default",
|
||||
"log_none": "None",
|
||||
"log_error": "(E) Error",
|
||||
"log_warn": "(W) Warning",
|
||||
"log_info": "(I) Info",
|
||||
"log_debug": "(D) Debug",
|
||||
"log_verbose": "(V) Verbose"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"MQTTSettings": "Ustawienia serwera MQTT",
|
||||
"InverterSettings": "Ustawienia falownika",
|
||||
"SecuritySettings": "Ustawienia zabezpieczeń",
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"DTUSettings": "Ustawienia DTU",
|
||||
"DeviceManager": "Zarządzanie urządzeniami",
|
||||
"ConfigManagement": "Zarządzanie konfiguracją",
|
||||
@@ -700,6 +701,19 @@
|
||||
"format_herf_valid": "Format E-Star HERF (zostanie zapisany po konwersji): {serial}",
|
||||
"format_herf_invalid": "Format E-Star HERF: Nieprawidłowa suma kontrolna",
|
||||
"format_unknown": "Nieznany format"
|
||||
},
|
||||
"loggingadmin": {
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"LogLevel": "Log Level",
|
||||
"DefaultLevel": "Default log level",
|
||||
"Module": "Module",
|
||||
"log_inherit": "Inherit from default",
|
||||
"log_none": "None",
|
||||
"log_error": "(E) Error",
|
||||
"log_warn": "(W) Warning",
|
||||
"log_info": "(I) Info",
|
||||
"log_debug": "(D) Debug",
|
||||
"log_verbose": "(V) Verbose"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "defaults.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <LittleFS.h>
|
||||
#include <esp_log.h>
|
||||
#include <nvs_flash.h>
|
||||
|
||||
#undef TAG
|
||||
@@ -153,6 +154,15 @@ bool ConfigurationClass::write()
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject logging = doc["logging"].to<JsonObject>();
|
||||
logging["default"] = config.Logging.Default;
|
||||
JsonArray modules = logging["modules"].to<JsonArray>();
|
||||
for (uint8_t i = 0; i < LOG_MODULE_COUNT; i++) {
|
||||
JsonObject module = modules.add<JsonObject>();
|
||||
module["level"] = config.Logging.Modules[i].Level;
|
||||
module["name"] = config.Logging.Modules[i].Name;
|
||||
}
|
||||
|
||||
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
|
||||
return false;
|
||||
}
|
||||
@@ -329,6 +339,15 @@ bool ConfigurationClass::read()
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject logging = doc["logging"];
|
||||
config.Logging.Default = logging["default"] | ESP_LOG_ERROR;
|
||||
JsonArray modules = logging["modules"];
|
||||
for (uint8_t i = 0; i < LOG_MODULE_COUNT; i++) {
|
||||
JsonObject module = modules[i].as<JsonObject>();
|
||||
strlcpy(config.Logging.Modules[i].Name, module["name"] | "", sizeof(config.Logging.Modules[i].Name));
|
||||
config.Logging.Modules[i].Level = module["level"] | ESP_LOG_VERBOSE;
|
||||
}
|
||||
|
||||
f.close();
|
||||
|
||||
// Check for default DTU serial
|
||||
@@ -426,6 +445,12 @@ void ConfigurationClass::migrate()
|
||||
}
|
||||
}
|
||||
|
||||
if (config.Cfg.Version < 0x00011e00) {
|
||||
config.Logging.Default = ESP_LOG_VERBOSE;
|
||||
strlcpy(config.Logging.Modules[0].Name, "CORE", sizeof(config.Logging.Modules[0].Name));
|
||||
config.Logging.Modules[0].Level = ESP_LOG_ERROR;
|
||||
}
|
||||
|
||||
f.close();
|
||||
|
||||
config.Cfg.Version = CONFIG_VERSION;
|
||||
@@ -487,6 +512,17 @@ void ConfigurationClass::deleteInverterById(const uint8_t id)
|
||||
}
|
||||
}
|
||||
|
||||
int8_t ConfigurationClass::getIndexForLogModule(const String& moduleName) const
|
||||
{
|
||||
for (uint8_t i = 0; i < LOG_MODULE_COUNT; i++) {
|
||||
if (strcmp(config.Logging.Modules[i].Name, moduleName.c_str()) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ConfigurationClass::loop()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(sWriterMutex);
|
||||
|
||||
37
src/Logging.cpp
Normal file
37
src/Logging.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2025 Thomas Basler and others
|
||||
*/
|
||||
#include "Logging.h"
|
||||
#include "Configuration.h"
|
||||
|
||||
LoggingClass Logging;
|
||||
|
||||
LoggingClass::LoggingClass()
|
||||
{
|
||||
_configurableModules.reserve(3);
|
||||
_configurableModules.push_back("CORE");
|
||||
_configurableModules.push_back("hoymiles");
|
||||
_configurableModules.push_back("mqtt");
|
||||
_configurableModules.push_back("network");
|
||||
_configurableModules.push_back("webapi");
|
||||
}
|
||||
|
||||
const std::vector<String>& LoggingClass::getConfigurableModules() const
|
||||
{
|
||||
return _configurableModules;
|
||||
}
|
||||
|
||||
void LoggingClass::applyLogLevels()
|
||||
{
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
|
||||
esp_log_level_set("*", static_cast<esp_log_level_t>(config.Logging.Default));
|
||||
for (int8_t i = 0; i < LOG_MODULE_COUNT; i++) {
|
||||
if (strlen(config.Logging.Modules[i].Name) == 0 || config.Logging.Modules[i].Level < ESP_LOG_NONE || config.Logging.Modules[i].Level > ESP_LOG_VERBOSE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
esp_log_level_set(config.Logging.Modules[i].Name, static_cast<esp_log_level_t>(config.Logging.Modules[i].Level));
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ void WebApiClass::init(Scheduler& scheduler)
|
||||
_webApiI18n.init(_server, scheduler);
|
||||
_webApiInverter.init(_server, scheduler);
|
||||
_webApiLimit.init(_server, scheduler);
|
||||
_webApiLogging.init(_server, scheduler);
|
||||
_webApiMaintenance.init(_server, scheduler);
|
||||
_webApiMqtt.init(_server, scheduler);
|
||||
_webApiNetwork.init(_server, scheduler);
|
||||
|
||||
105
src/WebApi_logging.cpp
Normal file
105
src/WebApi_logging.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2025 Thomas Basler and others
|
||||
*/
|
||||
#include "WebApi_logging.h"
|
||||
#include "Configuration.h"
|
||||
#include "Logging.h"
|
||||
#include "WebApi.h"
|
||||
#include "WebApi_errors.h"
|
||||
#include "helper.h"
|
||||
#include <AsyncJson.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
void WebApiLoggingClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
||||
{
|
||||
using std::placeholders::_1;
|
||||
|
||||
server.on("/api/logging/config", HTTP_GET, std::bind(&WebApiLoggingClass::onLoggingAdminGet, this, _1));
|
||||
server.on("/api/logging/config", HTTP_POST, std::bind(&WebApiLoggingClass::onLoggingAdminPost, this, _1));
|
||||
}
|
||||
|
||||
void WebApiLoggingClass::onLoggingAdminGet(AsyncWebServerRequest* request)
|
||||
{
|
||||
if (!WebApi.checkCredentials(request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
auto& root = response->getRoot();
|
||||
const CONFIG_T& config = Configuration.get();
|
||||
|
||||
auto& configurableModules = Logging.getConfigurableModules();
|
||||
|
||||
JsonObject loglevel = root["loglevel"].to<JsonObject>();
|
||||
loglevel["default"] = config.Logging.Default;
|
||||
|
||||
JsonArray logModules = loglevel["modules"].to<JsonArray>();
|
||||
for (const auto& availModule : configurableModules) {
|
||||
JsonObject logModule = logModules.add<JsonObject>();
|
||||
logModule["name"] = availModule;
|
||||
|
||||
int8_t idx = Configuration.getIndexForLogModule(availModule);
|
||||
// Set to inherit if unknown
|
||||
logModule["level"] = idx < 0 || idx > ESP_LOG_VERBOSE ? -1 : config.Logging.Modules[idx].Level;
|
||||
}
|
||||
|
||||
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
void WebApiLoggingClass::onLoggingAdminPost(AsyncWebServerRequest* request)
|
||||
{
|
||||
if (!WebApi.checkCredentials(request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonDocument root;
|
||||
if (!WebApi.parseRequestData(request, response, root)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& retMsg = response->getRoot();
|
||||
auto& configurableModules = Logging.getConfigurableModules();
|
||||
|
||||
{
|
||||
auto guard = Configuration.getWriteGuard();
|
||||
auto& config = guard.getConfig();
|
||||
|
||||
config.Logging.Default = std::max<int8_t>(ESP_LOG_NONE, std::min<int8_t>(ESP_LOG_VERBOSE, root["loglevel"]["default"].as<int8_t>()));
|
||||
|
||||
for (uint8_t i = 0; i < LOG_MODULE_COUNT; i++) {
|
||||
config.Logging.Modules[i].Level = ESP_LOG_NONE;
|
||||
config.Logging.Modules[i].Name[0] = '\0';
|
||||
}
|
||||
|
||||
JsonArray logmodules = root["loglevel"]["modules"].as<JsonArray>();
|
||||
uint8_t i = 0;
|
||||
for (const auto& logmodule : logmodules) {
|
||||
bool isValidModule = std::find(configurableModules.begin(), configurableModules.end(), logmodule["name"] | "") != configurableModules.end();
|
||||
if (!isValidModule) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int8_t level = std::max<int8_t>(-1, std::min<int8_t>(ESP_LOG_VERBOSE, logmodule["level"].as<int8_t>()));
|
||||
if (level < ESP_LOG_NONE) {
|
||||
// Skip modules set to inherit
|
||||
continue;
|
||||
}
|
||||
|
||||
config.Logging.Modules[i].Level = level;
|
||||
strlcpy(config.Logging.Modules[i].Name, logmodule["name"] | "", sizeof(config.Logging.Modules[i].Name));
|
||||
|
||||
if (++i >= LOG_MODULE_COUNT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logging.applyLogLevels();
|
||||
|
||||
WebApi.writeConfig(retMsg);
|
||||
|
||||
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "I18n.h"
|
||||
#include "InverterSettings.h"
|
||||
#include "Led_Single.h"
|
||||
#include "Logging.h"
|
||||
#include "MessageOutput.h"
|
||||
#include "MqttHandleDtu.h"
|
||||
#include "MqttHandleHass.h"
|
||||
@@ -73,6 +74,10 @@ void setup()
|
||||
Configuration.migrate();
|
||||
}
|
||||
|
||||
// Set configured log levels
|
||||
Logging.applyLogLevels();
|
||||
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
|
||||
|
||||
// Read languate pack
|
||||
ESP_LOGI(TAG, "Reading language pack...");
|
||||
I18n.init(scheduler);
|
||||
|
||||
@@ -63,6 +63,11 @@
|
||||
>{{ $t('menu.SecuritySettings') }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link @click="onClick" class="dropdown-item" to="/settings/logging"
|
||||
>{{ $t('menu.LoggingSettings') }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link @click="onClick" class="dropdown-item" to="/settings/dtu">{{
|
||||
$t('menu.DTUSettings')
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"MQTTSettings": "MQTT",
|
||||
"InverterSettings": "Wechselrichter",
|
||||
"SecuritySettings": "Sicherheit",
|
||||
"LoggingSettings": "Protokollierung",
|
||||
"DTUSettings": "DTU",
|
||||
"DeviceManager": "Hardware",
|
||||
"ConfigManagement": "Konfigurationsverwaltung",
|
||||
@@ -684,5 +685,18 @@
|
||||
"format_herf_valid": "E-Star HERF Format (wird konvertiert gespeichert): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF Format: Ungültige Prüfsumme",
|
||||
"format_unknown": "Unbekanntes Format"
|
||||
},
|
||||
"loggingadmin": {
|
||||
"LoggingSettings": "Protokollierungseinstellungen",
|
||||
"LogLevel": "Protokollierungsstufe",
|
||||
"DefaultLevel": "Standard-Protokollierungsstufe",
|
||||
"Module": "Modul",
|
||||
"log_inherit": "Von Standard erben",
|
||||
"log_none": "Keine",
|
||||
"log_error": "(E) Fehler",
|
||||
"log_warn": "(W) Warnung",
|
||||
"log_info": "(I) Info",
|
||||
"log_debug": "(D) Debug",
|
||||
"log_verbose": "(V) Ausführlich"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"MQTTSettings": "MQTT Settings",
|
||||
"InverterSettings": "Inverter Settings",
|
||||
"SecuritySettings": "Security Settings",
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"DTUSettings": "DTU Settings",
|
||||
"DeviceManager": "Device-Manager",
|
||||
"ConfigManagement": "Config Management",
|
||||
@@ -685,5 +686,18 @@
|
||||
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
|
||||
"format_unknown": "Unknown format"
|
||||
},
|
||||
"loggingadmin": {
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"LogLevel": "Log Level",
|
||||
"DefaultLevel": "Default log level",
|
||||
"Module": "Module",
|
||||
"log_inherit": "Inherit from default",
|
||||
"log_none": "None",
|
||||
"log_error": "(E) Error",
|
||||
"log_warn": "(W) Warning",
|
||||
"log_info": "(I) Info",
|
||||
"log_debug": "(D) Debug",
|
||||
"log_verbose": "(V) Verbose"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"MQTTSettings": "MQTT",
|
||||
"InverterSettings": "Onduleurs",
|
||||
"SecuritySettings": "Sécurité",
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"DTUSettings": "DTU",
|
||||
"DeviceManager": "Périphériques",
|
||||
"ConfigManagement": "Gestion de la configuration",
|
||||
@@ -666,5 +667,18 @@
|
||||
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
|
||||
"format_unknown": "Unknown format"
|
||||
},
|
||||
"loggingadmin": {
|
||||
"LoggingSettings": "Logging Settings",
|
||||
"LogLevel": "Log Level",
|
||||
"DefaultLevel": "Default log level",
|
||||
"Module": "Module",
|
||||
"log_inherit": "Inherit from default",
|
||||
"log_none": "None",
|
||||
"log_error": "(E) Error",
|
||||
"log_warn": "(W) Warning",
|
||||
"log_info": "(I) Info",
|
||||
"log_debug": "(D) Debug",
|
||||
"log_verbose": "(V) Verbose"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import HomeView from '@/views/HomeView.vue';
|
||||
import InverterAdminView from '@/views/InverterAdminView.vue';
|
||||
import LoginView from '@/views/LoginView.vue';
|
||||
import MaintenanceRebootView from '@/views/MaintenanceRebootView.vue';
|
||||
import LoggingAdminView from '@/views/LoggingAdminView.vue';
|
||||
import MqttAdminView from '@/views/MqttAdminView.vue';
|
||||
import MqttInfoView from '@/views/MqttInfoView.vue';
|
||||
import NetworkAdminView from '@/views/NetworkAdminView.vue';
|
||||
@@ -121,6 +122,11 @@ const router = createRouter({
|
||||
name: 'Security',
|
||||
component: SecurityAdminView,
|
||||
},
|
||||
{
|
||||
path: '/settings/logging',
|
||||
name: 'Logging',
|
||||
component: LoggingAdminView,
|
||||
},
|
||||
{
|
||||
path: '/maintenance/reboot',
|
||||
name: 'Device Reboot',
|
||||
|
||||
13
webapp/src/types/LoggingConfig.ts
Normal file
13
webapp/src/types/LoggingConfig.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export interface LogModule {
|
||||
name: string;
|
||||
level: number;
|
||||
}
|
||||
|
||||
export interface LogLevel {
|
||||
default: number;
|
||||
modules: Array<LogModule>;
|
||||
}
|
||||
|
||||
export interface LoggingConfig {
|
||||
loglevel: LogLevel;
|
||||
}
|
||||
125
webapp/src/views/LoggingAdminView.vue
Normal file
125
webapp/src/views/LoggingAdminView.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<BasePage :title="$t('loggingadmin.LoggingSettings')" :isLoading="dataLoading">
|
||||
<BootstrapAlert v-model="alert.show" dismissible :variant="alert.type">
|
||||
{{ alert.message }}
|
||||
</BootstrapAlert>
|
||||
<form @submit="saveLogConfig">
|
||||
<CardElement :text="$t('loggingadmin.LogLevel')" textVariant="text-bg-primary">
|
||||
<div class="row mb-3">
|
||||
<label for="inputDefaultLevel" class="col-sm-2 col-form-label">{{
|
||||
$t('loggingadmin.DefaultLevel')
|
||||
}}</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-select" id="inputDefaultLevel" v-model="loggingList.loglevel.default">
|
||||
<option
|
||||
v-for="level in logLevelList.filter((property) => property.key >= 0)"
|
||||
:value="level.key"
|
||||
:key="level.key"
|
||||
>
|
||||
{{ $t('loggingadmin.' + level.value) }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{ $t('loggingadmin.Module') }}</th>
|
||||
<th>{{ $t('loggingadmin.LogLevel') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="module in loggingList.loglevel.modules"
|
||||
v-bind:key="module.name"
|
||||
:data-id="module.name"
|
||||
class="align-middle"
|
||||
>
|
||||
<td>{{ module.name }}</td>
|
||||
<td>
|
||||
<select class="form-select" v-model="module.level">
|
||||
<option v-for="level in logLevelList" :value="level.key" :key="level.key">
|
||||
{{ $t('loggingadmin.' + level.value) }}
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</CardElement>
|
||||
|
||||
<FormFooter @reload="getLogConfig" />
|
||||
</form>
|
||||
</BasePage>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import BasePage from '@/components/BasePage.vue';
|
||||
import BootstrapAlert from '@/components/BootstrapAlert.vue';
|
||||
import CardElement from '@/components/CardElement.vue';
|
||||
import FormFooter from '@/components/FormFooter.vue';
|
||||
import type { AlertResponse } from '@/types/AlertResponse';
|
||||
import type { LoggingConfig } from '@/types/LoggingConfig';
|
||||
import { authHeader, handleResponse } from '@/utils/authentication';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
BasePage,
|
||||
BootstrapAlert,
|
||||
CardElement,
|
||||
FormFooter,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataLoading: true,
|
||||
alert: {} as AlertResponse,
|
||||
loggingList: {} as LoggingConfig,
|
||||
logLevelList: [
|
||||
{ key: -1, value: 'log_inherit' },
|
||||
{ key: 0, value: 'log_none' },
|
||||
{ key: 1, value: 'log_error' },
|
||||
{ key: 2, value: 'log_warn' },
|
||||
{ key: 3, value: 'log_info' },
|
||||
{ key: 4, value: 'log_debug' },
|
||||
{ key: 5, value: 'log_verbose' },
|
||||
],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getLogConfig();
|
||||
},
|
||||
methods: {
|
||||
getLogConfig() {
|
||||
this.dataLoading = true;
|
||||
fetch('/api/logging/config', { headers: authHeader() })
|
||||
.then((response) => handleResponse(response, this.$emitter, this.$router))
|
||||
.then((data) => {
|
||||
this.loggingList = data;
|
||||
this.dataLoading = false;
|
||||
});
|
||||
},
|
||||
saveLogConfig(e: Event) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('data', JSON.stringify(this.loggingList));
|
||||
|
||||
fetch('/api/logging/config', {
|
||||
method: 'POST',
|
||||
headers: authHeader(),
|
||||
body: formData,
|
||||
})
|
||||
.then((response) => handleResponse(response, this.$emitter, this.$router))
|
||||
.then((data) => {
|
||||
this.alert = data;
|
||||
this.alert.message = this.$t('apiresponse.' + data.code, data.param);
|
||||
this.alert.show = true;
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user