firmware-base/docs/CircularLogPrinter.md

4.2 KiB

title description keywords
CircularLogPrinter A thread-safe circular buffer logger for ESP32 applications
logger
esp32
circular buffer
thread-safe
logging

CircularLogPrinter

Path: 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

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.

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:

// 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