When two heavy requests overlapped, the serve engine left no trace, and clients hit the 30 s timeout without anyone seeing why. The per-request log records one line for each request, so overlap, queueing and slow commands can be found afterwards.
The log is off by default.
memnet serve --request-log PATHor set the environment variable:
MEMNET_REQUEST_LOG=PATHOn the Pi the journal is RAM-only, so the journal does not persist. Use a file under the user's state directory. Create the directory first:
mkdir -p "$HOME/.local/state/memnet"
MEMNET_REQUEST_LOG=$HOME/.local/state/memnet/request.jsonlThe file rotates by size.
MEMNET_REQUEST_LOG_MAX_BYTES: rotate when the file reaches this size. Default10485760(10 MiB).MEMNET_REQUEST_LOG_BACKUPS: number of old files kept. Default3(minimum1), givingPATH.1toPATH.3.
Each line is one JSON object.
| Field | Meaning |
|---|---|
received_ms |
Epoch milliseconds when the request frame was received. |
finished_ms |
Epoch milliseconds when the reply was sent. |
queue_wait_ms |
Time from the frame being fully read until the command starts. Includes drain-gate and session-lock waits (the work clock starts once the session lock is held). |
server_ms |
Time from the command start until the reply is ready. |
op |
Command words only, for example session open or mutate; a leading --version probe is recorded as --version. Never arguments. |
session |
One-way label: s_ plus 8 hex digits of the session id. The engine has no session names, and the real mn_ id is never written. |
bytes_in |
Bytes received in the request. |
bytes_out |
Bytes sent in the reply. |
lines_in |
Lines on stdin for the request. |
lines_out |
Lines on stdout for the reply. |
nodes_touched |
Currently always null. The dispatch layer does not know this. |
outcome |
ok, an @ERR code (usage for an unknown option or command, internal for a crash), error, peer_gone, response_too_large or incomplete_frame. |
conn_id |
Per-connection counter. |
seq |
Request number on that connection. Always 1 today, because the protocol is one request per connection. |
- A line is written after the reply is sent.
- Sink errors are swallowed. One warning is logged.
- Bare connects, such as probes, are not logged.
- No payload text, tokens or ids are written.
- The log applies to TCP
serveand toserve --ipc, which use the same handler. memnet-mcpover HTTP reaches the engine through thisservewhen it uses TCP, so those requests are logged. In-process MCP mode does not go throughserveand is not logged.
{"received_ms":1793000000123,"finished_ms":1793000031456,"queue_wait_ms":1204.0,"server_ms":30120.0,"op":"mutate","session":"s_3f9a1c2e","bytes_in":18342,"bytes_out":211,"lines_in":96,"lines_out":3,"nodes_touched":null,"outcome":"ok","conn_id":57,"seq":1}Requests that waited more than a second in the queue:
jq -c 'select(.queue_wait_ms>1000)' request.jsonl