TermUI.Widgets.LogViewer (TermUI v0.2.0)

View Source

LogViewer widget for displaying real-time logs with virtual scrolling.

LogViewer efficiently displays large log files (millions of lines) using virtual scrolling, with support for search, filtering, syntax highlighting, and bookmarking.

Usage

LogViewer.new(
  lines: log_lines,
  tail_mode: true,
  highlight_levels: true
)

Features

  • Virtual scrolling for efficient rendering of large datasets
  • Tail mode for live log monitoring
  • Search with regex support and match highlighting
  • Syntax highlighting for log levels and timestamps
  • Filtering by level, source, or pattern
  • Line bookmarking
  • Selection and copy functionality
  • Wrap/truncate toggle for long lines

Keyboard Controls

  • Up/Down: Move cursor
  • PageUp/PageDown: Scroll by page
  • Home/End: Jump to first/last line
  • /: Start search
  • n/N: Next/previous search match
  • f: Toggle filter mode
  • b: Toggle bookmark on current line
  • B: Jump to next bookmark
  • t: Toggle tail mode
  • w: Toggle wrap mode
  • Space: Start/extend selection
  • Escape: Clear search/filter/selection

Summary

Functions

Adds a single log line to the viewer.

Adds multiple log lines to the viewer.

Clears all log lines.

Clears the current filter.

Gets the list of bookmarked line indices.

Gets the current search matches.

Gets the currently selected text.

Jumps to a specific line number.

Gets the total number of lines.

Creates new LogViewer widget props.

Starts a search with the given pattern.

Sets a filter on the log viewer.

Checks if tail mode is enabled.

Gets the number of visible lines (after filtering).

Types

filter_spec()

@type filter_spec() :: %{
  levels: [log_level()] | nil,
  source: String.t() | nil,
  pattern: Regex.t() | String.t() | nil,
  bookmarks_only: boolean()
}

log_entry()

@type log_entry() :: %{
  id: non_neg_integer(),
  timestamp: DateTime.t() | nil,
  level: log_level() | nil,
  source: String.t() | nil,
  message: String.t(),
  raw: String.t()
}

log_level()

@type log_level() ::
  :debug | :info | :notice | :warning | :error | :critical | :alert | :emergency

search_state()

@type search_state() :: %{
  pattern: Regex.t() | String.t(),
  matches: [non_neg_integer()],
  current_match: non_neg_integer(),
  highlight: boolean()
}

Functions

add_line(state, line)

@spec add_line(map(), String.t() | log_entry()) :: map()

Adds a single log line to the viewer.

add_lines(state, new_lines)

@spec add_lines(map(), [String.t() | log_entry()]) :: map()

Adds multiple log lines to the viewer.

clear(state)

@spec clear(map()) :: map()

Clears all log lines.

clear_filter(state)

@spec clear_filter(map()) :: map()

Clears the current filter.

get_bookmarks(state)

@spec get_bookmarks(map()) :: [non_neg_integer()]

Gets the list of bookmarked line indices.

get_search_matches(state)

@spec get_search_matches(map()) :: [non_neg_integer()]

Gets the current search matches.

get_selected_text(state)

@spec get_selected_text(map()) :: String.t()

Gets the currently selected text.

goto_line(state, line_num)

@spec goto_line(map(), non_neg_integer()) :: {:ok, map()}

Jumps to a specific line number.

line_count(state)

@spec line_count(map()) :: non_neg_integer()

Gets the total number of lines.

new(opts)

@spec new(keyword()) :: map()

Creates new LogViewer widget props.

Options

  • :lines - Initial log lines (strings or log entries)
  • :max_lines - Maximum lines to keep in buffer (default: 100_000)
  • :tail_mode - Auto-scroll to new lines (default: true)
  • :wrap_lines - Wrap long lines (default: false)
  • :show_line_numbers - Display line numbers (default: true)
  • :show_timestamps - Display timestamps column (default: false)
  • :show_levels - Display level column (default: true)
  • :highlight_levels - Color-code by level (default: true)
  • :on_select - Callback when lines are selected
  • :on_copy - Callback when copy is requested
  • :parser - Custom log parser function

search(state, pattern)

@spec search(map(), String.t()) :: map()

Starts a search with the given pattern.

set_filter(state, filter)

@spec set_filter(map(), filter_spec()) :: map()

Sets a filter on the log viewer.

tail_mode?(state)

@spec tail_mode?(map()) :: boolean()

Checks if tail mode is enabled.

visible_line_count(state)

@spec visible_line_count(map()) :: non_neg_integer()

Gets the number of visible lines (after filtering).