20 releases
| new 0.2.19 | Dec 29, 2025 |
|---|---|
| 0.2.18 | Dec 29, 2025 |
| 0.1.0 | Dec 11, 2025 |
#105 in Visualization
405KB
1.5K
SLoC
RainbowTerm
Context-aware terminal colorizer with magnitude spectrum visualization for network device output.
๐ธ View Screenshots: Visit the GitHub repository to see the dual spectrum coloring system in action!
Screenshots
Dual Spectrum Coloring in Action
Juniper interface output showing dual spectrum: neutral colors for traffic stats, warm colors for errors
Configuration Diff Highlighting
JunOS configuration diff with syntax highlighting
Overview
RainbowTerm is a high-performance Rust-based terminal colorizer designed for network engineers. It provides intelligent syntax highlighting for network device output with advanced features like dual magnitude spectrum visualization (neutral vs. error-based) and context-aware coloring.
โจ Key Features
๐ Dual Spectrum Coloring System
RainbowTerm uses context-aware coloring with two distinct spectrum systems:
Neutral Spectrum (Cool Colors) - Informational Magnitude
For traffic counters, packet counts, and other metrics where bigger isn't bad:
Input bytes: 1298458 # Green โ Blue โ Purple (millions)
Output packets: 1234567890 # Orange โ Yellow โ Green โ Blue โ Purple (billions)
Input bytes: 2342779625172 # Orange โ Yellow โ Green โ Blue โ Purple (trillions)
Input bytes: 0 # Gray (idle)
- Rightmost 3 digits: Purple (base color)
- Next group (thousands): Blue โ Purple
- Millions: Green โ Blue โ Purple
- Billions: Yellow โ Green โ Blue โ Purple
- Trillions+: Orange โ Yellow โ Green โ Blue โ Purple
- Zero: Gray (idle/no traffic)
Error Spectrum (Warm Colors) - Severity-Based Problems
For errors, drops, and problems where bigger IS bad:
Errors: 724 # Yellow (minor - hundreds)
Drops: 1750520 # Orange โ Yellow (moderate - millions)
Errors: 1234567890 # Magenta โ Dark Red โ Crimson โ Yellow (billions)
Errors: 0 # Green (healthy - no errors!)
- Rightmost 3 digits: Yellow (base color)
- Thousands: Orange โ Yellow
- Ten thousands: Red โ Orange โ Yellow
- Hundred thousands: Dark Red โ Red โ Orange โ Yellow
- Millions: Crimson โ Dark Red โ Red โ Orange โ Yellow
- Billions+: Magenta/Violet โ Crimson โ Dark Red โ Red โ Orange โ Yellow
- Zero errors: Green (healthy state!)
Same number, different meaning, different color - The philosophy behind context-aware coloring.
๐ Automatic Profile Detection
RainbowTerm automatically detects the correct profile based on:
- Banner/MOTD content (e.g., "Versa FlexVNF", "JUNOS", "Cisco IOS")
- CLI prompts (e.g.,
user@hostname>,hostname#) - Interface naming patterns (e.g.,
ge-0/0/0,vni-0/2,GigabitEthernet0/1) - Configurable hostname prefixes (e.g.,
jr,vr,cs)
No flags needed - just pipe and go:
ssh router | rt # Auto-detects from banner/prompt
cat output.txt | rt # Auto-detects from content
๐ง Network Protocol Support
Juniper JunOS
- โ Interface names by speed (ge, xe, et, mge, vcp, ae)
- โ BGP states (Established/Idle)
- โ OSPF states (Full/Down)
- โ STP states (FWD/BLK) and roles (DESG/DIS)
- โ STP port costs with quality indicators
- โ Physical link status (Up/Down)
- โ Duplex modes (Full-duplex/Half-duplex)
- โ Log severity levels (Critical/Warning/Info)
- โ Active alarms and defects
- โ Routing table markers (* and >)
- โ Configuration diff output (+/-/!)
Versa SD-WAN
- โ Interface types (eth, vni, tvi, ptvi, dtvi)
- โ VRF coloring (Control-VR, LAN-VR, Transport-VR)
- โ WAN link identifiers (WAN1, WAN2, WAN3)
- โ SD-WAN session details (natted, sdwan, offload)
- โ SLA metrics (delay, jitter, loss)
- โ LLDP neighbor information
- โ Operational/configuration mode prompts
- โ Branch/site naming patterns
Cisco IOS/IOS-XE/NX-OS
- โ Interface names (GigabitEthernet, TenGigabitEthernet, etc.)
- โ BGP/OSPF states
- โ STP states and roles
- โ VTP/VLAN information
Generic Patterns
- โ IPv4 addresses
- โ MAC addresses (colon and dot formats)
- โ Serial numbers and model numbers
- โ Status keywords (up/down, error/warning)
- โ Packet/byte counters with magnitude spectrum
๐ฏ Context-Aware Coloring
Multi-line state machine tracks context across output:
- Interface state (up/down) affects duplex coloring
- Half-duplex on UP link = red warning
- Half-duplex on DOWN link = gray (irrelevant)
โ๏ธ Advanced Features
- Group-based coloring: Different colors for each regex capture group
- Priority system: Fine-grained control over pattern precedence
- Profile inheritance: Extend base patterns with vendor-specific rules
- TOML configuration: Human-readable, version-controllable config
- ChromaTerm converter: Migrate existing YAML configs to TOML
๐ Installation
Choose your platform:
macOS / Linux
Step 1: Install Rust
Using rustup (recommended):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
After installation, restart your terminal or run source ~/.cargo/env.
Alternative: Homebrew (macOS) or system package manager (Linux)
Homebrew (macOS):
brew install rust
Important: Homebrew doesn't add Cargo to your PATH automatically. Run:
# For zsh (default on macOS) echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc # For bash echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc
Linux package managers:
# Debian/Ubuntu
sudo apt install cargo
# Fedora
sudo dnf install cargo
# Arch
sudo pacman -S rust
Note: System packages may be older versions. If you encounter build issues, use rustup instead.
Step 2: Install RainbowTerm
cargo install rainbowterm
Step 3: Verify installation
rt --version
You're done! Config is created automatically on first run.
Windows
Windows requires additional setup for compiling Rust programs and for interactive SSH sessions.
Step 1: Install Git for Windows
Required for Git Bash, which supports interactive SSH sessions (PowerShell does not).
winget install Git.Git
Or download from git-scm.com.
Step 2: Install Visual Studio Build Tools
Required for compiling Rust programs.
winget install Microsoft.VisualStudio.2022.BuildTools --override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"
Or download from Visual Studio Build Tools and select "Desktop development with C++".
Step 3: Install Rust
winget install Rustlang.Rustup
Or download from rustup.rs.
Step 4: Restart your terminal, then verify Rust is installed:
cargo --version
Step 5: Install RainbowTerm
cargo install rainbowterm
Step 6: Add Cargo to your PATH (if rt command is not found):
# Check if rt is installed
ls $env:USERPROFILE\.cargo\bin\rt.exe
# Add to PATH permanently
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";$env:USERPROFILE\.cargo\bin", "User")
Restart your terminal after updating the PATH.
Step 7: Add Git Bash to Windows Terminal
Note: If you installed Git via the GUI installer (not winget), Git Bash may already appear in Windows Terminal. Skip to step 8 if it's there.
Run these commands in PowerShell to add Git Bash as a profile:
$settingsPath = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
$settings = Get-Content $settingsPath | ConvertFrom-Json
$gitBashProfile = @{
name = "Git Bash"
commandline = "C:\\Program Files\\Git\\bin\\bash.exe"
icon = "C:\\Program Files\\Git\\mingw64\\share\\git\\git-for-windows.ico"
startingDirectory = "%USERPROFILE%"
guid = "{" + [guid]::NewGuid().ToString() + "}"
}
$settings.profiles.list = @($settings.profiles.list) + $gitBashProfile
$settings | ConvertTo-Json -Depth 100 | Set-Content $settingsPath
Step 8: Use Git Bash for interactive SSH
- Open Windows Terminal
- Click the dropdown (โผ) next to the tab and select Git Bash
- Run:
ssh <remote-host> | rt
Example:
ssh admin@192.168.1.1 | rt
From Source
# Clone the repository
git clone https://github.com/Legendberg/rainbowterm.git
cd rainbowterm
# Build and install
cargo install --path .
Requirements
- Rust 1.70+ (for building)
- macOS, Linux, WSL2, or Windows (with Git Bash for interactive SSH)
๐ Usage
Basic Usage
# Pipe any command through RainbowTerm (auto-detects profile)
ssh router | rt
# Use with specific profile (skip auto-detection)
cat output.txt | rt --profile juniper
# Disable auto-detection, use default profile from config
cat output.txt | rt --no-auto-detect
# Disable context awareness
tail -f /var/log/messages | rt --no-context
# List available profiles
rt --list-profiles
Windows Note
For interactive SSH sessions on Windows, use Git Bash (see Windows installation above). Non-interactive commands work in PowerShell:
ssh router "show version" | rt
Testing Profiles
Comprehensive test files are included for each vendor:
# Test Juniper profile
cat tests/networking/juniper/common/sample.txt | rt --profile juniper
# Test Cisco profile
cat tests/networking/cisco/ios/sample.txt | rt --profile cisco
# Run integration tests
cargo test --test integration_tests
# Run all tests (unit + integration)
cargo test
Test files include realistic output from various commands: interfaces, BGP, OSPF, STP, logging, and more.
Real-World Example: Context-Aware Dual Spectrum
Same output, different colors based on context:
Physical interface: ge-0/0/0, Enabled, Physical link is Up
Traffic statistics (NEUTRAL SPECTRUM - cool colors):
Input bytes : 1298458 0 bps
Output bytes : 909181029 32112 bps
Input errors (ERROR SPECTRUM - warm colors, same magnitudes!):
Errors: 1298458, Drops: 909181029, Framing errors: 0
Queue counters: Queued packets Transmitted packets Dropped packets
0 1644910 1644910 724
1 14362000 14362000 1750520
^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^^
neutral/cool neutral/cool error/warm
Notice how 1298458 appears twice with different colors - once as traffic (neutral spectrum) and once as errors (error spectrum). Context determines meaning!
Configuration
On first run, RainbowTerm creates a default config file at the OS-standard location:
| OS | Config Path |
|---|---|
| Linux | ~/.config/rainbowterm/config.toml |
| macOS | ~/Library/Application Support/rainbowterm/config.toml |
| Windows | C:\Users\<user>\AppData\Roaming\rainbowterm\config.toml |
Use -c <path> to specify a custom config file.
Tip: The config file includes a version comment at line 3. Check it to verify you're using the latest patterns:
head -3 ~/.config/rainbowterm/config.toml # Linux
head -3 ~/Library/Application\ Support/rainbowterm/config.toml # macOS
# Set default profile (used when auto-detection fails)
default_profile = "juniper"
# Customize hostname prefixes for your organization
# These help auto-detection identify devices by hostname
[hostname_prefixes]
juniper = ["jr", "js", "mx", "ex"] # Your Juniper naming convention
versa = ["vr", "sdwan"] # Your Versa naming convention
cisco = ["cs", "sw", "rtr", "cat"] # Your Cisco naming convention
# Add custom colors to palette
[palette]
my-blue = "#0080ff"
# Create custom patterns
[[profiles.juniper.patterns]]
description = "Custom pattern"
regex = '''my-regex-here'''
color = "my-blue"
priority = 100
Profile System
- base: Universal patterns (IPs, MACs, dates, status)
- juniper: JunOS-specific patterns (inherits from base)
- versa: Versa SD-WAN patterns (inherits from base)
- cisco: Cisco IOS/NX-OS patterns (inherits from base)
๐จ Color Schemes
Status Colors
- ๐ข Green: Good/Active (FWD, Established, Up)
- ๐ก Orange: Warning (BLK, threshold)
- ๐ด Red: Critical (Down, Error, Idle)
- โช Gray: Inactive (DIS, zero counters)
- ๐ต Cyan: Info (DESG, configuration)
- ๐ฃ Purple: Virtual interfaces (ae, irb, lo)
Interface Speed Colors
- ๐ Bright green: 100G+ (et, fte)
- ๐ฟ Green-lime: 10G (xe)
- ๐ Cyan: 2.5G (mge)
- ๐งก Orange: 1G (ge)
- ๐ Amber: <1G (fe)
๐ฌ Technical Details
Architecture
src/
โโโ main.rs # CLI interface, stdin processing, output rendering
โโโ config.rs # TOML parsing, profile management, shared types
โโโ matching.rs # Pattern compilation and application
โโโ context.rs # State machine for context-aware rules
โโโ convert.rs # ChromaTerm YAML converter (optional feature)
Performance
- Patterns compiled at startup with
regexcrate - O(n) processing with efficient overlap detection
- Chunk-based reading (8192 bytes) for SSH compatibility
- ANSI escape sequence preservation
- No performance degradation on large outputs
Pattern Priority System
Higher priority = applied first:
- 200+: Critical keywords (error, warning, failure)
- 168: Error counter zeros (green = healthy)
- 166-160: Error spectrum (trillions down to hundreds)
- 155-150: Dropped packets column (error spectrum)
- 155-145: Neutral spectrum (trillions down to hundreds) and queue counters
- 100: Interface names and service patterns
- 90: Protocol states (BGP, OSPF, STP)
- 85: Routing markers and roles
- 80: Speed indicators
- 10: Generic up/down keywords
๐ค Contributing
Contributions are welcome! Please feel free to submit issues or pull requests on GitHub.
๐บ๏ธ Roadmap
- Add Cisco IOS/IOS-XE/NX-OS profile
- Comprehensive test files for Juniper, Cisco, Arista
- Dual spectrum system (neutral vs. error-based coloring)
- Context-aware coloring philosophy
- Auto-create config on first run
- Public release to crates.io (v0.1.0)
- v0.2.0 release with dual spectrum and screenshots
- v0.2.3 improved documentation for both platforms
- Unit test suite (15 tests for config and matching)
- Integration test suite (Juniper, Cisco profiles)
- Versa SD-WAN profile (v0.2.12)
- Automatic profile detection from content/banners
- User-configurable hostname prefixes
- Complete Arista EOS profile implementation
- Shell completions (bash, zsh, fish)
- Performance benchmarks
- Additional vendor profiles (Palo Alto, F5, etc.)
- PTY wrap mode for serial console access (see Future Development)
๐ฎ Future Development
PTY Wrap Mode (Paused)
A PTY (pseudo-terminal) wrap mode was prototyped to support serial console access (e.g., rt screen /dev/ttyUSB0). This would allow colorizing output from direct console connections where pipe mode isn't possible.
Why it was paused:
The implementation revealed fundamental limitations with the PTY approach for serial/console access:
-
Inconsistent colorization - Serial data arrives in unpredictable chunks due to baud rate timing. Pattern matching requires complete lines, but data often splits mid-line, causing the same command to colorize differently on each run.
-
Tab completion broken - The PTY layer intercepts terminal control sequences, preventing tab completion from working on the remote device.
-
Space pagination broken - Similar issue: pressing space for "more" pagination doesn't work properly through the PTY wrapper.
-
Password visibility - Unlike SSH pipe mode (where the SSH client handles password prompts directly), PTY wrap mode would display typed passwords on screen, creating security concerns for screen sharing, terminal logging, and shoulder surfing scenarios.
Current recommendation: Use pipe mode (ssh router | rt) for the best experience. For serial console access, colorization is not currently supported.
What we tried:
The prototype used portable-pty to spawn commands in a pseudo-terminal with two threads: one passing stdin to the PTY, another reading PTY output, colorizing it, and writing to stdout. Several buffering strategies were attempted:
-
Direct passthrough - Process data immediately as it arrives. Result: Highly inconsistent colorization because serial data splits unpredictably.
-
Line buffering - Only process complete lines (wait for newline). Result: Prompts (which don't end with newlines) would get stuck and not display until the next line arrived.
-
Accumulation delay - Add 5-20ms delay after each read to let more data accumulate before processing. Result: Improved consistency but still unreliable; also added noticeable latency.
-
Hybrid approach - Buffer complete lines, flush incomplete data (like prompts) after accumulation. Result: Still inconsistent due to the fundamental timing unpredictability of serial data.
The core issue is that serial/console data doesn't arrive in logical units - it arrives based on baud rate timing, which means a single line like x1oz@BuffLab> might arrive as x1o, then z@Buff, then Lab> in separate reads. No amount of buffering can reliably reassemble this without either blocking indefinitely or accepting inconsistent results.
Future possibility: This could be revisited if:
- A reliable line-buffering solution is found for serial timing issues
- Terminal control sequence passthrough can be implemented
- A secure password handling mechanism is developed
The prototype code demonstrated that colorization does work when timing aligns, so the core concept is sound - it's the edge cases and user experience that need solving.
๐ License
Dual licensed under MIT OR Apache-2.0
๐ Acknowledgments
- Inspired by ChromaTerm
- Built with Rust
- Developed with assistance from Claude Code
Note: RainbowTerm is designed for network engineers working with CLI output from routers, switches, and firewalls. It significantly improves readability and reduces eye strain during troubleshooting sessions.
Dependencies
~6โ11MB
~212K SLoC