Zero-copy parser and interactive TUI viewer for FIX (Financial Information eXchange) logs, in Rust. Built to chew through millions of FIX messages efficiently — zero-copy from the mmapped file all the way to the rendered output — with a fast local TUI in the spirit of fixparser.targetcompid.com.
It auto-detects the log layout (separator, line prefix, encoding) instead of assuming one format, so the same binary handles raw QuickFIX logs, pipe-rendered logs, and logs wrapped in timestamp/logback prefixes. Dictionaries cover FIX 4.4, FIXT.1.1, FIX 5.0, 5.0 SP1 and 5.0 SP2.
flowchart LR
F[("FIX log<br/>(mmap)")] --> S["sniff<br/>separator · prefix · encoding"]
S --> P["parse<br/>zero-copy 8=FIX scan"]
P --> R["resolve<br/>tags → names"]
P --> I["index<br/>rayon · hot-tag map"]
I --> Q["query · grep · --follow"]
R --> O["CLI render · TUI · analysis"]
Q --> O
I --> O
Requires a recent stable Rust toolchain (tested with 1.95, edition 2024; pinned in
rust-toolchain.toml).
git clone <repo> fixlog && cd fixlog
cargo build --release -p fixlog-cli # binary → target/release/fixlog
cargo install --path crates/fixlog-cli # …or install `fixlog` into ~/.cargo/binExamples assume alias fixlog=./target/release/fixlog (or that you ran cargo install).
fixlog sniff fixtures/synthetic/minimal_4.4.log # what layout is this log?
fixlog parse fixtures/synthetic/minimal_4.4.log --first 5
fixlog tui fixtures/real/fix44-om.log # interactive viewer (press : help)
fixlog grep live.log --filter "35=8 AND 55=AAPL" -F # tail -f, filtered
fixlog orders consolidate logs/*.log logs/*.log.gz # aggregate fills across rotated logs| Command | What it does | Deep dive |
|---|---|---|
sniff / parse / stats |
Detect layout, print resolved messages (pretty/JSON), summarize a file. | parsing & format |
grep (-F/--follow) |
Filter with a grep-style DSL (35=D AND 55=AAPL, 55~^MS); tail live files. |
query, grep & tailing |
tui |
Interactive viewer: virtual list, resolved detail, live filter, search, overlays, export. | interactive TUI |
sessions / orders (+ consolidate) / histogram |
Session gaps, order lifecycle (Gantt), consolidated fills across .gz/stdin, temporal histogram. |
analysis & consolidation |
fixlog tui also reads from a pipe (rg "35=D" *.log | fixlog tui) and takes --sort natural|seq|transact|sending. Inside the TUI, press ? or :help for the full keybinding
cheatsheet. Filter DSL: =, !=, ~ (regex), combined with AND/OR/NOT and parens
(precedence NOT > AND > OR); tag numbers only. JSON output is JSONL, pipe-friendly to jq.
| Aspect | Support |
|---|---|
| FIX versions | 4.4, FIXT.1.1 (session) + 5.0 / 5.0 SP1 / 5.0 SP2 (application) |
| Separator | SOH (\x01), |, ^, ; — auto-detected |
| Line prefix | any (timestamp, logback, PID…) — the parser scans for 8=FIX |
| Line ending | LF, CRLF |
| Encoding | UTF-8 / ASCII (non-UTF-8 bytes shown lossy) |
| Invalid checksums | non-fatal — the message is still emitted, logged at -vv |
Adding a FIX version is ~10 lines: drop the QuickFIX XML into dictionaries/ and register it in
crates/fixlog-dict/build.rs.
Parse ~1 GiB/s on long messages; parallel index build up to ~5× single-thread; TUI frame ~737 µs
on 1M messages (~22× under the 16 ms budget); hot-tag equality filters ~156 µs (~3000× vs full
scan). Full, per-phase benchmark tables live in
docs/agent/state.md.
docs/architecture.md— code layout, crate graph, data flow, key libraries, gotchas.docs/runbook.md— build, install, run, env vars, troubleshooting.docs/conventions.md— code style, errors, testing, commits.docs/features/— per-capability docs (the table above links into these).docs/agent/— dense, LLM-facing internals per crate;state.mdis authoritative on current status and backlog.
cargo run -p fixlog-cli -- tui <file> # run without installing
cargo test --all # full suite
cargo clippy --all-targets --all-features -- -D warnings # lint (must be clean)
cargo fmt --all
cargo bench -p fixlog-parser --bench parse # benches: parser / index / frameFixtures: fixtures/synthetic/ is versioned for golden tests; fixtures/real/ and
fixtures/orders/ hold real logs and are gitignored (never commit FIX data). See
fixtures/README.md.
MIT OR Apache-2.0.