mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-25 19:56:30 +00:00
Add command FileLog 10..14
to enable logging to filesystem using up to 16 log files of 100kB
This commit is contained in:
parent
ec8cf6e2f0
commit
6d7aab4662
@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
||||
## [14.4.1.3]
|
||||
### Added
|
||||
- Command `FileLog 0..4` to enable logging to filesystem using up to 16 rotating log files of 100kB (`#define FILE_LOG_SIZE 100`)
|
||||
- Command `FileLog 10..14` to enable logging to filesystem using up to 16 log files of 100kB (`#define FILE_LOG_SIZE 100`)
|
||||
- I2S Opus stream and file support for opus/aac (#22795)
|
||||
- I2S command I2sLoop (#22807)
|
||||
|
||||
|
@ -118,6 +118,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
||||
### Added
|
||||
- Command `SetOption163 1` to disable display of Device name in GUI header
|
||||
- Command `FileLog 0..4` to enable logging to filesystem using up to 16 rotating log files of 100kB (`#define FILE_LOG_SIZE 100`)
|
||||
- Command `FileLog 10..14` to enable logging to filesystem using up to 16 log files of 100kB (`#define FILE_LOG_SIZE 100`)
|
||||
- Command I2sLoop [#22807](https://github.com/arendst/Tasmota/issues/22807)
|
||||
- Support for PCF85063 RTC [#22727](https://github.com/arendst/Tasmota/issues/22727)
|
||||
- Support for Senseair S88 CO2 sensor [#22733](https://github.com/arendst/Tasmota/issues/22733)
|
||||
|
@ -2650,7 +2650,8 @@ void AddLogData(uint32_t loglevel, const char* log_data, const char* log_data_pa
|
||||
uint32_t highest_loglevel = Settings->weblog_level;
|
||||
if (Settings->mqttlog_level > highest_loglevel) { highest_loglevel = Settings->mqttlog_level; }
|
||||
#ifdef USE_UFILESYS
|
||||
if (Settings->filelog_level > highest_loglevel) { highest_loglevel = Settings->filelog_level; }
|
||||
uint32_t filelog_level = Settings->filelog_level % 10;
|
||||
if (filelog_level > highest_loglevel) { highest_loglevel = filelog_level; }
|
||||
#endif // USE_UFILESYS
|
||||
if (TasmotaGlobal.syslog_level > highest_loglevel) { highest_loglevel = TasmotaGlobal.syslog_level; }
|
||||
if (TasmotaGlobal.templog_level > highest_loglevel) { highest_loglevel = TasmotaGlobal.templog_level; }
|
||||
|
@ -2163,8 +2163,22 @@ void CmndLogport(void)
|
||||
|
||||
#ifdef USE_UFILESYS
|
||||
void CmndFilelog(void) {
|
||||
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) {
|
||||
Settings->filelog_level = XdrvMailbox.payload;
|
||||
// Filelog 0 - Disable file logging
|
||||
// Filelog 1..4 - Enable rotating file logging
|
||||
// Filelog 10 - Remove log files and disable file logging
|
||||
// Filelog 11..14 - Remove log files and enable file logging until filesystem is full or max rotates
|
||||
if (XdrvMailbox.payload >= LOG_LEVEL_NONE) {
|
||||
uint32_t filelog_level = XdrvMailbox.payload % 10;
|
||||
uint32_t filelog_option = XdrvMailbox.payload / 10;
|
||||
if (1 == filelog_option) { // Enable file logging until filesystem is full
|
||||
FileLoggingDelete(); // Remove all log files
|
||||
if (LOG_LEVEL_NONE == filelog_level) { // Remove log files and disable logging
|
||||
filelog_option = 0;
|
||||
}
|
||||
}
|
||||
if ((filelog_level >= LOG_LEVEL_NONE) && (filelog_level <= LOG_LEVEL_DEBUG_MORE)) {
|
||||
Settings->filelog_level = (filelog_option * 10) + filelog_level;
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber(Settings->filelog_level);
|
||||
}
|
||||
|
@ -497,38 +497,34 @@ bool TfsRenameFile(const char *fname1, const char *fname2) {
|
||||
/*********************************************************************************************\
|
||||
* Log file
|
||||
*
|
||||
* Enable with command `FileLog 1..4`
|
||||
* Enable with command `FileLog 1..4` or `FileLog 11..14`
|
||||
* Rotate max 16 x FILE_LOG_SIZE kB log files /log01 -> /log02 ... /log16 -> /log01 ...
|
||||
* Filesystem needs to be larger than FILE_LOG_SIZE + LOG_BUFFER_SIZE
|
||||
* Filesystem needs to be larger than 10k (FILE_LOG_FREE)
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifndef FILE_LOG_SIZE
|
||||
#define FILE_LOG_SIZE 100 // Log file size in kBytes (100kB is based on minimal filesystem of 320kB)
|
||||
#endif
|
||||
#define FILE_LOG_FREE FILE_LOG_SIZE+(LOG_BUFFER_SIZE/1000) // Minimum free filesystem space in kBytes
|
||||
#define FILE_LOG_FREE 10 // Minimum free filesystem space in kBytes
|
||||
|
||||
#define FILE_LOG_COUNT 16 // Number of log files (max 16 as four bits are reserved for index)
|
||||
#define FILE_LOG_NAME "/log%02d" // Log file name
|
||||
|
||||
void FileLoggingAsync(bool refresh) {
|
||||
static uint32_t index = 1; // Rotating log buffer entry pointer
|
||||
|
||||
if (!ffs_type || !Settings->filelog_level) { return; } // No filesystem or [FileLog] disabled
|
||||
if (refresh && !NeedLogRefresh(Settings->filelog_level, index)) { return; } // No log buffer changes
|
||||
if (UfsSize() < FILE_LOG_FREE) {
|
||||
Settings->filelog_level = 0; // [FileLog] disable
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("FLG: Logging diabled. Filesystem too small")); // Or FILE_LOG_SIZE too large
|
||||
return;
|
||||
}
|
||||
uint32_t filelog_level = Settings->filelog_level % 10;
|
||||
if (!ffs_type || !filelog_level) { return; } // No filesystem or [FileLog] disabled
|
||||
if (refresh && !NeedLogRefresh(filelog_level, index)) { return; } // No log buffer changes
|
||||
uint32_t filelog_option = Settings->filelog_level / 10;
|
||||
|
||||
char fname[14];
|
||||
snprintf_P(fname, sizeof(fname), PSTR(FILE_LOG_NAME), Settings->mbflag2.log_file_idx +1); // /log01
|
||||
File file = ffsp->open(fname, "a"); // Append to existing log file
|
||||
File file;
|
||||
uint32_t log_file_idx = Settings->mbflag2.log_file_idx; // 0..15
|
||||
for (uint32_t retry = 0; retry <= 1; retry++) {
|
||||
snprintf_P(fname, sizeof(fname), PSTR(FILE_LOG_NAME), log_file_idx +1); // /log01
|
||||
file = ffsp->open(fname, "a"); // Append to existing log file
|
||||
if (!file) {
|
||||
if (UfsFree() < FILE_LOG_FREE) {
|
||||
Settings->filelog_level = 0; // [FileLog] disable
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("FLG: Logging disabled. Filesystem full"));
|
||||
return;
|
||||
}
|
||||
file = ffsp->open(fname, "w"); // Make new log file
|
||||
if (!file) {
|
||||
Settings->filelog_level = 0; // [FileLog] disable
|
||||
@ -537,12 +533,53 @@ void FileLoggingAsync(bool refresh) {
|
||||
}
|
||||
}
|
||||
|
||||
bool fs_full = (UfsFree() < FILE_LOG_FREE);
|
||||
if (!fs_full && (file.size() < (FILE_LOG_SIZE * 1000))) { break; }
|
||||
|
||||
file.close();
|
||||
|
||||
if (1 == retry) {
|
||||
Settings->filelog_level = 0; // [FileLog] disable
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("FLG: Logging disabled. No free space"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Rotate log file(s) as size is over FILE_LOG_SIZE or free space is less than FILE_LOG_FREE
|
||||
uint32_t last_log_file_idx = log_file_idx; // 0..15
|
||||
log_file_idx++;
|
||||
|
||||
if ((1 == filelog_option) &&
|
||||
(fs_full || (log_file_idx == FILE_LOG_COUNT))) { // Rotate until free space is less than FILE_LOG_FREE
|
||||
Settings->filelog_level = 0; // [FileLog] disable
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("FLG: Logging disabled. Max rotates"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (log_file_idx >= FILE_LOG_COUNT) { log_file_idx = 0; } // Rotate max 16 log files
|
||||
snprintf_P(fname, sizeof(fname), PSTR(FILE_LOG_NAME), log_file_idx +1);
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("FLG: Rotate file %s"), fname +1); // Skip leading slash
|
||||
Settings->mbflag2.log_file_idx = log_file_idx; // Save for restart or power on
|
||||
|
||||
if (0 == filelog_option) { // Remove oldest log file(s)
|
||||
// Remove log file(s) taking into account non-sequential file names and different file sizes
|
||||
uint32_t idx = log_file_idx; // Next log file index
|
||||
do { // Need free space around FILE_LOG_SIZE so find oldest log file(s) and remove it
|
||||
snprintf_P(fname, sizeof(fname), PSTR(FILE_LOG_NAME), idx +1);
|
||||
if (ffsp->remove(fname)) { // Remove oldest (non-)sequential log file(s)
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("FLG: Delete file %s"), fname +1); // Skip leading slash
|
||||
}
|
||||
idx++;
|
||||
if (idx >= FILE_LOG_COUNT) { idx = 0; }
|
||||
} while ((UfsFree() < FILE_LOG_FREE) && (idx != last_log_file_idx));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_WEBCAM
|
||||
WcInterrupt(0); // Stop stream if active to fix TG1WDT_SYS_RESET
|
||||
#endif
|
||||
char* line;
|
||||
size_t len;
|
||||
while (GetLog(Settings->filelog_level, &index, &line, &len)) {
|
||||
while (GetLog(filelog_level, &index, &line, &len)) {
|
||||
// This will timeout on ESP32-webcam
|
||||
// But now solved with WcInterrupt(0) in support_esp.ino
|
||||
file.write((uint8_t*)line, len -1); // Write up to LOG_BUFFER_SIZE log data
|
||||
@ -553,25 +590,19 @@ void FileLoggingAsync(bool refresh) {
|
||||
WcInterrupt(1);
|
||||
#endif
|
||||
|
||||
uint32_t file_size = file.size();
|
||||
file.close();
|
||||
if (file_size > (FILE_LOG_SIZE * 1000)) {
|
||||
// Rotate log file(s) as size is over FILE_LOG_SIZE
|
||||
// Taking into account non-sequential file names and different file sizes
|
||||
uint32_t log_file_idx = Settings->mbflag2.log_file_idx; // 0..15
|
||||
log_file_idx++;
|
||||
if (log_file_idx >= FILE_LOG_COUNT) { log_file_idx = 0; } // Rotate max 16 log files
|
||||
uint32_t idx = log_file_idx;
|
||||
do { // Need free space around FILE_LOG_SIZE so find oldest log file(s) and remove it
|
||||
}
|
||||
|
||||
void FileLoggingDelete(void) {
|
||||
if (!ffs_type) { return; } // No filesystem
|
||||
|
||||
char fname[14];
|
||||
for (uint32_t idx = 0; idx < FILE_LOG_COUNT; idx++) {
|
||||
snprintf_P(fname, sizeof(fname), PSTR(FILE_LOG_NAME), idx +1);
|
||||
ffsp->remove(fname); // Remove oldest (non-)sequential log file(s)
|
||||
idx++;
|
||||
if (idx >= FILE_LOG_COUNT) { idx = 0; }
|
||||
} while ((UfsFree() < FILE_LOG_FREE) && (idx != Settings->mbflag2.log_file_idx));
|
||||
Settings->mbflag2.log_file_idx = log_file_idx; // Save for restart or power on
|
||||
snprintf_P(fname, sizeof(fname), PSTR(FILE_LOG_NAME), log_file_idx +1);
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("FLG: Rotate file %s"), fname +1); // Skip leading slash
|
||||
ffsp->remove(fname); // Remove all log file(s)
|
||||
}
|
||||
Settings->mbflag2.log_file_idx = 0;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("FLG: Log files deleted"));
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
@ -1819,7 +1850,6 @@ void Switch_FTP(void) {
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
|
||||
bool Xdrv50(uint32_t function) {
|
||||
bool result = false;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user