122 lines
4.2 KiB
Markdown
122 lines
4.2 KiB
Markdown
---
|
|
title: CircularLogPrinter
|
|
description: A thread-safe circular buffer logger for ESP32 applications
|
|
keywords: [logger, esp32, circular buffer, thread-safe, logging]
|
|
---
|
|
|
|
# CircularLogPrinter
|
|
|
|
**Path**: [`src/Logger.h`](../src/Logger.h)
|
|
|
|
**Revision History**: Initial documentation
|
|
|
|
CircularLogPrinter is a high-performance, thread-safe logging utility designed for ESP32 applications. It maintains a configurable circular buffer of log messages in memory while optionally mirroring output to a Serial or other Print-compatible stream. The implementation is compliant with MISRA/CPPCHECK standards, avoiding reinterpret casts for improved safety.
|
|
|
|
## Requirements
|
|
|
|
### Hardware
|
|
- No specific hardware pins required
|
|
- Compatible with ESP32 platforms
|
|
|
|
### Software
|
|
- Arduino framework
|
|
- FreeRTOS (for thread-safety features)
|
|
- ESP-IDF (for ESP log integration)
|
|
|
|
## Features
|
|
|
|
- Configurable circular buffer for storing the last N log lines
|
|
- Thread-safe operation (optional via configuration)
|
|
- Ability to redirect ESP-IDF logging macros (ESP_LOGx) into this printer
|
|
- MISRA/CPPCHECK compliant implementation with no pointer type casting
|
|
- Memory-efficient design with fixed buffer sizes
|
|
- Optional output mirroring to any Arduino Print-compatible stream
|
|
|
|
## Dependencies
|
|
|
|
- [Arduino.h](https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Arduino.h)
|
|
- [Print.h](https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Print.h)
|
|
- [esp_log.h](https://github.com/espressif/esp-idf/blob/master/components/log/include/esp_log.h)
|
|
|
|
```mermaid
|
|
graph TD
|
|
CircularLogPrinter --> Print
|
|
CircularLogPrinter --> Arduino
|
|
CircularLogPrinter --> esp_log
|
|
```
|
|
|
|
## Behaviour
|
|
|
|
The CircularLogPrinter maintains a circular buffer of log lines. When the buffer is full, new log entries overwrite the oldest entries. Log entries are committed when a newline character is encountered or when the maximum line length is reached.
|
|
|
|
```mermaid
|
|
stateDiagram-v2
|
|
[*] --> Initialize: Constructor
|
|
Initialize --> Ready
|
|
Ready --> AppendChar: write(byte)
|
|
Ready --> AppendMultipleChars: write(buffer, size)
|
|
AppendChar --> CommitLine: If newline
|
|
AppendChar --> AppendChar: If not newline
|
|
AppendMultipleChars --> CommitLine: If newline encountered
|
|
AppendMultipleChars --> Ready: After processing
|
|
CommitLine --> Ready
|
|
Ready --> Clear: clear() called
|
|
Clear --> Ready
|
|
```
|
|
|
|
## TODOs
|
|
|
|
### Performance
|
|
|
|
- Consider using a more efficient memory layout for the circular buffer
|
|
- Evaluate the impact of thread-safety mechanisms on performance in high-frequency logging scenarios
|
|
- Add compile-time options to disable features not needed for specific applications
|
|
|
|
### Security
|
|
|
|
- Add configurable log level filtering to prevent sensitive information leakage
|
|
- Consider adding encryption options for logs containing sensitive information
|
|
- Implement log rotation to persistent storage for critical deployments
|
|
|
|
### Compliance
|
|
|
|
- The implementation is already MISRA/CPPCHECK compliant by avoiding pointer type casting
|
|
- Consider adding support for standardized log formats like RFC5424
|
|
|
|
### Recommendations
|
|
|
|
- Use reasonable buffer sizes to avoid excessive memory usage
|
|
- Consider the performance impact of thread-safety in high-frequency logging scenarios
|
|
- When using with ESP-IDF logging, ensure consistent configuration across components
|
|
- For production environments, implement a strategy for persistent log storage
|
|
|
|
## Example
|
|
|
|
This example shows how to initialize and use the CircularLogPrinter:
|
|
|
|
```cpp
|
|
// Create a CircularLogPrinter that mirrors to Serial
|
|
CircularLogPrinter logger(&Serial);
|
|
|
|
// Clear the buffer
|
|
logger.clear();
|
|
|
|
// Write some logs
|
|
logger.println("Starting application...");
|
|
logger.printf("System initialized with version: %s", VERSION);
|
|
|
|
// Attach to ESP-IDF logging
|
|
logger.attachToEspLog();
|
|
|
|
// Now ESP_LOGx macros will also be captured
|
|
ESP_LOGI("TAG", "This will be captured by the CircularLogPrinter");
|
|
|
|
// Retrieve a specific line from history (0 is most recent)
|
|
const char* lastLine = logger.getLine(0);
|
|
```
|
|
|
|
### References
|
|
|
|
- [ESP-IDF Logging Library](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/log.html)
|
|
- [Arduino Print Class](https://www.arduino.cc/reference/en/language/functions/communication/serial/print/)
|