From 6d8d022f2a5d5a32bdb48f217e9875e31ece77c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 20:55:00 +0000 Subject: [PATCH 1/4] Initial plan From 955d4e0d00b09c0b9a368ed60f4eaa1f42467919 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 21:00:39 +0000 Subject: [PATCH 2/4] Implement smart file flushing policy for issue #21 Co-authored-by: jibrilsharafi <83494924+jibrilsharafi@users.noreply.github.com> --- src/AdvancedLogger.cpp | 34 ++++++++++++++++++++++++++++++++-- src/AdvancedLogger.h | 10 ++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/AdvancedLogger.cpp b/src/AdvancedLogger.cpp index 797b5fb..45f793f 100644 --- a/src/AdvancedLogger.cpp +++ b/src/AdvancedLogger.cpp @@ -38,6 +38,9 @@ namespace AdvancedLogger static TaskHandle_t _logTaskHandle = nullptr; static bool _queueInitialized = false; + // File flushing control + static unsigned long _lastFlushTime = 0; + // Forward declarations of private functions static void _log(const char *message, const char *file, const char *function, int line, LogLevel logLevel); static void _internalLog(const char* level, const char* format, ...); @@ -142,6 +145,9 @@ namespace AdvancedLogger _logLines = getLogLines(); + // Initialize flush timestamp + _lastFlushTime = millis(); + _initLogQueue(); _internalLog("DEBUG", "AdvancedLogger initialized"); @@ -331,7 +337,16 @@ namespace AdvancedLogger #endif #ifndef ADVANCED_LOGGER_DISABLE_FILE_LOGGING - if (entry.level >= _saveLevel) _save(messageFormatted); + if (entry.level >= _saveLevel) { + // Determine if immediate flush is needed based on log level + bool forceFlush = false; +#if ADVANCED_LOGGER_FLUSH_ON_ERROR + if (entry.level >= LogLevel::ERROR) { + forceFlush = true; + } +#endif + _save(messageFormatted, forceFlush); + } #endif } @@ -657,7 +672,21 @@ namespace AdvancedLogger if (!_checkAndOpenLogFile(FileMode::APPEND)) return; _logFile.println(messageFormatted); - if (flush) _logFile.flush(); + + // Smart flushing logic + unsigned long currentTime = millis(); + bool shouldFlush = flush; + + // Check if periodic flush interval has elapsed + if (!shouldFlush && (currentTime - _lastFlushTime >= ADVANCED_LOGGER_FLUSH_INTERVAL_MS)) { + shouldFlush = true; + } + + if (shouldFlush) { + _logFile.flush(); + _lastFlushTime = currentTime; + } + _logLines++; if (_logLines >= _maxLogLines) { @@ -830,6 +859,7 @@ namespace AdvancedLogger void _closeLogFile() { if (_logFile) { + _logFile.flush(); // Ensure all data is written before closing _logFile.close(); _currentFileMode = FileMode::APPEND; // Reset to default } diff --git a/src/AdvancedLogger.h b/src/AdvancedLogger.h index 605c629..dfbb56b 100644 --- a/src/AdvancedLogger.h +++ b/src/AdvancedLogger.h @@ -33,6 +33,8 @@ * - ADVANCED_LOGGER_TASK_PRIORITY: Priority for the log processing task. * - ADVANCED_LOGGER_TASK_CORE: Core ID for the log processing task. * - ADVANCED_LOGGER_MAX_MESSAGE_LENGTH: Maximum length of log messages. + * - ADVANCED_LOGGER_FLUSH_INTERVAL_MS: Interval in milliseconds for periodic file flushing (default: 5000ms). + * - ADVANCED_LOGGER_FLUSH_ON_ERROR: Enable immediate flush on ERROR and FATAL log levels (default: 1 = enabled). * * Usage: * In platformio.ini: build_flags = -DADVANCED_LOGGER_ALLOCABLE_HEAP_SIZE=10240 @@ -63,6 +65,14 @@ #define ADVANCED_LOGGER_MAX_MESSAGE_LENGTH 512 #endif +#ifndef ADVANCED_LOGGER_FLUSH_INTERVAL_MS + #define ADVANCED_LOGGER_FLUSH_INTERVAL_MS 5000 // Flush every 5 seconds +#endif + +#ifndef ADVANCED_LOGGER_FLUSH_ON_ERROR + #define ADVANCED_LOGGER_FLUSH_ON_ERROR 1 // 1 = enabled, 0 = disabled +#endif + /* * Compilation flags to conditionally disable logging: From 7d5eb4c68490bc28e5f12719d9fbd7b29855d048 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 21:18:40 +0000 Subject: [PATCH 3/4] Make flush log level configurable and add README documentation Co-authored-by: jibrilsharafi <83494924+jibrilsharafi@users.noreply.github.com> --- README.md | 13 +++++++++++++ src/AdvancedLogger.cpp | 2 +- src/AdvancedLogger.h | 7 ++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 04b7322..e3ee612 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,19 @@ build_flags = -DADVANCED_LOGGER_MAX_MESSAGE_LENGTH=512 ``` +### File Flushing +Configure when log files are flushed to ensure data persistence: + +```cpp +#define ADVANCED_LOGGER_FLUSH_INTERVAL_MS 5000 // Flush every 5 seconds (default) +#define ADVANCED_LOGGER_FLUSH_ON_ERROR 1 // Enable immediate flush on errors (default) +#define ADVANCED_LOGGER_FLUSH_LOG_LEVEL LogLevel::ERROR // Log level that triggers immediate flush (default) + +#include "AdvancedLogger.h" +``` + +The library automatically flushes files periodically and on critical log levels to prevent data loss during power cycles or crashes. + ### Callbacks Register a function to handle log entries: diff --git a/src/AdvancedLogger.cpp b/src/AdvancedLogger.cpp index 45f793f..5a5ca1e 100644 --- a/src/AdvancedLogger.cpp +++ b/src/AdvancedLogger.cpp @@ -341,7 +341,7 @@ namespace AdvancedLogger // Determine if immediate flush is needed based on log level bool forceFlush = false; #if ADVANCED_LOGGER_FLUSH_ON_ERROR - if (entry.level >= LogLevel::ERROR) { + if (entry.level >= ADVANCED_LOGGER_FLUSH_LOG_LEVEL) { forceFlush = true; } #endif diff --git a/src/AdvancedLogger.h b/src/AdvancedLogger.h index dfbb56b..a2bb111 100644 --- a/src/AdvancedLogger.h +++ b/src/AdvancedLogger.h @@ -34,7 +34,8 @@ * - ADVANCED_LOGGER_TASK_CORE: Core ID for the log processing task. * - ADVANCED_LOGGER_MAX_MESSAGE_LENGTH: Maximum length of log messages. * - ADVANCED_LOGGER_FLUSH_INTERVAL_MS: Interval in milliseconds for periodic file flushing (default: 5000ms). - * - ADVANCED_LOGGER_FLUSH_ON_ERROR: Enable immediate flush on ERROR and FATAL log levels (default: 1 = enabled). + * - ADVANCED_LOGGER_FLUSH_ON_ERROR: Enable immediate flush on specified log level and above (default: 1 = enabled). + * - ADVANCED_LOGGER_FLUSH_LOG_LEVEL: Log level that triggers immediate flush when FLUSH_ON_ERROR is enabled (default: ERROR). * * Usage: * In platformio.ini: build_flags = -DADVANCED_LOGGER_ALLOCABLE_HEAP_SIZE=10240 @@ -73,6 +74,10 @@ #define ADVANCED_LOGGER_FLUSH_ON_ERROR 1 // 1 = enabled, 0 = disabled #endif +#ifndef ADVANCED_LOGGER_FLUSH_LOG_LEVEL + #define ADVANCED_LOGGER_FLUSH_LOG_LEVEL LogLevel::ERROR // Default to ERROR level +#endif + /* * Compilation flags to conditionally disable logging: From fe6b0d29c58d5749d21658a394e7cf58c1aaf3ce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Sep 2025 21:23:35 +0000 Subject: [PATCH 4/4] Simplify flush configuration by removing FLUSH_ON_ERROR define Co-authored-by: jibrilsharafi <83494924+jibrilsharafi@users.noreply.github.com> --- README.md | 3 +-- src/AdvancedLogger.cpp | 7 +------ src/AdvancedLogger.h | 7 +------ 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e3ee612..773c2dd 100644 --- a/README.md +++ b/README.md @@ -96,13 +96,12 @@ Configure when log files are flushed to ensure data persistence: ```cpp #define ADVANCED_LOGGER_FLUSH_INTERVAL_MS 5000 // Flush every 5 seconds (default) -#define ADVANCED_LOGGER_FLUSH_ON_ERROR 1 // Enable immediate flush on errors (default) #define ADVANCED_LOGGER_FLUSH_LOG_LEVEL LogLevel::ERROR // Log level that triggers immediate flush (default) #include "AdvancedLogger.h" ``` -The library automatically flushes files periodically and on critical log levels to prevent data loss during power cycles or crashes. +The library automatically flushes files periodically and on the specified log level to prevent data loss during power cycles or crashes. ### Callbacks Register a function to handle log entries: diff --git a/src/AdvancedLogger.cpp b/src/AdvancedLogger.cpp index 5a5ca1e..f7a19ba 100644 --- a/src/AdvancedLogger.cpp +++ b/src/AdvancedLogger.cpp @@ -339,12 +339,7 @@ namespace AdvancedLogger #ifndef ADVANCED_LOGGER_DISABLE_FILE_LOGGING if (entry.level >= _saveLevel) { // Determine if immediate flush is needed based on log level - bool forceFlush = false; -#if ADVANCED_LOGGER_FLUSH_ON_ERROR - if (entry.level >= ADVANCED_LOGGER_FLUSH_LOG_LEVEL) { - forceFlush = true; - } -#endif + bool forceFlush = (entry.level >= ADVANCED_LOGGER_FLUSH_LOG_LEVEL); _save(messageFormatted, forceFlush); } #endif diff --git a/src/AdvancedLogger.h b/src/AdvancedLogger.h index a2bb111..3823a1d 100644 --- a/src/AdvancedLogger.h +++ b/src/AdvancedLogger.h @@ -34,8 +34,7 @@ * - ADVANCED_LOGGER_TASK_CORE: Core ID for the log processing task. * - ADVANCED_LOGGER_MAX_MESSAGE_LENGTH: Maximum length of log messages. * - ADVANCED_LOGGER_FLUSH_INTERVAL_MS: Interval in milliseconds for periodic file flushing (default: 5000ms). - * - ADVANCED_LOGGER_FLUSH_ON_ERROR: Enable immediate flush on specified log level and above (default: 1 = enabled). - * - ADVANCED_LOGGER_FLUSH_LOG_LEVEL: Log level that triggers immediate flush when FLUSH_ON_ERROR is enabled (default: ERROR). + * - ADVANCED_LOGGER_FLUSH_LOG_LEVEL: Log level that triggers immediate flush (default: ERROR). * * Usage: * In platformio.ini: build_flags = -DADVANCED_LOGGER_ALLOCABLE_HEAP_SIZE=10240 @@ -70,10 +69,6 @@ #define ADVANCED_LOGGER_FLUSH_INTERVAL_MS 5000 // Flush every 5 seconds #endif -#ifndef ADVANCED_LOGGER_FLUSH_ON_ERROR - #define ADVANCED_LOGGER_FLUSH_ON_ERROR 1 // 1 = enabled, 0 = disabled -#endif - #ifndef ADVANCED_LOGGER_FLUSH_LOG_LEVEL #define ADVANCED_LOGGER_FLUSH_LOG_LEVEL LogLevel::ERROR // Default to ERROR level #endif