Skip to content

XenotriX/jnav

Repository files navigation

jnav

A TUI viewer and navigator for structured log files.

screenshot

Install

uv tool install jnav

or

pipx install jnav

Usage

# Open a log file
$ jnav app.log

# Follow the file for new entries (like tail -f)
$ jnav --follow app.log

# Pipe JSONL from stdin
$ cat logs.jsonl | jnav

Features

Filtering

Filters use jq expressions. Clauses are organized in a tree of AND/OR groups, which gets compiled into a single jq expression used to evaluate each entry.

.level == "error"                                   # exact match
.data.user_id | IN("abc123", "def456", "ghi789")    # match any of
.message | contains("timeout")                      # substring
.message | test("connection (refused|reset)")       # regex
.status >= 500                                      # numeric comparison
.items | any(.name == "widget")                     # list predicate
filtering.mp4

Selected Fields

Selectors are jq expressions evaluated per entry, rendered inline next to the summary. They can index arrays, aggregate, or reshape strings.

.status                                # plain field
.items[0].name                         # array index
.items | length                        # computed
.items | map("\(.name): \(.qty)")      # string interpolation over a list
.build | split("-")[1] | tonumber      # extract a number from a string
.request.headers.user_agent            # deep path

Add from the detail panel with s, or open the selectors manager with S to add, edit, reorder, and toggle them.

selectors.mp4

JSON String Expansion

Values that are JSON-encoded strings (e.g. "data": "{\"key\": \"value\"}") are automatically parsed and displayed as nested objects. The tree view shows "{}" in italic to distinguish them from real objects. Filters and selectors work through expanded JSON strings transparently.

Live Tailing

With --follow, jnav watches the file for new lines (like tail -f). New entries are parsed, filtered, and appended to the view. If you're at the bottom of the list, it auto-scrolls to show new entries.

Session Persistence

Filters, selected fields, scroll position, panel state, and search terms are saved when you quit and restored when reopening the same file. State is stored in ~/.local/share/jnav/.

Keybindings

Navigation

Key Action
j / k Move up/down
gg / G Jump to first/last entry
Ctrl+D / Ctrl+U Half-page scroll
h / l Focus list / detail panel
Enter Inspect entry (open detail)
Escape Back

Search and Filter

Key Action
/ Search (highlights matches, does not hide entries)
n / N Next / previous search match
F Filter manager (jq expressions)
ft Quick text filter
fp Pause / resume filters
Escape Clear search
r Reset filters, fields, and search

Display

Key Action
S Selected fields manager
vi Toggle inline expanded tree in list rows
d Toggle detail panel
? Help
q Quit

Detail Panel

Key Action
s Select (or deselect) the field
ff Filter by value of the highlighted field
fn Filter: entries that have this field
ve View the value in $EDITOR
vo Show only selected fields

Filter Manager

Key Action
a Add filter clause
g Add group
e Edit clause
d / y / p Cut / yank / paste
t Enable / disable
o Toggle AND / OR on a group
n Negate
c Flatten group
r Rename
Escape Close

Selected Fields Manager

Key Action
a Add selector
e Edit selector
d / y / p Cut / yank / paste
t Enable / disable
Escape Close

Credits

  • lnav: the main inspiration: an interactive log viewer with structured querying
  • hl: shaped several design decisions around how JSON log entries should look
  • Open Color: the palette the theme is built on

See also

  • jnv: an interactive JSON filter and jq query builder. Similar name, different tool. jnv is for constructing jq queries against JSON documents, jnav is for navigating JSONL log streams.

About

A TUI viewer and navigator for structured log files.

Resources

License

Stars

Watchers

Forks

Contributors