Skip to the content.

MTR session recording v1

--mtr-record FILE explicitly records the current CLI MTR session in all three builds. TUI, non-TTY tables, report/wide, RAW and MTR JSON can be recorded. The file is independent of stdout and of the existing MTR JSON v1 contract. Existing NDJSON streams and final JSON reports are not replay files.

Recording

nexttrace --mtr --mtr-record session.jsonl example.com
nexttrace -w -q 10 --mtr-record report-session.jsonl example.com
nexttrace --mtr --json -q 10 --mtr-record stream-session.jsonl example.com
ntr --mtr-record session.jsonl example.com

Full and tiny require an explicit MTR mode; ntr defaults to MTR. Traditional traceroute, standalone modes and replay cannot be combined with recording. The file is exclusively created with Unix mode 0600: existing files and symlinks are never overwritten or appended to. The parent directory must exist. Opening the recording precedes network initialization and probing.

Each accepted event is written as a complete UTF-8 JSON line. A failed encode or write cancels probing. The file is synchronized and closed at the end, and sync/close errors are reported as failures. The first session error and its stage take precedence over later recording start or finish errors. When file writes already failed, no complete error end record is guaranteed. No events are silently dropped. There is no rotation, compression, append mode, or periodic durable checkpoint. Crash recovery is limited to complete records that remain readable from disk.

Event contract

Records identify format: "nexttrace-mtr-session" and schema_version: 1. The maximum encoded record size is 1 MiB including its terminating newline. Every record includes type, seq, generation, elapsed_ns, and timestamp.

Type Payload
start session: software version, target, resolved IP, protocol, start time, effective parameters, source display information and initial display settings
probe probe: counted TTL, IP/Host, success, integer rtt_ns, completed_at, complete available Geo/MPLS and response details; iteration retains scheduler meaning
metadata metadata: IP and applied Host/Geo updates, without counting another probe
pause, resume Changes actually observed by the scheduler; pending probe results may still follow pause
reset New generation; clears current statistics, path evidence and history
path_end path_end: destination/unreachable/max-hops conclusion, or explicit null for reopening
end end: end time, reason, final path conclusion and optional error/signal

The end time must equal its record timestamp, and the final path must match the reconstructed state. completed has no error or signal; interrupted has no error and optionally SIGINT or SIGTERM; error requires a nonempty error stage/message and no signal. Metadata events must actually update an existing responder. Probe TTLs stay within the configured range, and bounded sessions may not exceed max_per_hop in any generation. A max_hops event requires all configured TTLs to have completed that count. Reset clears these counts. Contradictory or unapplied events are rejected.

When present, a probe’s response.kind must be transit, destination, or unreachable; empty or unknown kinds are invalid records. A response also requires success: true and a valid responder IP; timeouts cannot carry path evidence.

Replay verifies destination, unreachable and reopening events against the accumulated probe evidence before applying a path boundary. A contradictory event is an error, not an instruction to discard statistics.

Offline JSON always encodes stats as an array, including [] for empty sessions, initialization failures and the state immediately after a reset.

The session header only includes explicitly selected safe fields, not the runtime configuration or provider credentials. Source selection describes the recorded configuration/display, not proof of an operating-system route. Initialization failure can produce a complete empty session with undetermined parameters and an error end record.

Statistics and ordering

Only probes actually accepted into the existing aggregator are recorded. The probe payload contains the final Hop used for aggregation, including synchronous metadata. Later metadata patches update existing rows without changing Snt, RTT statistics or responder order.

Response identity, integer RTT precision, unknown-row merging and synthetic timeouts retain the live aggregator’s semantics. Individual local send retries, unsent time during pause and in-flight probes discarded by cancellation are not converted into additional timeout records.

The triggering probe precedes its path_end event. A confirmed destination clears statistics above its TTL. A provisional unreachable edge hides those rows; reopening can reveal their earlier statistics. Reset discards late results from the previous generation. It does not remove earlier events from the file.

Offline replay

nexttrace --mtr-replay session.jsonl
nexttrace --mtr-replay session.jsonl -w
nexttrace --mtr-replay session.jsonl -r --json

--mtr-replay --help and --mtr-replay --version need no file. For a file named --help or --version, use --mtr-replay=--help or a path such as ./--help.

Replay accepts presentation options, not a target or probe configuration.

Option Behavior
-r, --report Print the final compact text report
-w, --wide Print the final text report without host truncation
-j, --json Print the offline JSON document, taking precedence over report/wide
--mtr-columns Select text columns; incompatible with JSON
-y, --ipinfo Initial TUI host mode 0..4
--show-ips Display PTR and IP together
-g, --language Display cn or en using recorded metadata
-C, --no-color Disable TUI colors; text reports already have no ANSI
--no-mtr-summary Suppress the text summary after leaving the replay TUI; no effect on non-TTY/report/JSON output

Omitted host mode, PTR/IP display, columns and language inherit the recording’s initial settings; MPLS display also starts from the recorded setting. Live column edits are session-local and are not recorded as replay control events. Explicit -r chooses compact output; without -r/-w, non-TTY output inherits the recorded wide setting. Both source and responder host names are truncated in compact output. No target, --raw, probe options, --mtr-record, stdin (-), pipe or non-regular input file is accepted. It does not initialize probing, resolve addresses, query metadata, or discover a source interface. Recorded missing metadata stays missing. It can run without raw-socket privileges and without network connectivity.

TTY opens paused at the last valid position. Space plays at original speed; at EOF it starts from the beginning. p pauses playback, r rewinds and pauses, q quits. Recorded probe pause and current playback pause are separate states. Host, MPLS, columns and the existing three history charts remain available.

s/S saves the current cumulative statistics as a txt, json, or standalone html snapshot report. The report includes the current playback position and display settings, without historical probe events. Saving does not change playback or recorded pause state and never overwrites a file. Tab switches save fields, Left/Right or Space selects a format, Enter saves, and Esc cancels.

? opens complete help. Up/Down scroll, ? or Esc closes help, and q or Ctrl-C exits. Help does not change playback state. Leaving the TUI restores the terminal and prints a plain-text summary at the current position by default; use --no-mtr-summary to suppress it.

j/J opens elapsed-time input, prefilled with the current position, and pauses. Use HH:MM:SS[.mmm], with hours allowed beyond 23. Enter seeks and stays paused; Esc cancels and stays paused; Backspace deletes and Ctrl-U clears. Invalid or out-of-range input leaves the current position unchanged. Bracketed-paste newlines cannot submit the input.

The history chart shows the three minutes ending at the playback position. The whole file remains available for seeking. Initial loading and seeking scan records sequentially, using the existing aggregator; no full event array or checkpoint index is retained. Seeking is O(N) in the events before the requested position and can be canceled. Memory still depends on distinct responder state and probes inside the current history window. This version does not tail a file that continues growing after it is opened.

Non-TTY or explicit -r/-w produces one final report. --json produces a separate offline document with session information, statistics, path state, playback position and recording completeness, rather than emitting live NDJSON.

Offline JSON fields

The output is one object plus a newline, with schema_version: 1 and type: "mtr_replay". It contains:

Field Meaning
session Original session header and initial display/effective parameters
complete Whether a valid end record was read
cursor_ns, duration_ns Final valid playback position and duration, in nanoseconds
generation, recorded_paused Final reducer generation and recorded probe-pause state
path_end Reconstructed conclusion, or null
stats Final MTR statistics; always an array, including []
end Original end payload, omitted when absent

Replay text/TUI and diagnostics replace Unicode control (Cc) and format (Cf, including bidi overrides and isolates) characters with spaces. Only display copies are sanitized; recorded data and offline JSON retain original values. JSON consumers must apply their own display escaping.

Incomplete and invalid files

A missing end record or an unfinished final JSON line recovers only the complete valid prefix. Text/TUI explicitly identify the recording as incomplete; offline JSON exposes the same state. Incomplete replay exits nonzero, even when some statistics could be recovered. An unsupported version, invalid middle record, oversized record or invalid sequence is an error; records are never skipped to fabricate a complete session.

Normal replay of a complete file exits 0. A complete recording may describe an original session that ended with an error or signal; that historical outcome is retained separately from the current file-read result. Invalid arguments exit 2; file/recording errors exit 1; handled SIGINT/SIGTERM exit 130/143. Diagnostics go to stderr. A completed probe session is not itself a reachability verdict.

Recordings contain target, source and responder addresses and available metadata. Redact those fields before attaching files to a public issue when they identify private infrastructure.

Extended column statistics

Replay recomputes dropped packets, geometric mean and jitter from the recorded successful RTTs in event sequence order, not completion-timestamp order. Existing recordings need no conversion. See column metrics.

The recording schema stays unchanged. A new recording may name additional columns (including space) in display.columns. Older binaries need an explicit supported --mtr-columns selection for text replay of such a recording; JSON replay does not parse display columns. Interactive column edits remain local to the display and do not rewrite the recording’s initial column selection.