Skip to content

RaftRemoteLogging

Rob Dobson edited this page Mar 27, 2026 · 1 revision

Remote Logging (RaftRemote)

Overview

The RaftRemote logger provides real-time log streaming from a Raft device over a TCP connection. It runs a TCP server on the device that clients can connect to in order to receive log output. The same connection also accepts commands, making it a bidirectional debug console.

When no client is connected, the logger has negligible overhead — the ring buffer used for thread-safe log delivery is only allocated when a client connects and freed when it disconnects.

The easiest way to use remote logging is with the RaftCLI raft debug command, but any TCP client (e.g. nc, telnet, or a custom tool) can connect to the configured port.

SysType Configuration

Remote logging is configured through the LogManager SysMod in your SysType JSON. Add a LogManager section with a logDests array containing a RaftRemote entry:

"LogManager": {
    "enable": 1,
    "logDests": [
        {
            "enable": true,
            "type": "RaftRemote",
            "port": 8080
        }
    ]
}

Configuration Fields

Field Type Default Description
enable bool false Enable or disable this log destination
type string Must be "RaftRemote"
port int TCP port to listen on (e.g. 8080)
level string "" (all) Minimum log level: "E", "W", "I", "D", or "V"
pause bool false Start in paused state (can be enabled later via REST API)

The LogManager must also be registered as a SysMod in the SysManager SysMods list:

"SysManager": {
    "SysMods": {
        "LogManager": { }
    }
}

Using RaftCLI for Remote Logging

The RaftCLI provides a debug command that connects to the device's RaftRemote logger over TCP. This gives you a live log stream and an interactive command console — similar to the serial monitor but over WiFi or Ethernet.

Basic Usage

raft debug <IP_ADDRESS_OR_HOSTNAME>

or using the short alias:

raft d <IP_ADDRESS_OR_HOSTNAME>

For example, if your device is at 192.168.1.250:

raft debug 192.168.1.250

Options

Usage: raft debug [OPTIONS] <IP_ADDRESS_OR_HOSTNAME> [APPLICATION_FOLDER]

Arguments:
  <IP_ADDRESS_OR_HOSTNAME>    Device IP address or hostname
  [APPLICATION_FOLDER]        Application folder (optional)

Options:
  -p, --port <PORT>              Port for debugging [default: 8080]
  -l, --log                      Log debug console data to file
  -g, --log-folder <LOG_FOLDER>  Folder for log files [default: ./logs]
  -h, --help                     Print help

Features

  • Real-time log output — device log messages are displayed as they are generated
  • Interactive commands — type REST API commands (e.g. v) and they are sent to the device and the response is displayed
  • Auto-reconnect — if the connection drops, the CLI retries every 5 seconds
  • Command history — use up/down arrow keys to cycle through previously entered commands
  • Log to file — use -l to save the session to a timestamped file in the log folder
  • Custom port — use -p to connect to a non-default port

Press ESC or Ctrl+C to exit.

Log Output Format

The remote log output matches the serial console format:

I (96431) SysMan: {"n":"Axiom009","v":"6ab4b1f",...}
W (97012) NetMan: connection timeout
E (97500) I2C: bus error on addr 0x48

Each line uses the standard ESP-IDF format: LEVEL (timestamp_ms) TAG: message.

REST API

The LogManager provides a REST API for managing loggers at runtime. All endpoints use HTTP GET.

Status — Get All Loggers

GET /api/log

Returns the status of all configured loggers:

{
    "rslt": "ok",
    "loggers": [
        {
            "type": "RaftRemote",
            "level": "I",
            "enabled": 1,
            "connected": 1,
            "port": 8080,
            "maxcount": 60,
            "windowms": 60000,
            "bufsize": 16384
        }
    ]
}

Enable / Disable a Logger

GET /api/log/enable/<name>
GET /api/log/disable/<name>

Enable or disable (pause/unpause) a logger by type name or index. When disabled, log messages are silently dropped.

Examples:

GET /api/log/disable/RaftRemote
GET /api/log/enable/0

Disconnect Client

GET /api/log/disconnect/<name>

Force-disconnect the currently connected TCP client and free the ring buffer. The server continues listening for new connections.

GET /api/log/disconnect/RaftRemote

Configure Logger Parameters

GET /api/log/config/<name>?key=value&key=value

Adjust logger parameters at runtime. All parameters are optional — only those provided are changed.

Parameter Description
level Minimum log level: E, W, I, D, V
maxcount Maximum log messages per rate-limit window
windowms Rate-limit window duration in milliseconds
bufsize Ring buffer size in bytes (takes effect on next client connection)

Examples:

GET /api/log/config/RaftRemote?level=W
GET /api/log/config/RaftRemote?maxcount=120&windowms=30000
GET /api/log/config/RaftRemote?level=D&bufsize=32768

Logger Identification

Loggers can be identified by:

  • Type name (case-insensitive): RaftRemote, Loki, Papertrail
  • Index (zero-based): 0, 1, etc. — in the order they appear in the logDests array

Architecture

The RaftRemote logger uses a two-stage design for thread safety:

  1. log() — called from any task/ISR context: formats the message and pushes it into a FreeRTOS ring buffer (non-blocking, zero-tick timeout). If the buffer is full, the message is silently dropped.

  2. loop() — called from the main task: drains up to 10 messages per iteration from the ring buffer and sends them over the TCP socket.

This separation ensures that logging from any FreeRTOS task or interrupt context never blocks on network I/O.

Rate Limiting

To avoid overwhelming the network or the receiving client, the logger enforces a rate limit: by default, a maximum of 60 messages per 60-second window. Messages exceeding the limit are dropped. These parameters can be adjusted via the REST API.

Backoff on Failure

If a TCP send fails (e.g. the client disconnects unexpectedly), the logger enters a 30-second backoff period during which it stops attempting to send. This prevents repeated blocking send calls from stalling the main loop.

Resource Management

  • The ring buffer (default 16 KB) is only allocated when a client connects and freed when the client disconnects
  • Only one client connection is accepted at a time
  • Individual log messages are truncated to 1024 bytes if they exceed the maximum item size

Clone this wiki locally