Files
2026-08-06 10:18:22 -04:00

80 lines
3.4 KiB
Markdown

# vif-log
A high-performance, terminal-based JSONL diagnostic log viewer engineered for the `vi-fighter` ECS game engine.
Designed to parse and navigate high-frequency ECS event streams and state snapshots with minimal overhead. Features zero-allocation index passes, lazy-loaded line evaluation, and asynchronous chronological merging of multiple log sources.
## Core Architecture
* **Zero-Alloc Indexing**: Hand-rolled RFC3339Nano parser and JSON tokenizer (`internal/logfile`). Constructs a pointer-free 48-byte `Meta` struct per record. Raw JSON strings are interned to bitset-friendly integer IDs.
* **Asynchronous Render Pipeline**: Background indexers publish lock-free slice headers to the render thread. The UI remains responsive during multi-gigabyte ingestion.
* **Multi-Source K-Way Merge**: Loads multiple `.jsonl` files (e.g., cross-network client/server logs) and performs a stable chronological merge using nanosecond timestamps without mutating the row index.
* **Smart ECS Snapshotting**: High-frequency telemetry (ECS component states pushed per-tick) are automatically collapsed into single navigable rows (`Filter.Collapse`), expanding on demand.
* **Deferred Evaluation Stack**: The filter chain evaluates index-resident predicates (Tick, Run, Subsystem, Level) first. Costly operations (Regex over raw JSON fields) only trigger for surviving records that enter the sliding read window.
## Build & Run
Requires Go 1.26+ (Wayland environment natively supported via underlying TUI library).
```bash
go build -o vif-log ./cmd/vif-log
```
## Usage
```bash
# Open a specific log file or directory
vif-log path/to/run.jsonl
vif-log ./logs/
# Multi-file merge
vif-log server.jsonl client.jsonl
# Pre-seed filter stack
vif-log -f level:>=WARN -f sub:^(fsm|event)$ -f tick:1000-5000 ./logs/
```
### Predicates (Filters)
Filters stack. Use `\` in the UI or `-f` via CLI.
* `level`: Exact match (`IWE`) or threshold (`>=WARN`).
* `sub` / `msg`: Smart-case regex evaluated against the interned vocabulary.
* `tick` / `run`: Numeric spans (`100-200`, `150-`, `-50`).
* `fields`: Smart-case regex evaluated over the parsed JSON fields.
* `find`: Column-scoped regex search (evaluates against time, tick, sub, msg, or fields).
## Keybindings
### Navigation & UI
| Key | Action |
| :--- | :--- |
| `j` / `k` | Move cursor down/up |
| `gg` / `G` | Jump to first/last record |
| `Ctrl+d` / `Ctrl+u` | Half-page down/up |
| `Tab` / `Shift+Tab`| Cycle column focus |
| `s` | Sort by focused column (asc/desc/off) |
| `J` / `K` | Scroll detail pane down/up |
| `Enter` | Expand/collapse ECS stat snapshot |
| `n` / `N` | Jump to next/prev snapshot head |
| `Ctrl+l` | Force redraw |
### Search & Filtering
| Key | Action |
| :--- | :--- |
| `/` | Regex search in the currently focused column |
| `\` | Add/replace a filter in the stack (e.g., `msg:transition`) |
| `f` / `F` | Follow: Jump to next/prev record with identical `sub`/`msg`/context |
| `t` `d` `i` `w` `e` `p` `b` | Toggle visibility of exact log levels |
| `1`-`5` | Set minimum level threshold (1=TRACE, 5=ERROR) |
| `<` / `>` | Lower/Raise level threshold |
| `Esc` | Clear search and dynamic filters |
### Buffer & File Management
| Key | Action |
| :--- | :--- |
| `Space` | Toggle pin on current record |
| `P` | Toggle pinned-only view |
| `C` | Clear all pins |
| `o` | Open file browser (supports multi-select with `Space`) |
| `x` | Export current view (or pins) to a new `.jsonl` file |