lnav is a terminal log file viewer that auto-detects common log formats, merges multiple files into a single timestamp-ordered view, and lets you query log data with SQL.
Merged Timeline View
Point it at several files (or a directory) and it interleaves every line across all of them by timestamp into one scrollable view — no manual correlation needed when debugging an issue that spans, say, an app log and a syslog.
Tailing
Tailing is the default mode, not an opt-in flag: every file passed in is followed live and merged into the same timestamp-ordered view as new lines arrive. Scrolling up to inspect history pauses auto-scroll until you jump back to the bottom, so incoming lines don’t yank you away mid-read. It also tails piped input, e.g. journalctl -f | lnav.
Querying Logs with SQL
Each recognized log format is exposed as a SQLite virtual table (e.g. syslog lines become the syslog_log table), with parsed fields like log_time, log_level, and log_body as columns. Press ; to drop into a SQL prompt and SELECT against that table instead of piping through grep/awk — this also unlocks aggregation (GROUP BY log_level, COUNT(*) for an error/warning tally) and joins across multiple loaded formats on a shared timestamp, which plain text tools can’t do.
Source Filename Visibility
The source filename isn’t a fixed column — it’s revealed by horizontal scrolling. At the start of the message text, scrolling left cycles hidden → shortened filename → full path; scrolling right cycles back, useful when multiple files are tailed together and you need to see (or hide again) which file a line came from.
Format Detection and Pretty-Printing
Common formats (syslog, Apache/nginx access logs, journald, JSON logs, etc.) are recognized automatically and colorized by level. Structured lines (e.g. JSON) can be expanded into a pretty-printed detail view.
Cheatsheet
Open Files
lnav <file1> <file2> # tail and merge multiple files into one timeline
lnav <directory> # open every log file in a directory
journalctl -f | lnav # tail piped inputNavigate
/<regex> # search
n / N # next / previous search match
e / E # next / previous error
w / W # next / previous warning
G # jump to bottom, resume auto-scroll while tailing
h / l # (at start of line) cycle filename: hidden -> short -> full path, and back
q # quit
Query with SQL
;SELECT log_time, log_body FROM syslog_log WHERE log_level = 'error';
List Available Tables
;SELECT name FROM sqlite_master WHERE type='table';
Or press ; then Tab on an empty query to browse via autocomplete.
Filter Lines
:filter-in <regex> # show only matching lines
:filter-out <regex> # hide matching lines
:delete-filter <regex> # remove a filter by its pattern
TAB shifts focus into the visual filter editor: Space toggles a filter on/off, Enter edits it, Shift+D deletes it, t flips it between IN/OUT. Ctrl+R clears every filter at once.
Toggle Views
i # histogram of log volume over time
p # pretty-print / detail view of the selected line
? # full keybinding help