You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/08/29 12:57:41 UTC
[camel] branch main updated (881588fc809 -> 90a5863a761)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
from 881588fc809 Do wait for started before running the test
new 471a17fc989 CAMEL-18425: camel-cli - Display more information for top commands.
new 90a5863a761 CAMEL-18425: camel-cli - Display more information for top commands.
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../GarbageCollectorDevConsoleConfigurer.java | 49 +++++
.../impl/console/ThreadDevConsoleConfigurer.java | 49 +++++
...e.camel.impl.console.GarbageCollectorDevConsole | 2 +
.../org.apache.camel.impl.console.ThreadDevConsole | 2 +
.../services/org/apache/camel/dev-console/gc | 2 +
.../services/org/apache/camel/dev-console/thread | 2 +
.../impl/console/GarbageCollectorDevConsole.java | 73 +++++++
.../camel/impl/console/ThreadDevConsole.java | 101 ++++++++++
.../modules/ROOT/pages/camel-jbang.adoc | 36 +++-
.../camel/cli/connector/LocalCliConnector.java | 84 +++++++-
.../dsl/jbang/core/commands/CamelJBangMain.java | 10 +-
.../core/commands/process/CamelContextTop.java | 222 +++++++++++++++++++++
.../{CamelTopStatus.java => CamelRouteTop.java} | 6 +-
.../process/{CamelTopStatus.java => CamelTop.java} | 26 +--
14 files changed, 640 insertions(+), 24 deletions(-)
create mode 100644 core/camel-console/src/generated/java/org/apache/camel/impl/console/GarbageCollectorDevConsoleConfigurer.java
create mode 100644 core/camel-console/src/generated/java/org/apache/camel/impl/console/ThreadDevConsoleConfigurer.java
create mode 100644 core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.impl.console.GarbageCollectorDevConsole
create mode 100644 core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.impl.console.ThreadDevConsole
create mode 100644 core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/gc
create mode 100644 core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/thread
create mode 100644 core/camel-console/src/main/java/org/apache/camel/impl/console/GarbageCollectorDevConsole.java
create mode 100644 core/camel-console/src/main/java/org/apache/camel/impl/console/ThreadDevConsole.java
create mode 100644 dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java
copy dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/{CamelTopStatus.java => CamelRouteTop.java} (89%)
rename dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/{CamelTopStatus.java => CamelTop.java} (62%)
[camel] 01/02: CAMEL-18425: camel-cli - Display more information for top commands.
Posted by da...@apache.org.
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 471a17fc9890a4d19fabc6592184a1c54b689ae6
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 29 14:20:51 2022 +0200
CAMEL-18425: camel-cli - Display more information for top commands.
---
.../GarbageCollectorDevConsoleConfigurer.java | 49 +++++
.../impl/console/ThreadDevConsoleConfigurer.java | 49 +++++
...e.camel.impl.console.GarbageCollectorDevConsole | 2 +
.../org.apache.camel.impl.console.ThreadDevConsole | 2 +
.../services/org/apache/camel/dev-console/gc | 2 +
.../services/org/apache/camel/dev-console/thread | 2 +
.../impl/console/GarbageCollectorDevConsole.java | 73 +++++++
.../camel/impl/console/ThreadDevConsole.java | 101 ++++++++++
.../camel/cli/connector/LocalCliConnector.java | 84 +++++++-
.../dsl/jbang/core/commands/CamelJBangMain.java | 10 +-
.../core/commands/process/CamelContextTop.java | 222 +++++++++++++++++++++
.../{CamelTopStatus.java => CamelRouteTop.java} | 6 +-
.../process/{CamelTopStatus.java => CamelTop.java} | 26 +--
13 files changed, 605 insertions(+), 23 deletions(-)
diff --git a/core/camel-console/src/generated/java/org/apache/camel/impl/console/GarbageCollectorDevConsoleConfigurer.java b/core/camel-console/src/generated/java/org/apache/camel/impl/console/GarbageCollectorDevConsoleConfigurer.java
new file mode 100644
index 00000000000..6e11e40485e
--- /dev/null
+++ b/core/camel-console/src/generated/java/org/apache/camel/impl/console/GarbageCollectorDevConsoleConfigurer.java
@@ -0,0 +1,49 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.impl.console;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.impl.console.GarbageCollectorDevConsole;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class GarbageCollectorDevConsoleConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+ @Override
+ public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+ org.apache.camel.impl.console.GarbageCollectorDevConsole target = (org.apache.camel.impl.console.GarbageCollectorDevConsole) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "camelcontext":
+ case "CamelContext": target.setCamelContext(property(camelContext, org.apache.camel.CamelContext.class, value)); return true;
+ default: return false;
+ }
+ }
+
+ @Override
+ public Class<?> getOptionType(String name, boolean ignoreCase) {
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "camelcontext":
+ case "CamelContext": return org.apache.camel.CamelContext.class;
+ default: return null;
+ }
+ }
+
+ @Override
+ public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+ org.apache.camel.impl.console.GarbageCollectorDevConsole target = (org.apache.camel.impl.console.GarbageCollectorDevConsole) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "camelcontext":
+ case "CamelContext": return target.getCamelContext();
+ default: return null;
+ }
+ }
+}
+
diff --git a/core/camel-console/src/generated/java/org/apache/camel/impl/console/ThreadDevConsoleConfigurer.java b/core/camel-console/src/generated/java/org/apache/camel/impl/console/ThreadDevConsoleConfigurer.java
new file mode 100644
index 00000000000..6df6dd7ab60
--- /dev/null
+++ b/core/camel-console/src/generated/java/org/apache/camel/impl/console/ThreadDevConsoleConfigurer.java
@@ -0,0 +1,49 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.impl.console;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.impl.console.ThreadDevConsole;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class ThreadDevConsoleConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+ @Override
+ public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+ org.apache.camel.impl.console.ThreadDevConsole target = (org.apache.camel.impl.console.ThreadDevConsole) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "camelcontext":
+ case "CamelContext": target.setCamelContext(property(camelContext, org.apache.camel.CamelContext.class, value)); return true;
+ default: return false;
+ }
+ }
+
+ @Override
+ public Class<?> getOptionType(String name, boolean ignoreCase) {
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "camelcontext":
+ case "CamelContext": return org.apache.camel.CamelContext.class;
+ default: return null;
+ }
+ }
+
+ @Override
+ public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+ org.apache.camel.impl.console.ThreadDevConsole target = (org.apache.camel.impl.console.ThreadDevConsole) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "camelcontext":
+ case "CamelContext": return target.getCamelContext();
+ default: return null;
+ }
+ }
+}
+
diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.impl.console.GarbageCollectorDevConsole b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.impl.console.GarbageCollectorDevConsole
new file mode 100644
index 00000000000..da5eb35d631
--- /dev/null
+++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.impl.console.GarbageCollectorDevConsole
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.impl.console.GarbageCollectorDevConsoleConfigurer
diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.impl.console.ThreadDevConsole b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.impl.console.ThreadDevConsole
new file mode 100644
index 00000000000..6aff17f333c
--- /dev/null
+++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.impl.console.ThreadDevConsole
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.impl.console.ThreadDevConsoleConfigurer
diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/gc b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/gc
new file mode 100644
index 00000000000..b3f7a71ee18
--- /dev/null
+++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/gc
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.impl.console.GarbageCollectorDevConsole
diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/thread b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/thread
new file mode 100644
index 00000000000..e34acd483f6
--- /dev/null
+++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/thread
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.impl.console.ThreadDevConsole
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/GarbageCollectorDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/GarbageCollectorDevConsole.java
new file mode 100644
index 00000000000..9e2bdc6ee3a
--- /dev/null
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/GarbageCollectorDevConsole.java
@@ -0,0 +1,73 @@
+/*
+ * 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.impl.console;
+
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.annotations.DevConsole;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.camel.util.UnitUtils.printUnitFromBytesDot;
+
+@DevConsole("gc")
+@Configurer(bootstrap = true)
+public class GarbageCollectorDevConsole extends AbstractDevConsole {
+
+ public GarbageCollectorDevConsole() {
+ super("jvm", "gc", "Garbage Collector", "Displays Garbage Collector information");
+ }
+
+ @Override
+ protected String doCallText(Map<String, Object> options) {
+ StringBuilder sb = new StringBuilder();
+
+ List<GarbageCollectorMXBean> gcs = ManagementFactory.getGarbageCollectorMXBeans();
+ if (gcs != null && !gcs.isEmpty()) {
+ for (GarbageCollectorMXBean gc : gcs) {
+ sb.append(String.format("\n %s: %s (%s ms)", gc.getName(), gc.getCollectionCount(), gc.getCollectionTime()));
+ }
+ }
+
+ return sb.toString();
+ }
+
+ @Override
+ protected JsonObject doCallJson(Map<String, Object> options) {
+ JsonObject root = new JsonObject();
+ JsonArray arr = new JsonArray();
+ root.put("garbageCollectors", arr);
+
+ List<GarbageCollectorMXBean> gcs = ManagementFactory.getGarbageCollectorMXBeans();
+ if (gcs != null && !gcs.isEmpty()) {
+ for (GarbageCollectorMXBean gc : gcs) {
+ JsonObject jo = new JsonObject();
+ arr.add(jo);
+ jo.put("name", gc.getName());
+ jo.put("collectionCount", gc.getCollectionCount());
+ jo.put("collectionTime", gc.getCollectionTime());
+ jo.put("memoryPoolNames", String.join(",", Arrays.asList(gc.getMemoryPoolNames())));
+ }
+ }
+ return root;
+ }
+}
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/ThreadDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/ThreadDevConsole.java
new file mode 100644
index 00000000000..ed98ea22724
--- /dev/null
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/ThreadDevConsole.java
@@ -0,0 +1,101 @@
+/*
+ * 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.impl.console;
+
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.annotations.DevConsole;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.util.Arrays;
+import java.util.Map;
+
+@DevConsole("thread")
+@Configurer(bootstrap = true)
+public class ThreadDevConsole extends AbstractDevConsole {
+
+ public ThreadDevConsole() {
+ super("jvm", "thread", "Thread", "Displays Threads information");
+ }
+
+ @Override
+ protected String doCallText(Map<String, Object> options) {
+ StringBuilder sb = new StringBuilder();
+
+ ThreadMXBean tb = ManagementFactory.getThreadMXBean();
+ if (tb != null) {
+ sb.append(String.format("Threads: %s\n", tb.getThreadCount()));
+ sb.append(String.format("Daemon Threads: %s\n", tb.getDaemonThreadCount()));
+ sb.append(String.format("Total Started Threads: %s\n", tb.getTotalStartedThreadCount()));
+ sb.append(String.format("Peak Threads: %s\n", tb.getPeakThreadCount()));
+
+ long[] ids = tb.getAllThreadIds();
+ Arrays.sort(ids);
+ for (long id : ids) {
+ ThreadInfo ti = tb.getThreadInfo(id);
+ if (ti != null) {
+ String lock = ti.getLockName() != null ? "locked: " + ti.getLockName() : "";
+ sb.append(String.format("\n Thread %s: %s (%s) %s", id, ti.getThreadName(), ti.getThreadState(), lock));
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+ @Override
+ protected JsonObject doCallJson(Map<String, Object> options) {
+ JsonObject root = new JsonObject();
+
+ ThreadMXBean tb = ManagementFactory.getThreadMXBean();
+ if (tb != null) {
+ root.put("threadCount", tb.getThreadCount());
+ root.put("daemonThreadCount", tb.getDaemonThreadCount());
+ root.put("totalStartedThreadCount", tb.getTotalStartedThreadCount());
+ root.put("peakThreadCount", tb.getPeakThreadCount());
+
+ JsonArray arr = new JsonArray();
+ root.put("threads", arr);
+
+ long[] ids = tb.getAllThreadIds();
+ Arrays.sort(ids);
+ for (long id : ids) {
+ ThreadInfo ti = tb.getThreadInfo(id);
+ if (ti != null) {
+ JsonObject jo = new JsonObject();
+ jo.put("id", ti.getThreadId());
+ jo.put("name", ti.getThreadName());
+ jo.put("state", ti.getThreadState());
+ jo.put("blockedCount", ti.getBlockedCount());
+ jo.put("blockedTime", ti.getBlockedTime());
+ jo.put("waitedCount", ti.getWaitedCount());
+ jo.put("waitedTime", ti.getWaitedTime());
+ if (ti.getLockName() != null) {
+ jo.put("lockName", ti.getLockName());
+ }
+ arr.add(jo);
+ }
+ }
+ }
+
+ return root;
+ }
+
+}
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 d51a7f79a27..f26d00b5afd 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
@@ -17,7 +17,14 @@
package org.apache.camel.cli.connector;
import java.io.File;
+import java.lang.management.ClassLoadingMXBean;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
import java.util.Collection;
+import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -168,11 +175,15 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C
ProcessHandle.current().info().user().ifPresent(u -> rc.put("user", u));
rc.put("platform", platform);
if (platformVersion != null) {
- rc.put("version", platformVersion);
+ rc.put("platformVersion", platformVersion);
}
if (mainClass != null) {
rc.put("mainClass", mainClass);
}
+ RuntimeMXBean mb = ManagementFactory.getRuntimeMXBean();
+ if (mb != null) {
+ rc.put("javaVersion", mb.getVmVersion());
+ }
root.put("runtime", rc);
// collect details via console
@@ -190,6 +201,23 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C
root.put("routes", json2.get("routes"));
}
}
+ // various details
+ JsonObject mem = collectMemory();
+ if (mem != null) {
+ root.put("memory", mem);
+ }
+ JsonObject cl = collectClassLoading();
+ if (cl != null) {
+ root.put("classLoading", cl);
+ }
+ JsonObject threads = collectThreads();
+ if (threads != null) {
+ root.put("threads", threads);
+ }
+ JsonObject gc = collectGC();
+ if (gc != null) {
+ root.put("gc", gc);
+ }
// and health-check readiness
Collection<HealthCheck.Result> res = HealthCheckHelper.invokeReadiness(camelContext);
for (var r : res) {
@@ -213,6 +241,60 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C
}
}
+ private JsonObject collectMemory() {
+ MemoryMXBean mb = ManagementFactory.getMemoryMXBean();
+ if (mb != null) {
+ JsonObject root = new JsonObject();
+ root.put("heapMemoryUsed", mb.getHeapMemoryUsage().getUsed());
+ root.put("heapMemoryCommitted", mb.getHeapMemoryUsage().getCommitted());
+ root.put("heapMemoryMax", mb.getHeapMemoryUsage().getMax());
+ root.put("nonHeapMemoryUsed", mb.getNonHeapMemoryUsage().getUsed());
+ root.put("nonHeapMemoryCommitted", mb.getNonHeapMemoryUsage().getCommitted());
+ return root;
+ }
+ return null;
+ }
+
+ private JsonObject collectClassLoading() {
+ ClassLoadingMXBean cb = ManagementFactory.getClassLoadingMXBean();
+ if (cb != null) {
+ JsonObject root = new JsonObject();
+ root.put("loadedClassCount", cb.getLoadedClassCount());
+ root.put("unloadedClassCount", cb.getUnloadedClassCount());
+ root.put("totalLoadedClassCount", cb.getTotalLoadedClassCount());
+ return root;
+ }
+ return null;
+ }
+
+ private JsonObject collectThreads() {
+ ThreadMXBean tb = ManagementFactory.getThreadMXBean();
+ if (tb != null) {
+ JsonObject root = new JsonObject();
+ root.put("threadCount", tb.getThreadCount());
+ root.put("peakThreadCount", tb.getPeakThreadCount());
+ return root;
+ }
+ return null;
+ }
+
+ private JsonObject collectGC() {
+ List<GarbageCollectorMXBean> gcs = ManagementFactory.getGarbageCollectorMXBeans();
+ if (gcs != null && !gcs.isEmpty()) {
+ JsonObject root = new JsonObject();
+ long count = 0;
+ long time = 0;
+ for (GarbageCollectorMXBean gc : gcs) {
+ count += gc.getCollectionCount();
+ time += gc.getCollectionTime();
+ }
+ root.put("collectionCount", count);
+ root.put("collectionTime", time);
+ return root;
+ }
+ return null;
+ }
+
@Override
protected void doStop() throws Exception {
// cleanup
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 e19a4f0f55f..32448d38b62 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
@@ -21,9 +21,11 @@ import java.util.concurrent.Callable;
import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.catalog.DefaultCamelCatalog;
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.CamelRouteStatus;
+import org.apache.camel.dsl.jbang.core.commands.process.CamelRouteTop;
import org.apache.camel.dsl.jbang.core.commands.process.CamelStatus;
-import org.apache.camel.dsl.jbang.core.commands.process.CamelTopStatus;
+import org.apache.camel.dsl.jbang.core.commands.process.CamelTop;
import org.apache.camel.dsl.jbang.core.commands.process.Hawtio;
import org.apache.camel.dsl.jbang.core.commands.process.Jolokia;
import org.apache.camel.dsl.jbang.core.commands.process.ListProcess;
@@ -44,8 +46,10 @@ public class CamelJBangMain implements Callable<Integer> {
.addSubcommand("stop", new CommandLine(new StopProcess(main)))
.addSubcommand("get", new CommandLine(new CamelStatus(main))
.addSubcommand("context", new CommandLine(new CamelContextStatus(main)))
- .addSubcommand("route", new CommandLine(new CamelRouteStatus(main)))
- .addSubcommand("top", new CommandLine(new CamelTopStatus(main))))
+ .addSubcommand("route", new CommandLine(new CamelRouteStatus(main))))
+ .addSubcommand("top", new CommandLine(new CamelTop(main))
+ .addSubcommand("context", new CommandLine(new CamelContextTop(main)))
+ .addSubcommand("route", new CommandLine(new CamelRouteTop(main))))
.addSubcommand("generate", new CommandLine(new CodeGenerator(main))
.addSubcommand("rest", new CommandLine(new CodeRestGenerator(main))))
.addSubcommand("jolokia", new CommandLine(new Jolokia(main)))
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java
new file mode 100644
index 00000000000..2c51d4acfa5
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java
@@ -0,0 +1,222 @@
+/*
+ * 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 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.TimeUtils;
+import org.apache.camel.util.json.JsonObject;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+
+@Command(name = "integration", aliases = { "int", "integration", "integrations", "context" },
+ description = "Top status of Camel integrations")
+public class CamelContextTop 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, name, mem, or age", defaultValue = "mem")
+ String sort;
+
+ public CamelContextTop(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());
+ // there must be a status file for the running Camel integration
+ if (root != null) {
+ Row row = new Row();
+ rows.add(row);
+ row.name = extractName(root, ph);
+ row.pid = "" + ph.pid();
+ row.uptime = extractSince(ph);
+ row.ago = TimeUtils.printSince(row.uptime);
+ JsonObject runtime = (JsonObject) root.get("runtime");
+ row.platform = extractPlatform(ph, runtime);
+ row.platformVersion = runtime != null ? runtime.getString("platformVersion") : null;
+ row.javaVersion = runtime != null ? runtime.getString("javaVersion") : null;
+ JsonObject context = (JsonObject) root.get("context");
+ row.state = context.getInteger("phase");
+ row.camelVersion = context.getString("version");
+
+ JsonObject mem = (JsonObject) root.get("memory");
+ if (mem != null) {
+ row.heapMemUsed = mem.getLong("heapMemoryUsed");
+ row.heapMemCommitted = mem.getLong("heapMemoryCommitted");
+ row.heapMemMax = mem.getLong("heapMemoryMax");
+ row.nonHeapMemUsed = mem.getLong("nonHeapMemoryUsed");
+ row.nonHeapMemCommitted = mem.getLong("nonHeapMemoryCommitted");
+ }
+ JsonObject threads = (JsonObject) root.get("threads");
+ if (threads != null) {
+ row.threadCount = threads.getInteger("threadCount");
+ row.peakThreadCount = threads.getInteger("peakThreadCount");
+ }
+ JsonObject cl = (JsonObject) root.get("classLoading");
+ if (cl != null) {
+ row.loadedClassCount = cl.getInteger("loadedClassCount");
+ row.totalLoadedClassCount = cl.getLong("totalLoadedClassCount");
+ }
+ JsonObject gc = (JsonObject) root.get("gc");
+ if (gc != null) {
+ row.gcCount = gc.getLong("collectionCount");
+ row.gcTime = gc.getLong("collectionTime");
+ }
+ }
+ });
+
+ // sort rows
+ rows.sort(this::sortRow);
+
+ if (!rows.isEmpty()) {
+ System.out.println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList(
+ new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid),
+ new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS)
+ .with(r -> r.name),
+ new Column().header("JAVA").dataAlign(HorizontalAlign.LEFT).with(this::getJavaVersion),
+ new Column().header("CAMEL").dataAlign(HorizontalAlign.LEFT).with(r -> r.camelVersion),
+ new Column().header("PLATFORM").dataAlign(HorizontalAlign.LEFT).with(this::getPlatform),
+ new Column().header("STATUS").headerAlign(HorizontalAlign.CENTER)
+ .with(r -> extractState(r.state)),
+ new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.ago),
+ new Column().header("HEAP").headerAlign(HorizontalAlign.CENTER).with(this::getHeapMemory),
+ new Column().header("NON-HEAP").headerAlign(HorizontalAlign.CENTER).with(this::getNonHeapMemory),
+ new Column().header("GC").headerAlign(HorizontalAlign.CENTER).with(this::getGC),
+ new Column().header("THREADS").headerAlign(HorizontalAlign.CENTER).with(this::getThreads),
+ new Column().header("CLASSES").headerAlign(HorizontalAlign.CENTER).with(this::getClassLoading))));
+ }
+
+ return 0;
+ }
+
+ private String extractPlatform(ProcessHandle ph, JsonObject runtime) {
+ String answer = runtime != null ? runtime.getString("platform") : null;
+ if ("Camel".equals(answer)) {
+ // generic camel, we need to check if we run in JBang
+ String cl = ph.info().commandLine().orElse("");
+ if (cl.contains("main.CamelJBang run")) {
+ answer = "JBang";
+ }
+ }
+ return answer;
+ }
+
+ 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 "mem":
+ return Long.compare(o1.heapMemUsed, o2.heapMemUsed) * -1; // we want the biggest first
+ case "age":
+ return Long.compare(o1.uptime, o2.uptime);
+ default:
+ return 0;
+ }
+ }
+
+ private String getPlatform(Row r) {
+ if (r.platformVersion != null) {
+ return r.platform + " v" + r.platformVersion;
+ } else {
+ return r.platform;
+ }
+ }
+
+ private String getHeapMemory(Row r) {
+ return asMegaBytesOneDigit(r.heapMemUsed) + "/" + asMegaBytesOneDigit(r.heapMemCommitted) + "/"
+ + asMegaBytesOneDigit(r.heapMemMax) + " MB";
+ }
+
+ private String getNonHeapMemory(Row r) {
+ return asMegaBytesOneDigit(r.nonHeapMemUsed) + "/" + asMegaBytesOneDigit(r.nonHeapMemCommitted) + " MB";
+ }
+
+ private String getThreads(Row r) {
+ return r.threadCount + "/" + r.peakThreadCount;
+ }
+
+ private String getClassLoading(Row r) {
+ return r.loadedClassCount + "/" + r.totalLoadedClassCount;
+ }
+
+ private String getGC(Row r) {
+ if (r.gcTime <= 0) {
+ return "";
+ } else {
+ return r.gcTime + "ms (" + r.gcCount + ")";
+ }
+ }
+
+ private String getJavaVersion(Row r) {
+ String v = r.javaVersion;
+ for (int i = 0; i < v.length(); i++) {
+ char ch = v.charAt(i);
+ if (Character.isDigit(ch) || ch == '.') {
+ continue;
+ }
+ return v.substring(0, i);
+ }
+ return v;
+ }
+
+ private static long asMegaBytesOneDigit(long bytes) {
+ return bytes / 1000 / 1000;
+ }
+
+ private static class Row {
+ String pid;
+ String platform;
+ String platformVersion;
+ String camelVersion;
+ String javaVersion;
+ String name;
+ int state;
+ String ago;
+ long uptime;
+ long heapMemUsed;
+ long heapMemCommitted;
+ long heapMemMax;
+ long nonHeapMemUsed;
+ long nonHeapMemCommitted;
+ int threadCount;
+ int peakThreadCount;
+ int loadedClassCount;
+ long totalLoadedClassCount;
+ long gcCount;
+ long gcTime;
+ }
+
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTopStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteTop.java
similarity index 89%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTopStatus.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteTop.java
index 44d6e8a17ea..afef2e6bb1c 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTopStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteTop.java
@@ -19,10 +19,10 @@ package org.apache.camel.dsl.jbang.core.commands.process;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
import picocli.CommandLine.Command;
-@Command(name = "top", description = "Top performing routes")
-public class CamelTopStatus extends CamelRouteStatus {
+@Command(name = "route", description = "Top performing routes")
+public class CamelRouteTop extends CamelRouteStatus {
- public CamelTopStatus(CamelJBangMain main) {
+ public CamelRouteTop(CamelJBangMain main) {
super(main);
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTopStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
similarity index 62%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTopStatus.java
rename to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
index 44d6e8a17ea..93c56715adf 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTopStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
@@ -16,28 +16,22 @@
*/
package org.apache.camel.dsl.jbang.core.commands.process;
+import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
-import picocli.CommandLine.Command;
+import picocli.CommandLine;
-@Command(name = "top", description = "Top performing routes")
-public class CamelTopStatus extends CamelRouteStatus {
+@CommandLine.Command(name = "top",
+ description = "Top status of Camel integrations (use --help to see sub commands)")
+public class CamelTop extends CamelCommand {
- public CamelTopStatus(CamelJBangMain main) {
+ public CamelTop(CamelJBangMain main) {
super(main);
}
@Override
- protected int sortRow(Row o1, Row o2) {
- // sort for highest mean value as we want the slowest in the top
- long m1 = o1.mean != null ? Long.parseLong(o1.mean) : 0;
- long m2 = o2.mean != null ? Long.parseLong(o2.mean) : 0;
- if (m1 < m2) {
- return 1;
- } else if (m1 > m2) {
- return -1;
- } else {
- return 0;
- }
+ public Integer call() throws Exception {
+ // default to top the integrations
+ new CommandLine(new CamelRouteTop(getMain())).execute();
+ return 0;
}
-
}
[camel] 02/02: CAMEL-18425: camel-cli - Display more information for top commands.
Posted by da...@apache.org.
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 90a5863a7611a47dd28ebc95754fece9b9aa5c8f
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 29 14:57:22 2022 +0200
CAMEL-18425: camel-cli - Display more information for top commands.
---
.../modules/ROOT/pages/camel-jbang.adoc | 36 +++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
index 1aab8db4ca3..ac79fa7d447 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
@@ -614,7 +614,7 @@ the total number of messages processed. The column _Since Last_
shows how long time ago the integration was active processing
incoming messages.
-You can also see the status of every routes, from all the local Camel integrations:
+You can also see the status of every routes, from all the local Camel integrations with `camel get route`:
[source,bash]
----
@@ -627,6 +627,40 @@ camel get route
TIP: Use `camel get --help` to display all the available commands as additional will be added in upcoming releases.
+=== Top status of Camel integrations
+
+The `camel top` command is intended for getting top utilization statistics (highest to lowest heap used memory)
+of the running Camel integrations.
+
+[source,bash]
+----
+camel top
+ PID NAME JAVA CAMEL PLATFORM STATUS AGE HEAP NON-HEAP GC THREADS CLASSES
+ 22104 chuck.yaml 11.0.13 3.19.0-SNAPSHOT JBang Running 2m10s 131/322/4294 MB 70/73 MB 17ms (6) 7/8 7456/7456
+ 14242 sample.camel.MyCamelApplica… 11.0.13 3.19.0-SNAPSHOT Spring Boot v2.7.3 Running 33m40s 115/332/4294 MB 62/66 MB 37ms (6) 16/16 8428/8428
+ 22116 bar.yaml 11.0.13 3.19.0-SNAPSHOT JBang Running 2m7s 33/268/4294 MB 54/58 MB 20ms (4) 7/8 6104/6104
+----
+
+The _HEAP_ column shows the heap memory (used/committed/max) and the non-heap (used/committed).
+The _GC_ column shows garbage collection information (time and total runs).
+The _CLASSES_ column shows number of classes (loaded/total).
+
+You can also see the top performing routes (highest to lowest mean processing time)
+of every routes, from all the local Camel integrations with `camel top route`:
+
+[source,bash]
+----
+camel top route
+ PID NAME ID FROM STATUS AGE TOTAL FAILED INFLIGHT MEAN MIN MAX SINCE-LAST
+ 22104 chuck.yaml chuck-norris-source-1 timer://chuck?period=10000 Started 10s 1 0 0 163 163 163 9s
+ 22116 bar.yaml route1 timer://yaml2?period=1000 Started 7s 7 0 0 1 0 11 0s
+ 22104 chuck.yaml chuck kamelet://chuck-norris-source Started 10s 1 0 0 0 0 0 9s
+ 22104 chuck.yaml log-sink-2 kamelet://source?routeId=log-sink-2 Started 10s 1 0 0 0 0 0 9s
+ 14242 sample.camel.MyCamelApplicat hello timer://hello?period=2000 Started 31m41s 948 0 0 0 0 4 0s
+----
+
+TIP: Use `camel top --help` to display all the available commands as additional will be added in upcoming releases.
+
=== Using Jolokia and Hawtio