Skip to content

Latest commit

 

History

40 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

slaptrack - OpenLDAP Log Viewer (pure ANSI edition)

An interactive terminal-based log viewer for OpenLDAP (slapd) logs with colorization, filtering, and real-time follow mode — built without ncurses, using only raw ANSI escape sequences.

Same features as the ncurses edition (slaptrack), same architecture, same test suite — the only difference is the rendering layer:

  • ncurses → raw ANSI (ESC[ sequences, alternate screen, SGR mouse)
  • one frame = one big string + a single flush (wrapped in sync ESC[?2026h/l)
  • keyboard + mouse input parsed from raw ESC[/ESC O sequences (no wgetch)
  • terminal restored on exit, including on crashes (SIGSEGV/SIGABRT handlers)

Features

  • Colorized display - Different log components are color-coded for easy reading
  • 8 color schemas - F1-F8: Default, Monochrome, Solarized Light, Solarized Dark, Monokai, Nord, Gruvbox, Dracula
  • Compressed logs - Transparent support for .gz, .bz2, .xz (auto-detected by magic bytes)
  • Interactive filtering - Click on connection IDs, thread IDs, DNs, or other tokens to filter
  • Filter chaining - Apply multiple filters in sequence (e.g., filter by conn, then by dn)
  • Token-aware navigation - Cursor highlights entire token, press / to search for current token
  • Follow mode - Real-time monitoring like tail -f with automatic scroll
  • Line numbers - Toggle display with # key
  • Horizontal scroll - ←/→ (or h/l) scroll long lines that exceed the terminal width
  • Mouse support - SGR mouse: scroll wheel navigation, click to move cursor, double-click to filter
  • Search - Full-text search with next/previous navigation
  • Vim-like navigation - Supports hjkl, g/G, and other vim shortcuts
  • Read-only - Safe for viewing production logs
  • Streaming architecture - Handles huge files efficiently with on-demand parsing
  • No ncurses dependency - only zlib/bzip2/xz + a POSIX terminal

Building

make clean && make          # Makefile (colorized output; QUIET=true to disable colors)
make test                   # run the unit tests (43 tests)
make banner                 # print the ANSI logo

CMake is also supported:

cmake -S . -B build-cmake && cmake --build build-cmake

Usage

./build/slaptrack [-f] [--log-format <fmt>] <logfile>

Options

  • -f - Follow mode (like tail -f), automatically shows new lines as they're written
  • --log-format <fmt> - Input log format: auto, debug, syslog-utc, syslog-local, rfc3339 (default: auto)
    • auto - Per-line detection: decodes the debug hex epoch prefix and syslog timestamps (as UTC), leaves the rest untouched
    • debug - OpenLDAP debug/access log: <sec>.<frac> <thread-id> ... (hex epoch) decoded to RFC3339 UTC
    • syslog-utc - %b %d %H:%M:%S syslog timestamps decoded as UTC
    • syslog-local - same, but decoded as local time
    • rfc3339 - no conversion (the default for existing logs)

Examples

# View a log file
./build/slaptrack logs/slapd_2.6.log

# Follow a log file in real-time
./build/slaptrack -f logs/slapd_2.6.log

# Decode an epoch-prefixed debug log (olcLogFileFormat debug output)
./build/slaptrack --log-format debug logs/slapd_debug.log

# Decode syslog-format access log as UTC on stdin
tail -f /var/log/slapd/access.log | ./build/slaptrack - --log-format syslog-utc

Controls

Navigation

Key Action
↑/↓ or j/k Move cursor up/down
←/→ or h/l Move cursor left/right
Page Up/Down Scroll by page
Home/End or g/G Go to top/bottom
Mouse scroll Scroll up/down (3 lines per tick)
Mouse click Move cursor to position

Filtering

Key Action
Enter Filter by token under cursor
Esc or Backspace Remove last filter (undo)
(at leftmost) Remove last filter
h (at leftmost) Remove last filter
Mouse double-click Filter by token at position

Search

Key Action
/ Search (pre-filled with current token)
n Next search result
N Previous search result

Display

Key Action
F1-F8 Switch color schema
# Toggle line numbers
q Quit

Color Legend (Default schema)

Color Component
Blue Timestamp
Yellow Connection ID (conn=)
Purple Operation ID (op=)
Purple Thread ID (0x...)
Green Distinguished Name (dn=)
Yellow Filter expression
Blue IP Address
Red Error code
Blue (bold) Keywords (BIND, SRCH, RESULT, etc.)

Workflow Examples

Basic Navigation

  1. Open a log file: ./build/slaptrack logs/slapd_2.6.log
  2. Navigate with arrow keys or hjkl
  3. Press # to show line numbers
  4. Press g or G to jump to top/bottom

Filtering by Connection

  1. Navigate to a line with conn=12345
  2. Move cursor onto the connection ID token
  3. Press Enter to filter - now only showing that connection
  4. Press Esc or Backspace to remove the filter

Filtering by Thread

  1. Navigate to a line with a thread ID token (0x..., magenta, at the start of debug-format lines)
  2. Move cursor onto the thread ID token
  3. Press Enter to filter - now only showing lines from that slapd thread
  4. Press Esc or Backspace to remove the filter

Chained Filtering

  1. Filter by connection ID (conn=12345)
  2. Navigate to a line with dn="uid=user,dc=example"
  3. Press Enter to add another filter
  4. Now showing only that connection AND that DN
  5. Press Esc twice to remove both filters

Real-time Monitoring

  1. Open with follow mode: ./build/slaptrack -f logs/slapd_2.6.log
  2. Automatically scrolls to bottom and shows new lines
  3. Navigate up to review history (disables auto-scroll)
  4. Press G to jump to bottom and re-enable auto-scroll

Token-based Search

  1. Navigate to any token (conn, dn, op, etc.)
  2. Press / - search is pre-filled with that token's value
  3. Press Enter to search
  4. Use n/N to navigate results

Architecture

Rendering (ANSI methodology)

  • No ncurses - the whole UI is built from raw ESC[ sequences: Fx (SGR styles), Mv (cursor movement), Term (alternate screen, mouse modes, sync start/end, termios raw mode)
  • One frame = one string - renderFrame() builds the entire screen into a single std::string, flushFrame() writes it once wrapped in ESC[?2026h / ESC[?2026l (synchronized output), then a single flush
  • UTF-8 aware - column math uses ulen/wide_ulen (wcwidth), so wide glyphs don't break layout
  • Input parsing - Input::pollKey() reads raw bytes and parses ESC[/ESC O sequences (arrows, F1-F8, PageUp/Down, Home/End) plus SGR mouse (ESC[<b;x;yM/m, wheel = buttons 64/65, motion = bit 5)
  • Crash-safe restore - SIGSEGV/SIGABRT/SIGBUS/SIGFPE handlers call Term::restore() before re-raising, so the terminal is never left raw
  • Resize - SIGWINCH handler triggers Term::refresh() + full redraw

Streaming Design

  • LogIndex - Builds byte-offset index for fast random access (~11MB for 1.37M lines)
  • LogBuffer - Keeps only ~2000 parsed lines in memory around current view
  • On-demand parsing - Lines are parsed only when needed
  • Prefetching - Loads lines ahead as you scroll

Performance

  • Startup: ~0.15s for 214MB file (index build)
  • Memory: ~25MB vs loading entire file into memory
  • Scrolling: Instant, lines parsed on-demand
  • Follow mode: Uses inotify for efficient file monitoring
  • Connection filtering: Single conn= filter on an empty filter stack takes the fast path — it range-scans the raw lines around the cursor with grouped disk reads (no full-file regex parse), so a filter on a 1.37M-line log applies in ~0.5s instead of seconds. Chained filters still go through the full filtered-index rebuild.

Requirements

  • C++17 compiler (GCC 8+, Clang 5+)
  • Linux (uses inotify for follow mode)
  • No ncurses - only a POSIX terminal (xterm-256color / tmux / kitty / etc.)
  • zlib, bzip2, and xz/lzma development libraries (for compressed log support)

Install dependencies per distribution

Distribution Command
Fedora / RHEL 9+ sudo dnf install gcc-c++ zlib-devel bzip2-devel xz-devel
RHEL 8 (EPEL) sudo dnf install gcc-toolset-12-gcc-c++ zlib-devel bzip2-devel xz-devel
Debian / Ubuntu sudo apt install g++ zlib1g-dev libbz2-dev liblzma-dev
Arch / Manjaro sudo pacman -S gcc zlib bzip2 xz
openSUSE Leap/Tumbleweed sudo zypper install gcc-c++ zlib-devel libbz2-devel xz-devel
Alpine sudo apk add g++ zlib-dev bzip2-dev xz-dev

Project Structure

slaptrack/
├── Makefile             # Colorized build (section 13 of the ANSI methodology)
├── CMakeLists.txt       # Alternative build (single source of truth for version)
├── ansi_banner.utf8     # ANSI logo (256-color gradient), printed by `make banner`
├── src/
│   ├── main.cpp         # Entry point, argument parsing, compression dispatch, crash handlers
│   ├── ansi.hpp         # Fx / Mv / Term namespaces (raw ANSI primitives)
│   ├── utf8.h/cpp       # UTF-8 width-aware helpers (ulen, wide_ulen, ljust/rjust, uresize)
│   ├── symbols.hpp      # Box-drawing / TTY fallback symbols
│   ├── theme.h/cpp      # 8 color schemas, Theme::c(), truecolor gradient, hexToColor
│   ├── widgets.h/cpp    # Draw::createBox, Meter, progressBar (with caches)
│   ├── input.h/cpp      # Raw keyboard + SGR mouse parsing (replaces wgetch)
│   ├── viewer.h/cpp     # TUI rendering (frame = one string) and interaction
│   ├── compressed_io.h/cpp # Magic-byte detection + gzip/bzip2/xz decompression
│   ├── log_parser.h/cpp # Log parsing and tokenization
│   ├── log_index.h/cpp  # File indexing for random access
│   ├── log_buffer.h/cpp # Rolling window buffer
│   └── filter.h/cpp     # Filter management
└── tests/               # Unit tests (test_log_parser, test_filter)

Compressed Log Handling

When given a file, slaptrack reads the first bytes to detect the compression format rather than trusting the filename extension. The supported formats are:

Magic bytes Format
1F 8B gzip (.gz)
42 5A 68 (BZh[1-9]) bzip2 (.bz2)
FD 37 7A 58 5A 00 xz (.xz)

On detection, the file is fully decompressed into a uniquely-named temp file under /tmp (via mkstemp(3)), the TUI is built on that file, and the temp file is removed on exit (including on SIGINT / SIGTERM via atexit(3)).

License

AGPL-3.0

About

A C++ ncurses TUI viewer for OpenLDAP slapd access logs with colorised display, interactive filtering, follow mode, compressed log support, and 8 switchable color schemas.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages