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


The following commit(s) were added to refs/heads/main by this push:
     new 2175171ac52 CAMEL-20972: camel-jbang - Be able to see route error 
message and stacktrace
2175171ac52 is described below

commit 2175171ac5238040eaf096aa2a505de105ca8d3c
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Thu Jul 11 20:42:32 2024 +0200

    CAMEL-20972: camel-jbang - Be able to see route error message and stacktrace
---
 .../apache/camel/impl/console/RouteDevConsole.java | 34 +++++++++++
 .../core/commands/process/CamelRouteStatus.java    | 67 +++++++++++++++++++++-
 2 files changed, 99 insertions(+), 2 deletions(-)

diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
index 59d022b5440..0624230c452 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
@@ -16,8 +16,11 @@
  */
 package org.apache.camel.impl.console;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
@@ -92,6 +95,20 @@ public class RouteDevConsole extends AbstractDevConsole {
                 sb.append(String.format("\n    Source: %s", 
mrb.getSourceLocation()));
             }
             sb.append(String.format("\n    State: %s", mrb.getState()));
+            if (mrb.getLastError() != null) {
+                String phase = 
StringHelper.capitalize(mrb.getLastError().getPhase().name().toLowerCase());
+                sb.append(String.format("\n    Error Phase: %s", phase));
+                Throwable cause = mrb.getLastError().getException();
+                if (cause != null) {
+                    sb.append(String.format("\n    Error Message: %s", 
cause.getMessage()));
+                    StringWriter sw = new StringWriter();
+                    PrintWriter pw = new PrintWriter(sw);
+                    cause.printStackTrace(pw);
+                    sb.append("\n\n");
+                    sb.append(sw);
+                    sb.append("\n\n");
+                }
+            }
             sb.append(String.format("\n    Uptime: %s", mrb.getUptime()));
             String coverage = calculateRouteCoverage(mrb, true);
             if (coverage != null) {
@@ -240,6 +257,23 @@ public class RouteDevConsole extends AbstractDevConsole {
             }
             jo.put("state", mrb.getState());
             jo.put("uptime", mrb.getUptime());
+            if (mrb.getLastError() != null) {
+                String phase = 
StringHelper.capitalize(mrb.getLastError().getPhase().name().toLowerCase());
+                JsonObject eo = new JsonObject();
+                eo.put("phase", phase);
+                Throwable cause = mrb.getLastError().getException();
+                if (cause != null) {
+                    eo.put("message", cause.getMessage());
+                    JsonArray arr2 = new JsonArray();
+                    StringWriter writer = new StringWriter();
+                    cause.printStackTrace(new PrintWriter(writer));
+                    writer.flush();
+                    String trace = writer.toString();
+                    eo.put("stackTrace", arr2);
+                    Collections.addAll(arr2, trace.split("\n"));
+                }
+                jo.put("lastError", eo);
+            }
             JsonObject stats = new JsonObject();
             String coverage = calculateRouteCoverage(mrb, false);
             if (coverage != null) {
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
index ac3eb7464f4..b2941c3b0ac 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
@@ -21,6 +21,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
 
 import com.github.freva.asciitable.AsciiTable;
 import com.github.freva.asciitable.Column;
@@ -29,6 +30,7 @@ import com.github.freva.asciitable.OverflowBehaviour;
 import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
 import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates;
 import org.apache.camel.dsl.jbang.core.common.ProcessHelper;
+import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.TimeUtils;
 import org.apache.camel.util.json.JsonArray;
 import org.apache.camel.util.json.JsonObject;
@@ -66,6 +68,10 @@ public class CamelRouteStatus extends ProcessWatchCommand {
                         description = "Filter routes that must be slower than 
the given time (ms)")
     long mean;
 
+    @CommandLine.Option(names = { "--error" },
+                        description = "Shows detailed information for routes 
that has error status")
+    boolean error;
+
     public CamelRouteStatus(CamelJBangMain main) {
         super(main);
     }
@@ -106,6 +112,12 @@ public class CamelRouteStatus extends ProcessWatchCommand {
                             row.state = o.getString("state");
                             row.age = o.getString("uptime");
                             row.uptime = row.age != null ? 
TimeUtils.toMilliSeconds(row.age) : 0;
+                            JsonObject eo = (JsonObject) o.get("lastError");
+                            if (eo != null) {
+                                row.lastErrorPhase = eo.getString("phase");
+                                row.lastErrorMessage = eo.getString("message");
+                                row.stackTrace = 
eo.getCollection("stackTrace");
+                            }
                             Map<String, ?> stats = o.getMap("statistics");
                             if (stats != null) {
                                 Object load = stats.get("load01");
@@ -180,7 +192,16 @@ public class CamelRouteStatus extends ProcessWatchCommand {
         rows.sort(this::sortRow);
 
         if (!rows.isEmpty()) {
-            printTable(rows, remoteVisible.get());
+            if (error) {
+                for (Row r : rows) {
+                    boolean error = r.lastErrorPhase != null;
+                    if (error) {
+                        printErrorTable(r, remoteVisible.get());
+                    }
+                }
+            } else {
+                printTable(rows, remoteVisible.get());
+            }
         }
 
         return 0;
@@ -200,7 +221,7 @@ public class CamelRouteStatus extends ProcessWatchCommand {
                         .dataAlign(HorizontalAlign.CENTER)
                         .with(this::getRemote),
                 new 
Column().header("STATUS").headerAlign(HorizontalAlign.CENTER)
-                        .with(r -> r.state),
+                        .with(this::getStatus),
                 new 
Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.age),
                 new Column().header("COVER").with(this::getCoverage),
                 new Column().header("MSG/S").with(this::getThroughput),
@@ -215,6 +236,38 @@ public class CamelRouteStatus extends ProcessWatchCommand {
                 new Column().header("SINCE-LAST").with(this::getSinceLast))));
     }
 
+    protected void printErrorTable(Row er, boolean remoteVisible) {
+        printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, 
List.of(er), Arrays.asList(
+                new 
Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid),
+                new 
Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, 
OverflowBehaviour.ELLIPSIS_RIGHT)
+                        .with(r -> r.name),
+                new 
Column().header("ID").dataAlign(HorizontalAlign.LEFT).maxWidth(20, 
OverflowBehaviour.ELLIPSIS_RIGHT)
+                        .with(this::getId),
+                new 
Column().header("FROM").visible(!wideUri).dataAlign(HorizontalAlign.LEFT)
+                        .maxWidth(45, OverflowBehaviour.ELLIPSIS_RIGHT)
+                        .with(this::getFrom),
+                new 
Column().header("REMOTE").visible(remoteVisible).headerAlign(HorizontalAlign.CENTER)
+                        .dataAlign(HorizontalAlign.CENTER)
+                        .with(this::getRemote),
+                new 
Column().header("STATUS").headerAlign(HorizontalAlign.CENTER)
+                        .with(this::getStatus),
+                new 
Column().header("PHASE").headerAlign(HorizontalAlign.CENTER)
+                        .with(r -> r.lastErrorPhase),
+                new Column().header("MESSAGE").dataAlign(HorizontalAlign.LEFT)
+                        .maxWidth(80, OverflowBehaviour.NEWLINE)
+                        .with(r -> r.lastErrorMessage))));
+        if (!er.stackTrace.isEmpty()) {
+            printer().println();
+            printer().println(StringHelper.fillChars('-', 120));
+            printer().println(StringHelper.padString(1, 55) + "STACK-TRACE");
+            printer().println(StringHelper.fillChars('-', 120));
+            for (String line : er.stackTrace) {
+                printer().println(String.format("\t%s", line));
+            }
+            printer().println();
+        }
+    }
+
     protected int sortRow(Row o1, Row o2) {
         String s = sort;
         int negate = 1;
@@ -272,6 +325,13 @@ public class CamelRouteStatus extends ProcessWatchCommand {
         return r.remote ? "x" : "";
     }
 
+    protected String getStatus(Row r) {
+        if (r.lastErrorPhase != null) {
+            return "Error";
+        }
+        return r.state;
+    }
+
     protected String getId(Row r) {
         if (source && r.source != null) {
             return sourceLocLine(r.source);
@@ -318,6 +378,9 @@ public class CamelRouteStatus extends ProcessWatchCommand {
         String load01;
         String load05;
         String load15;
+        String lastErrorPhase;
+        String lastErrorMessage;
+        List<String> stackTrace;
     }
 
 }

Reply via email to