-
Notifications
You must be signed in to change notification settings - Fork 3
RaftRemoteLogging
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.
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
}
]
}| 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": { }
}
}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.
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
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
- 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
-lto save the session to a timestamped file in the log folder -
Custom port — use
-pto connect to a non-default port
Press ESC or Ctrl+C to exit.
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.
The LogManager provides a REST API for managing loggers at runtime. All endpoints use HTTP GET.
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
}
]
}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
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
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
Loggers can be identified by:
-
Type name (case-insensitive):
RaftRemote,Loki,Papertrail -
Index (zero-based):
0,1, etc. — in the order they appear in thelogDestsarray
The RaftRemote logger uses a two-stage design for thread safety:
-
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. -
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.
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.
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.
- 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