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 <[email protected]>
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;
}
}