Skip to content

CAMEL-23226: Add TUI dashboards for Camel JBang#22197

Open
gnodet wants to merge 10 commits intomainfrom
Guillaume-Nodet/camel-tui
Open

CAMEL-23226: Add TUI dashboards for Camel JBang#22197
gnodet wants to merge 10 commits intomainfrom
Guillaume-Nodet/camel-tui

Conversation

@gnodet
Copy link
Contributor

@gnodet gnodet commented Mar 23, 2026

JIRA: CAMEL-23226

Summary

Add full-screen TUI (Terminal User Interface) dashboards to Camel JBang using TamboUI, providing rich interactive monitoring and browsing capabilities directly in the terminal. The TUI is implemented as a separate plugin module (camel-jbang-plugin-tui), loaded via the @CamelJBangPlugin SPI mechanism.

New Commands

Command Description
camel monitor Multi-tab dashboard with overview, routes, processors, health, endpoints, log, and trace tabs
camel catalog-tui Interactive component catalog browser with search and detail view

Monitor Tabs

  1. Overview — Live integration list with status, uptime, throughput sparklines, memory gauge
  2. Routes — Route list with state, message counts, timing stats, and processor detail
  3. Processors — Per-route processor breakdown with message counts and timing
  4. Health — Health check dashboard with UP/DOWN indicators
  5. Endpoints — Endpoint list with direction, component, and route association
  6. Log — Scrollable log viewer with level filtering (TRACE/DEBUG/INFO/WARN/ERROR), follow mode, and detail panel
  7. Trace — Exchange trace viewer with detail panel for headers, body, and exchange properties

Key Features

  • Live data refresh with configurable intervals
  • Keyboard navigation (arrow keys, tab switching via number keys)
  • Color-coded status indicators (green/yellow/red)
  • Sparkline throughput charts in overview
  • Log level filtering and follow mode
  • Trace detail with headers/body toggle
  • Memory gauge with heap usage
  • Vanishing effect for stopped integrations
  • Fuzzy search in catalog browser

Dependencies

  • Add TamboUI 0.2.0-SNAPSHOT dependencies (tamboui-tui, tamboui-widgets, tamboui-jline3-backend)

Module Structure

  • dsl/camel-jbang/camel-jbang-plugin-tui/ — new plugin module
    • CamelMonitor.java — multi-tab monitor dashboard
    • CamelCatalogTui.java — interactive catalog browser
    • TuiHelper.java — shared TUI utilities
    • TuiPlugin.java — plugin registration via SPI

Test plan

  • camel monitor shows running integrations with live stats across all tabs
  • Log tab correctly parses ANSI-stripped log lines with regex-based parser
  • Trace tab correctly parses backlog trace JSON format
  • All null fields handled safely (no NPEs in rendering)
  • camel catalog-tui browses components with search and detail view
  • All TUI views handle Ctrl+C/q cleanly

- Add `camel monitor` full-screen TUI dashboard with tabs for overview,
  routes, health checks, endpoints, and log viewer
- Add `camel top tui` htop-style route performance dashboard with
  sortable columns and live refresh
- Add `camel log tui` scrollable log viewer with level filtering,
  follow mode, and grep support
- Add `camel trace tui` exchange trace viewer with detail panel showing
  headers, body, and exchange properties
- Add `camel health` TUI health check dashboard with UP/DOWN indicators
  and memory gauge
- Add `camel catalog tui` interactive component catalog browser with
  search/filter and component detail view
- Upgrade JLine from 4.0.7 to 4.0.9
- Add TamboUI dependencies for terminal UI rendering
- Use TamboUI's built-in JLine 3 backend (compatible with JLine 4.0.9)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using build-all, build-dependents, skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 23, 2026

🧪 CI tested the following changed modules:

  • dsl/camel-jbang
  • dsl/camel-jbang/camel-jbang-core
  • dsl/camel-jbang/camel-jbang-plugin-tui
  • dsl/camel-jbang/camel-launcher
  • parent

ℹ️ Dependent modules were not tested because the total number of affected modules exceeded the threshold (50). Use the test-dependents label to force testing all dependents.

Build reactor — dependencies compiled but only changed modules were tested (10 modules)
  • Camel :: JBang :: Core
  • Camel :: JBang :: Core [jar]
  • Camel :: JBang :: Parent
  • Camel :: JBang :: Parent [pom]
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: TUI [jar]
  • Camel :: Launcher
  • Camel :: Launcher [jar]
  • Camel :: Parent
  • Camel :: Parent [pom]

Comment on lines +83 to +90
try {
Class.forName("dev.tamboui.tui.event.KeyModifiers");
Class.forName("dev.tamboui.tui.event.KeyEvent");
Class.forName("dev.tamboui.tui.event.KeyCode");
Class.forName("picocli.CommandLine$IExitCodeGenerator");
} catch (ClassNotFoundException e) {
// ignore
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the interest of callingClass;forName to then ignore exception and do nothing about it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code on behalf of Guillaume Nodet

Good question! This eagerly pre-loads classes that the TUI input reader daemon thread needs. Without this, during JVM shutdown the classloader may already be closing (especially with JBang's custom classloader) while the input reader thread is still trying to load KeyModifiers, KeyEvent, etc. lazily — causing ClassNotFoundException stack traces on exit.

The comment was missing on this file (the others already had it). Added it now, and will also extract this into a shared utility to avoid the duplication.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If one fails the following classes are not pre-loeaded and there is no error handling that could help understand what happened.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, though, if one fails, the real code (main thread) will certainly fail too with an error that will be logged somewhere. This is really only to avoid the daemon thread to fail with a non actionable exception. I guess another possibility would be to swallow exceptions when closing, but that may hide other problems.

gnodet and others added 2 commits March 23, 2026 16:14
…ogTui

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move duplicated code (preloadClasses, findPids, loadStatus, truncate,
objToLong) from all 6 TUI commands into a shared TuiHelper utility class.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Croway
Copy link
Contributor

Croway commented Mar 23, 2026

Why is the TUI part of Camel JBang core? what about having it as a new plugin?

gnodet and others added 3 commits March 23, 2026 17:45
- Create camel-jbang-plugin-tui with TuiPlugin that registers all TUI commands
- Move all TUI source files from camel-jbang-core to camel-jbang-plugin-tui
- Remove TamboUI dependencies from camel-jbang-core
- Add parentCommands support to @CamelJBangPlugin annotation so plugins
  can inject subcommands into existing commands (e.g. 'top tui', 'trace tui')
- Update PluginHelper to load plugins when target matches parentCommands

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Register TuiPlugin in CamelLauncherMain.postAddCommands() (plugins are
  loaded explicitly, not via classpath scanning)
- Rename parentCommands to commands in @CamelJBangPlugin annotation to
  cover both top-level commands and parent commands the plugin extends
- Include health and monitor in the plugin's commands list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Consolidate CamelTopTui, CamelTraceTui, CamelLogTui, CamelHealthTui
  into unified CamelMonitor dashboard with 6 tabs (Overview, Routes,
  Health, Endpoints, Log, Trace)
- Enhanced Routes tab with sort cycling (mean/max/total/failed/name)
- Enhanced Health tab with readiness/liveness columns and DOWN filter
- Enhanced Log tab with level filtering and follow mode
- New Trace tab with exchange-level trace viewer
- Redesigned CamelCatalogTui with split-panel layout (component list +
  options table) and context-sensitive description panel
- Added inline per-panel filtering with name-only and full-text toggle (/)
- Simplified TuiPlugin to only register top-level commands
- Removed commands attribute from @CamelJBangPlugin annotation
- Reverted plugin loading mechanism in PluginHelper

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gansheer gansheer self-requested a review March 23, 2026 19:10
gnodet and others added 3 commits March 23, 2026 21:20
- Redesign log tab: table with selectable rows + bottom detail panel
- Add LogEntry data class for structured log parsing
- Add highlight spacing (ALWAYS) to all tables to prevent content shift
- Remove hardcoded column truncation (routes FROM, overview NAME, etc.)
- Increase endpoints ROUTE column width
- Remove redundant SPACE_CELL buffer fill (Cell.EMPTY already uses space)
- Rendering artifacts fix: requires updated TamboUI 0.2.0-SNAPSHOT with
  refactored AbstractBackend (cursor optimization removed)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use regex-based parser that handles both old format (space separator)
  and Spring Boot 3.x/Camel 4.x ISO-8601 format (T separator + timezone)
- Strip ANSI color codes from log lines before parsing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix trace file parser to handle actual JSON format (traces array wrapper,
  numeric uid/timestamp, done/failed booleans instead of status string,
  nested body/headers/properties structures)
- Add null guards for switch expressions (ep.direction, entry.status)
- Use getIntegerOrDefault/getLongOrDefault to prevent NPE from null unboxing
- Add null checks for route.state, ep.component, proc.id, proc.processor
- Move log file reading from render to refreshData tick for better performance
- Make traceFilePositions thread-safe with ConcurrentHashMap
- Remove dead truncate method in CamelCatalogTui
- Revert unneeded PluginHelper.java changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
Copy link
Contributor Author

gnodet commented Mar 23, 2026

Claude Code on behalf of Guillaume Nodet

@Croway The TUI is already implemented as a separate plugin module (camel-jbang-plugin-tui), not in camel-jbang-core. The initial commit had it in core but it was moved to its own plugin in a follow-up commit (549d945). The plugin is loaded via the @CamelJBangPlugin annotation and SPI mechanism.

@gnodet gnodet marked this pull request as ready for review March 23, 2026 21:09
Switch from 0.2.0-SNAPSHOT to the released 0.1.0 version and remove
the sonatype-snapshots repository block. No 0.2.0-specific APIs are
used by the TUI plugin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants