This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit 15bcdbe2f2a68e7f372d5b800096a12e8db6209b Author: Claus Ibsen <[email protected]> AuthorDate: Tue Sep 8 17:05:14 2026 +0200 Camel TUI: Overview table export sends uptime as a duration, not the start timestamp tui_get_table(Overview) put the process start time (epoch millis) under "uptime", so an AI reading the row converted it as a duration and answered with hours of uptime for an app started minutes ago. Export the same elapsed duration the screen shows, plus uptimeMillis and startedAt for the raw values. Co-Authored-By: Claude Fable 5.1 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../dsl/jbang/core/commands/tui/OverviewTab.java | 11 ++++++++++- .../core/commands/tui/OverviewTabRenderTest.java | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java index 990053c91c7b..d5ed6dc88cc4 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java @@ -16,6 +16,7 @@ */ package org.apache.camel.dsl.jbang.core.commands.tui; +import java.time.Instant; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -49,6 +50,7 @@ import dev.tamboui.widgets.table.Cell; import dev.tamboui.widgets.table.Row; import dev.tamboui.widgets.table.Table; import dev.tamboui.widgets.table.TableState; +import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -1399,7 +1401,14 @@ class OverviewTab extends AbstractTab { row.put("platform", info.platform); row.put("state", info.state); row.put("ready", info.ready); - row.put("uptime", info.uptime); + // info.uptime holds the process start time (epoch millis), which the screen shows as an elapsed + // duration; export the same duration plus the raw values with unambiguous names so an AI reading + // the row does not mistake the timestamp for a duration + row.put("uptime", info.ago != null ? info.ago : (info.uptime > 0 ? TimeUtils.printSince(info.uptime) : "")); + if (info.uptime > 0) { + row.put("uptimeMillis", Math.max(0, System.currentTimeMillis() - info.uptime)); + row.put("startedAt", Instant.ofEpochMilli(info.uptime).toString()); + } row.put("exchangesTotal", info.exchangesTotal); row.put("failed", info.failed); row.put("inflight", info.inflight); diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTabRenderTest.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTabRenderTest.java index 2d83070df68b..894ec99f0f32 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTabRenderTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTabRenderTest.java @@ -16,6 +16,7 @@ */ package org.apache.camel.dsl.jbang.core.commands.tui; +import java.time.Instant; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -31,6 +32,8 @@ import dev.tamboui.tui.event.KeyEvent; import dev.tamboui.tui.event.KeyModifiers; import dev.tamboui.tui.event.MouseButton; import dev.tamboui.tui.event.MouseEvent; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -81,6 +84,23 @@ class OverviewTabRenderTest { assertTrue(rendered.contains("TOTAL"), "Should show TOTAL header"); } + @Test + void tableDataExportsUptimeAsDurationNotStartTimestamp() { + info.state = 5; + info.uptime = System.currentTimeMillis() - 2 * 60 * 1000; + info.ago = "2m0s"; + + OverviewTab tab = new OverviewTab(ctx, new MetricsCollector(), new HashSet<>(), () -> { + }); + JsonObject data = tab.getTableDataAsJson(); + JsonObject row = (JsonObject) ((JsonArray) data.get("rows")).get(0); + + assertEquals("2m0s", row.get("uptime"), "uptime must be the elapsed duration shown on screen"); + long millis = ((Number) row.get("uptimeMillis")).longValue(); + assertTrue(millis >= 2 * 60 * 1000 && millis < 3 * 60 * 1000, "uptimeMillis was " + millis); + assertEquals(Instant.ofEpochMilli(info.uptime).toString(), row.get("startedAt")); + } + @Test void renderShowsIntegrationData() { info.state = 5;
