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 65466625fcf camel-jbang - get processors command.
65466625fcf is described below

commit 65466625fcfffc07c183a1a54d8f158708be9521
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Sep 14 14:00:01 2022 +0200

    camel-jbang - get processors command.
---
 .../apache/camel/impl/console/RouteDevConsole.java |   2 +
 .../management/mbean/ManagedProcessorMBean.java    |   3 +
 .../camel/management/mbean/ManagedProcessor.java   |   5 +
 .../camel/cli/connector/LocalCliConnector.java     |   2 +-
 .../dsl/jbang/core/commands/CamelJBangMain.java    |   2 +
 .../commands/process/CamelProcessorStatus.java     | 259 +++++++++++++++++++++
 6 files changed, 272 insertions(+), 1 deletion(-)

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 6cec4cc94c0..c8a68b722bc 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
@@ -142,6 +142,7 @@ public class RouteDevConsole extends AbstractDevConsole {
         for (ManagedProcessorMBean mp : mps) {
             sb.append("\n");
             sb.append(String.format("\n        Id: %s", mp.getProcessorId()));
+            sb.append(String.format("\n        Processor: %s", 
mp.getProcessorName()));
             if (mp.getSourceLocation() != null) {
                 String loc = mp.getSourceLocation();
                 if (mp.getSourceLineNumber() != null) {
@@ -267,6 +268,7 @@ public class RouteDevConsole extends AbstractDevConsole {
                 }
                 jo.put("source", loc);
             }
+            jo.put("processor", mp.getProcessorName());
             JsonObject stats = new JsonObject();
             stats.put("exchangesTotal", mp.getExchangesTotal());
             stats.put("exchangesFailed", mp.getExchangesFailed());
diff --git 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedProcessorMBean.java
 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedProcessorMBean.java
index c8d91555618..e8935b1e6d1 100644
--- 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedProcessorMBean.java
+++ 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedProcessorMBean.java
@@ -39,6 +39,9 @@ public interface ManagedProcessorMBean extends 
ManagedPerformanceCounterMBean {
     @ManagedAttribute(description = "Processor ID")
     String getProcessorId();
 
+    @ManagedAttribute(description = "Processor Name (Short)")
+    String getProcessorName();
+
     @ManagedAttribute(description = "Processor Index")
     Integer getIndex();
 
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java
index ba06da256fe..8e8e76db59b 100644
--- 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java
+++ 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java
@@ -162,6 +162,11 @@ public class ManagedProcessor extends 
ManagedPerformanceCounter implements Manag
         return id;
     }
 
+    @Override
+    public String getProcessorName() {
+        return definition.getShortName();
+    }
+
     @Override
     public void start() throws Exception {
         if (!context.getStatus().isStarted()) {
diff --git 
a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
 
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
index b40b9b3c8e0..5dbab868607 100644
--- 
a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
+++ 
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
@@ -314,7 +314,7 @@ public class LocalCliConnector extends ServiceSupport 
implements CliConnector, C
                     .getDevConsoleResolver().resolveDevConsole("route");
             if (dc != null && dc2 != null) {
                 JsonObject json = (JsonObject) 
dc.call(DevConsole.MediaType.JSON);
-                JsonObject json2 = (JsonObject) 
dc2.call(DevConsole.MediaType.JSON);
+                JsonObject json2 = (JsonObject) 
dc2.call(DevConsole.MediaType.JSON, Map.of("processors", "true"));
                 if (json != null && json2 != null) {
                     root.put("context", json);
                     root.put("routes", json2.get("routes"));
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
index f713df4d0f7..59aeda0c45e 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
@@ -29,6 +29,7 @@ import 
org.apache.camel.dsl.jbang.core.commands.action.CamelRouteStopAction;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelThreadDump;
 import org.apache.camel.dsl.jbang.core.commands.process.CamelContextStatus;
 import org.apache.camel.dsl.jbang.core.commands.process.CamelContextTop;
+import org.apache.camel.dsl.jbang.core.commands.process.CamelProcessorStatus;
 import org.apache.camel.dsl.jbang.core.commands.process.CamelRouteStatus;
 import org.apache.camel.dsl.jbang.core.commands.process.CamelRouteTop;
 import org.apache.camel.dsl.jbang.core.commands.process.CamelStatus;
@@ -55,6 +56,7 @@ public class CamelJBangMain implements Callable<Integer> {
                 .addSubcommand("get", new CommandLine(new CamelStatus(main))
                         .addSubcommand("context", new CommandLine(new 
CamelContextStatus(main)))
                         .addSubcommand("route", new CommandLine(new 
CamelRouteStatus(main)))
+                        .addSubcommand("processor", new CommandLine(new 
CamelProcessorStatus(main)))
                         .addSubcommand("vault", new CommandLine(new 
ListVault(main))))
                 .addSubcommand("top", new CommandLine(new CamelTop(main))
                         .addSubcommand("context", new CommandLine(new 
CamelContextTop(main)))
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java
new file mode 100644
index 00000000000..a15de84bc82
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.process;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import com.github.freva.asciitable.AsciiTable;
+import com.github.freva.asciitable.Column;
+import com.github.freva.asciitable.HorizontalAlign;
+import com.github.freva.asciitable.OverflowBehaviour;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+
+@Command(name = "processor", aliases = { "processor", "processors" }, 
description = "Get status of Camel processors")
+public class CamelProcessorStatus extends ProcessBaseCommand {
+
+    @CommandLine.Parameters(description = "Name or pid of running Camel 
integration", arity = "0..1")
+    String name = "*";
+
+    @CommandLine.Option(names = { "--sort" },
+                        description = "Sort by pid or name", defaultValue = 
"pid")
+    String sort;
+
+    @CommandLine.Option(names = { "--source" },
+                        description = "Prefer to display source filename 
instead of processor IDs")
+    boolean source;
+
+    @CommandLine.Option(names = { "--limit" },
+                        description = "Filter routes by limiting to the given 
number of rows")
+    int limit;
+
+    @CommandLine.Option(names = { "--filter-mean" },
+                        description = "Filter processors that must be slower 
than the given time (ms)")
+    long mean;
+
+    public CamelProcessorStatus(CamelJBangMain main) {
+        super(main);
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        List<Row> rows = new ArrayList<>();
+
+        List<Long> pids = findPids(name);
+        ProcessHandle.allProcesses()
+                .filter(ph -> pids.contains(ph.pid()))
+                .forEach(ph -> {
+                    JsonObject root = loadStatus(ph.pid());
+                    if (root != null) {
+                        JsonObject context = (JsonObject) root.get("context");
+                        JsonArray array = (JsonArray) root.get("routes");
+                        for (int i = 0; i < array.size(); i++) {
+                            JsonObject o = (JsonObject) array.get(i);
+                            Row row = new Row();
+                            row.name = context.getString("name");
+                            if ("CamelJBang".equals(row.name)) {
+                                row.name = extractName(root, ph);
+                            }
+                            row.pid = "" + ph.pid();
+                            row.routeId = o.getString("routeId");
+                            row.processor = o.getString("from");
+                            row.source = o.getString("source");
+                            row.state = o.getString("state");
+                            Map<String, ?> stats = o.getMap("statistics");
+                            if (stats != null) {
+                                row.total = 
stats.get("exchangesTotal").toString();
+                                row.inflight = 
stats.get("exchangesInflight").toString();
+                                row.failed = 
stats.get("exchangesFailed").toString();
+                                row.mean = 
stats.get("meanProcessingTime").toString();
+                                if ("-1".equals(row.mean)) {
+                                    row.mean = null;
+                                }
+                                row.max = 
stats.get("maxProcessingTime").toString();
+                                row.min = 
stats.get("minProcessingTime").toString();
+                                Object last = 
stats.get("sinceLastCreatedExchange");
+                                if (last != null) {
+                                    row.sinceLastStarted = last.toString();
+                                }
+                                last = stats.get("sinceLastCompletedExchange");
+                                if (last != null) {
+                                    row.sinceLastCompleted = last.toString();
+                                }
+                                last = stats.get("sinceLastFailedExchange");
+                                if (last != null) {
+                                    row.sinceLastFailed = last.toString();
+                                }
+                            }
+
+                            boolean add = true;
+                            if (mean > 0 && row.mean != null && 
Long.parseLong(row.mean) < mean) {
+                                add = false;
+                            }
+                            if (limit > 0 && rows.size() >= limit) {
+                                add = false;
+                            }
+                            if (add) {
+                                rows.add(row);
+                                List<JsonObject> list = 
o.getCollection("processors");
+                                addProcessors(row, rows, list);
+                            }
+                        }
+                    }
+                });
+
+        // sort rows
+        rows.sort(this::sortRow);
+
+        if (!rows.isEmpty()) {
+            printTable(rows);
+        }
+
+        return 0;
+    }
+
+    private void addProcessors(Row route, List<Row> rows, List<JsonObject> 
processors) {
+        for (JsonObject o : processors) {
+            Row row = new Row();
+            row.pid = route.pid;
+            row.name = route.name;
+            row.routeId = route.routeId;
+            rows.add(row);
+            row.processorId = o.getString("id");
+            row.processor = o.getString("processor");
+            row.source = o.getString("source");
+            Map<String, ?> stats = o.getMap("statistics");
+            if (stats != null) {
+                row.total = stats.get("exchangesTotal").toString();
+                row.inflight = stats.get("exchangesInflight").toString();
+                row.failed = stats.get("exchangesFailed").toString();
+                row.mean = stats.get("meanProcessingTime").toString();
+                if ("-1".equals(row.mean)) {
+                    row.mean = null;
+                }
+                row.max = stats.get("maxProcessingTime").toString();
+                row.min = stats.get("minProcessingTime").toString();
+                Object last = stats.get("sinceLastCompletedExchange");
+                if (last != null) {
+                    row.sinceLastCompleted = last.toString();
+                }
+                last = stats.get("sinceLastFailedExchange");
+                if (last != null) {
+                    row.sinceLastFailed = last.toString();
+                }
+            }
+        }
+    }
+
+    protected void printTable(List<Row> rows) {
+        // need to flatten list
+        System.out.println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, 
Arrays.asList(
+                new 
Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(this::getPid),
+                new 
Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, 
OverflowBehaviour.ELLIPSIS_RIGHT)
+                        .with(this::getName),
+                new 
Column().header("ID").dataAlign(HorizontalAlign.LEFT).maxWidth(40, 
OverflowBehaviour.ELLIPSIS_RIGHT)
+                        .with(this::getId),
+                new 
Column().header("PROCESSOR").dataAlign(HorizontalAlign.LEFT).maxWidth(40, 
OverflowBehaviour.ELLIPSIS_RIGHT)
+                        .with(this::getProcessor),
+                new Column().header("TOTAL").with(r -> r.total),
+                new Column().header("FAIL").with(r -> r.failed),
+                new Column().header("INFLIGHT").with(r -> r.inflight),
+                new Column().header("MEAN").with(r -> r.mean),
+                new Column().header("MIN").with(r -> r.min),
+                new Column().header("MAX").with(r -> r.max),
+                new Column().header("SINCE-LAST").with(this::getSinceLast))));
+    }
+
+    protected int sortRow(Row o1, Row o2) {
+        switch (sort) {
+            case "pid":
+                return Long.compare(Long.parseLong(o1.pid), 
Long.parseLong(o2.pid));
+            case "name":
+                return o1.name.compareToIgnoreCase(o2.name);
+            case "age":
+                return Long.compare(o1.uptime, o2.uptime);
+            default:
+                return 0;
+        }
+    }
+
+    protected String getSinceLast(Row r) {
+        String s1 = r.sinceLastCompleted != null ? r.sinceLastCompleted : "-";
+        String s2 = r.sinceLastFailed != null ? r.sinceLastFailed : "-";
+        return s1 + "/" + s2;
+    }
+
+    protected String getName(Row r) {
+        return r.processorId == null ? r.name : "";
+    }
+
+    protected String getId(Row r) {
+        String answer;
+        if (source && r.source != null) {
+            answer = sourceLocLine(r.source);
+        } else {
+            answer = r.processorId != null ? r.processorId : r.routeId;
+        }
+        if (r.processorId != null) {
+            answer = "  " + answer;
+        }
+        return answer;
+    }
+
+    protected String getPid(Row r) {
+        if (r.processorId == null) {
+            return r.pid;
+        } else {
+            return "";
+        }
+    }
+
+    protected String getProcessor(Row r) {
+        String answer = r.processor;
+        if (r.processorId != null) {
+            answer = "  " + answer;
+        }
+        return answer;
+    }
+
+    static class Row {
+        String pid;
+        String name;
+        long uptime;
+        String routeId;
+        String processorId;
+        String processor;
+        String source;
+        String state;
+        String total;
+        String failed;
+        String inflight;
+        String mean;
+        String max;
+        String min;
+        String sinceLastStarted;
+        String sinceLastCompleted;
+        String sinceLastFailed;
+    }
+
+}

Reply via email to