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 2015/07/27 11:57:28 UTC
camel git commit: CAMEL-9014: Added camel command to show endpoint
runtime stats.
Repository: camel
Updated Branches:
refs/heads/master e20760513 -> fae3bb65f
CAMEL-9014: Added camel command to show endpoint runtime stats.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/fae3bb65
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/fae3bb65
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/fae3bb65
Branch: refs/heads/master
Commit: fae3bb65fe15b4cb949db35593eaba859e2f3129
Parents: e207605
Author: Claus Ibsen <da...@apache.org>
Authored: Mon Jul 27 12:00:47 2015 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Mon Jul 27 12:04:35 2015 +0200
----------------------------------------------------------------------
.../mbean/ManagedCamelContextMBean.java | 3 +
.../management/mbean/ManagedCamelContext.java | 13 +-
.../management/ManagedCamelContextTest.java | 3 +
.../commands/AbstractLocalCamelController.java | 37 ++++
.../apache/camel/commands/CamelController.java | 9 +
.../camel/commands/ContextInfoCommand.java | 3 +
.../commands/EndpointStatisticCommand.java | 216 +++++++++++++++++++
.../jolokia/DefaultJolokiaCamelController.java | 36 ++++
.../camel/karaf/commands/EndpointStats.java | 43 ++++
.../OSGI-INF/blueprint/camel-commands.xml | 9 +
10 files changed, 369 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
index abf246e..4cb8905 100644
--- a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
+++ b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
@@ -43,6 +43,9 @@ public interface ManagedCamelContextMBean extends ManagedPerformanceCounterMBean
@ManagedAttribute(description = "Uptime")
String getUptime();
+ @ManagedAttribute(description = "Camel Management StatisticsLevel")
+ String getManagementStatisticsLevel();
+
@ManagedAttribute(description = "Camel Properties")
Map<String, String> getProperties();
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index 1cb56a1..a1c1be7 100644
--- a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -37,9 +37,6 @@ import javax.management.openmbean.CompositeType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
-import org.apache.camel.spi.ManagementStrategy;
-import org.w3c.dom.Document;
-
import org.apache.camel.CamelContext;
import org.apache.camel.Component;
import org.apache.camel.ComponentConfiguration;
@@ -60,9 +57,11 @@ import org.apache.camel.model.RouteDefinition;
import org.apache.camel.model.RoutesDefinition;
import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.model.rest.RestsDefinition;
+import org.apache.camel.spi.ManagementStrategy;
import org.apache.camel.util.CamelContextHelper;
import org.apache.camel.util.JsonSchemaHelper;
import org.apache.camel.util.ObjectHelper;
+import org.w3c.dom.Document;
/**
* @version
@@ -107,6 +106,14 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
return context.getUptime();
}
+ public String getManagementStatisticsLevel() {
+ if (context.getManagementStrategy().getManagementAgent() != null) {
+ return context.getManagementStrategy().getManagementAgent().getStatisticsLevel().name();
+ } else {
+ return null;
+ }
+ }
+
public String getClassResolver() {
return context.getClassResolver().getClass().getName();
}
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/camel-core/src/test/java/org/apache/camel/management/ManagedCamelContextTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedCamelContextTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedCamelContextTest.java
index f2fcf7f..46237b7 100644
--- a/camel-core/src/test/java/org/apache/camel/management/ManagedCamelContextTest.java
+++ b/camel-core/src/test/java/org/apache/camel/management/ManagedCamelContextTest.java
@@ -76,6 +76,9 @@ public class ManagedCamelContextTest extends ManagementTestSupport {
String managementName = (String) mbeanServer.getAttribute(on, "ManagementName");
assertEquals("19-camel-1", managementName);
+ String level = (String) mbeanServer.getAttribute(on, "ManagementStatisticsLevel");
+ assertEquals("Default", level);
+
String uptime = (String) mbeanServer.getAttribute(on, "Uptime");
assertNotNull(uptime);
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
index 1657a16..4fa7da0 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
@@ -41,8 +41,10 @@ import org.apache.camel.model.ModelHelper;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.model.rest.RestsDefinition;
+import org.apache.camel.spi.EndpointRegistry;
import org.apache.camel.spi.ManagementAgent;
import org.apache.camel.spi.RestRegistry;
+import org.apache.camel.spi.RuntimeEndpointRegistry;
import org.apache.camel.util.JsonSchemaHelper;
/**
@@ -71,6 +73,10 @@ public abstract class AbstractLocalCamelController extends AbstractCamelControll
answer.put("status", context.getStatus().name());
answer.put("uptime", context.getUptime());
answer.put("suspended", context.getStatus().isSuspended());
+ if (context.getManagementStrategy().getManagementAgent() != null) {
+ String level = context.getManagementStrategy().getManagementAgent().getStatisticsLevel().name();
+ answer.put("managementStatisticsLevel", level);
+ }
answer.put("allowUseOriginalMessage", context.isAllowUseOriginalMessage());
answer.put("messageHistory", context.isMessageHistory());
answer.put("tracing", context.isTracing());
@@ -424,6 +430,37 @@ public abstract class AbstractLocalCamelController extends AbstractCamelControll
return answer;
}
+ public List<Map<String, String>> getEndpointRuntimeStatistics(String camelContextName) throws Exception {
+ List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
+
+ if (camelContextName != null) {
+ CamelContext context = this.getLocalCamelContext(camelContextName);
+ if (context != null) {
+ EndpointRegistry staticRegistry = context.getEndpointRegistry();
+ for (RuntimeEndpointRegistry.Statistic stat : context.getRuntimeEndpointRegistry().getEndpointStatistics()) {
+
+ String url = stat.getUri();
+ String routeId = stat.getRouteId();
+ String direction = stat.getDirection();
+ Boolean isStatic = staticRegistry.isStatic(url);
+ Boolean isDynamic = staticRegistry.isDynamic(url);
+ long hits = stat.getHits();
+
+ Map<String, String> row = new LinkedHashMap<String, String>();
+ row.put("camelContextName", context.getName());
+ row.put("uri", url);
+ row.put("routeId", routeId);
+ row.put("direction", direction);
+ row.put("static", isStatic.toString());
+ row.put("dynamic", isDynamic.toString());
+ row.put("hits", "" + hits);
+ answer.add(row);
+ }
+ }
+ }
+ return answer;
+ }
+
public List<Map<String, String>> getRestServices(String camelContextName) throws Exception {
List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
index bb00f9e..67030bc 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
@@ -191,6 +191,15 @@ public interface CamelController {
List<Map<String, String>> getEndpoints(String camelContextName) throws Exception;
/**
+ * Return endpoint runtime statistics
+ *
+ * @param camelContextName the Camel context.
+ * @return a list of key/value pairs with endpoint runtime statistics
+ * @throws java.lang.Exception can be thrown
+ */
+ List<Map<String, String>> getEndpointRuntimeStatistics(String camelContextName) throws Exception;
+
+ /**
* Return the definition of the REST services as XML for the given Camel context.
*
* @param camelContextName the Camel context.
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
index d2a9731..698e809 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
@@ -75,6 +75,9 @@ public class ContextInfoCommand extends AbstractCamelCommand {
out.println(stringEscape.unescapeJava("\u001B[1mMiscellaneous\u001B[0m"));
out.println(stringEscape.unescapeJava("\tSuspended: " + row.get("suspended")));
out.println(stringEscape.unescapeJava("\tShutdown Timeout: " + row.get("shutdownTimeout") + " sec."));
+ if (row.get("managementStatisticsLevel") != null) {
+ out.println(stringEscape.unescapeJava("\tManagement StatisticsLevel: " + row.get("managementStatisticsLevel")));
+ }
out.println(stringEscape.unescapeJava("\tAllow UseOriginalMessage: " + row.get("allowUseOriginalMessage")));
out.println(stringEscape.unescapeJava("\tMessage History: " + row.get("messageHistory")));
out.println(stringEscape.unescapeJava("\tTracing: " + row.get("tracing")));
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/EndpointStatisticCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/EndpointStatisticCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/EndpointStatisticCommand.java
new file mode 100644
index 0000000..fb76655
--- /dev/null
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/EndpointStatisticCommand.java
@@ -0,0 +1,216 @@
+/**
+ * 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.commands;
+
+import java.io.PrintStream;
+import java.net.URLDecoder;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.util.URISupport;
+
+/**
+ * Display endpoint runtime statistics for a CamelContext
+ */
+public class EndpointStatisticCommand extends AbstractContextCommand {
+
+ private static final String URI_COLUMN_LABEL = "Uri";
+ private static final String ROUTE_COLUMN_LABEL = "Route Id";
+ private static final String DIRECTION_COLUMN_LABEL = "Direction";
+ private static final String STATIC_COLUMN_LABEL = "Static";
+ private static final String DYNAMIC_COLUMN_LABEL = "Dynamic";
+ private static final String HITS_COLUMN_LABEL = "Hits";
+
+ private static final int DEFAULT_COLUMN_WIDTH_INCREMENT = 0;
+ private static final String DEFAULT_FIELD_PREAMBLE = " ";
+ private static final String DEFAULT_FIELD_POSTAMBLE = " ";
+ private static final String DEFAULT_HEADER_PREAMBLE = " ";
+ private static final String DEFAULT_HEADER_POSTAMBLE = " ";
+ private static final int DEFAULT_FORMAT_BUFFER_LENGTH = 24;
+ // endpoint uris can be very long so clip by default after 120 chars
+ private static final int MAX_COLUMN_WIDTH = 120;
+ private static final int MIN_COLUMN_WIDTH = 12;
+
+ boolean decode = true;
+ private String[] filter;
+
+ public EndpointStatisticCommand(String context, boolean decode, String[] filter) {
+ super(context);
+ this.decode = decode;
+ this.filter = filter;
+ }
+
+ @Override
+ protected Object performContextCommand(CamelController camelController, String contextName, PrintStream out, PrintStream err) throws Exception {
+ List<Map<String, String>> endpoints = camelController.getEndpointRuntimeStatistics(contextName);
+
+ final Map<String, Integer> columnWidths = computeColumnWidths(endpoints);
+ final String headerFormat = buildFormatString(columnWidths, true);
+ final String rowFormat = buildFormatString(columnWidths, false);
+
+ if (endpoints.size() > 0) {
+ out.println(String.format(headerFormat, URI_COLUMN_LABEL, ROUTE_COLUMN_LABEL, DIRECTION_COLUMN_LABEL, STATIC_COLUMN_LABEL, DYNAMIC_COLUMN_LABEL, HITS_COLUMN_LABEL));
+ out.println(String.format(headerFormat, "---", "--------", "---------", "------", "-------", "----"));
+ for (Map<String, String> row : endpoints) {
+
+ String uri = row.get("uri");
+ if (decode) {
+ // decode uri so its more human readable
+ uri = URLDecoder.decode(uri, "UTF-8");
+ }
+ // sanitize and mask uri so we dont see passwords
+ uri = URISupport.sanitizeUri(uri);
+ String routeId = row.get("routeId");
+ String direction = row.get("direction");
+ String isStatic = row.get("static");
+ String isDynamic = row.get("dynamic");
+ String hits = row.get("hits");
+
+ // should we filter
+ if (isValidRow(direction, isStatic, isDynamic)) {
+ out.println(String.format(rowFormat, uri, routeId, direction, isStatic, isDynamic, hits));
+ }
+ }
+ }
+
+ return null;
+ }
+
+ protected boolean isValidRow(String direction, String isStatic, String isDynamic) {
+ if (filter == null || filter.length == 0) {
+ return true;
+ }
+
+ boolean answer = false;
+ for (String f : filter) {
+ if ("in".equals(f)) {
+ answer = "in".equals(direction);
+ } else if ("out".equals(f)) {
+ answer = "out".equals(direction);
+ } else if ("static".equals(f)) {
+ answer = "true".equals(isStatic);
+ } else if ("dynamic".equals(f)) {
+ answer = "true".equals(isDynamic);
+ }
+ // all filters must apply to accept when multi valued
+ if (!answer) {
+ return false;
+ }
+ }
+ return answer;
+ }
+
+ private Map<String, Integer> computeColumnWidths(final Iterable<Map<String, String>> endpoints) throws Exception {
+ if (endpoints == null) {
+ throw new IllegalArgumentException("Unable to determine column widths from null Iterable<Endpoint>");
+ } else {
+ int maxUriLen = 0;
+ int maxRouteIdLen = 0;
+ int maxDirectionLen = 0;
+ int maxStaticLen = 0;
+ int maxDynamicLen = 0;
+ int maxHitsLen = 0;
+
+ for (Map<String, String> row : endpoints) {
+ final String name = row.get("camelContextName");
+
+ String uri = row.get("uri");
+ if (decode) {
+ // decode uri so its more human readable
+ uri = URLDecoder.decode(uri, "UTF-8");
+ }
+ // sanitize and mask uri so we dont see passwords
+ uri = URISupport.sanitizeUri(uri);
+
+ maxUriLen = Math.max(maxUriLen, uri == null ? 0 : uri.length());
+
+ final String routeId = row.get("routeId");
+ maxRouteIdLen = Math.max(maxRouteIdLen, routeId == null ? 0 : routeId.length());
+
+ final String direction = row.get("direction");
+ maxDirectionLen = Math.max(maxDirectionLen, direction == null ? 0 : direction.length());
+
+ final String isStatic = row.get("static");
+ maxStaticLen = Math.max(maxStaticLen, isStatic == null ? 0 : isStatic.length());
+
+ final String isDynamic = row.get("dynamic");
+ maxDynamicLen = Math.max(maxDynamicLen, isDynamic == null ? 0 : isDynamic.length());
+
+ final String hits = row.get("hits");
+ maxHitsLen = Math.max(maxHitsLen, hits == null ? 0 : hits.length());
+ }
+
+ final Map<String, Integer> retval = new Hashtable<String, Integer>();
+ retval.put(URI_COLUMN_LABEL, maxUriLen);
+ retval.put(ROUTE_COLUMN_LABEL, maxRouteIdLen);
+ retval.put(DIRECTION_COLUMN_LABEL, maxDirectionLen);
+ retval.put(STATIC_COLUMN_LABEL, maxStaticLen);
+ retval.put(DYNAMIC_COLUMN_LABEL, maxDynamicLen);
+ retval.put(HITS_COLUMN_LABEL, maxHitsLen);
+
+ return retval;
+ }
+ }
+
+ private String buildFormatString(final Map<String, Integer> columnWidths, final boolean isHeader) {
+ final String fieldPreamble;
+ final String fieldPostamble;
+ final int columnWidthIncrement;
+
+ if (isHeader) {
+ fieldPreamble = DEFAULT_HEADER_PREAMBLE;
+ fieldPostamble = DEFAULT_HEADER_POSTAMBLE;
+ } else {
+ fieldPreamble = DEFAULT_FIELD_PREAMBLE;
+ fieldPostamble = DEFAULT_FIELD_POSTAMBLE;
+ }
+ columnWidthIncrement = DEFAULT_COLUMN_WIDTH_INCREMENT;
+
+ int uriLen = Math.min(columnWidths.get(URI_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+ uriLen = Math.max(MIN_COLUMN_WIDTH, uriLen);
+
+ int routeIdLen = Math.min(columnWidths.get(ROUTE_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+ routeIdLen = Math.max(MIN_COLUMN_WIDTH, routeIdLen);
+
+ int directionLen = Math.min(columnWidths.get(DIRECTION_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+ directionLen = Math.max(MIN_COLUMN_WIDTH, directionLen);
+
+ int staticLen = Math.min(columnWidths.get(STATIC_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+ staticLen = Math.max(MIN_COLUMN_WIDTH, staticLen);
+
+ int dynamicLen = Math.min(columnWidths.get(DYNAMIC_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+ dynamicLen = Math.max(MIN_COLUMN_WIDTH, staticLen);
+
+ // last row does not have min width
+
+ final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
+ retval.append(fieldPreamble).append("%-").append(uriLen).append('.').append(uriLen).append('s').append(fieldPostamble).append(' ');
+ retval.append(fieldPreamble).append("%-").append(routeIdLen).append('.').append(routeIdLen).append('s').append(fieldPostamble).append(' ');
+ retval.append(fieldPreamble).append("%-").append(directionLen).append('.').append(directionLen).append('s').append(fieldPostamble).append(' ');
+ retval.append(fieldPreamble).append("%-").append(staticLen).append('.').append(staticLen).append('s').append(fieldPostamble).append(' ');
+ retval.append(fieldPreamble).append("%-").append(dynamicLen).append('.').append(dynamicLen).append('s').append(fieldPostamble).append(' ');
+ retval.append(fieldPreamble).append("%s").append(fieldPostamble).append(' ');
+
+ return retval.toString();
+ }
+
+ private int getMaxColumnWidth() {
+ return MAX_COLUMN_WIDTH;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java b/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
index 8f8ffae..454fbb0 100644
--- a/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
+++ b/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
@@ -538,6 +538,42 @@ public class DefaultJolokiaCamelController extends AbstractCamelController imple
}
@Override
+ public List<Map<String, String>> getEndpointRuntimeStatistics(String camelContextName) throws Exception {
+ if (jolokia == null) {
+ throw new IllegalStateException("Need to connect to remote jolokia first");
+ }
+
+ List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
+
+ ObjectName found = lookupCamelContext(camelContextName);
+ if (found != null) {
+ String pattern = String.format("%s:context=%s,type=services,name=DefaultRuntimeEndpointRegistry", found.getDomain(), found.getKeyProperty("context"));
+ ObjectName on = ObjectName.getInstance(pattern);
+
+ J4pExecResponse response = jolokia.execute(new J4pExecRequest(on, "endpointStatistics()"));
+ if (response != null) {
+ JSONObject data = response.getValue();
+ for (Object obj : data.values()) {
+ JSONObject data2 = (JSONObject) obj;
+ JSONObject service = (JSONObject) data2.values().iterator().next();
+
+ Map<String, String> row = new LinkedHashMap<String, String>();
+ row.put("index", asString(service.get("index")));
+ row.put("url", asString(service.get("url")));
+ row.put("routeId", asString(service.get("routeId")));
+ row.put("direction", asString(service.get("direction")));
+ row.put("static", asString(service.get("static")));
+ row.put("dynamic", asString(service.get("dynamic")));
+ row.put("hits", asString(service.get("hits")));
+ answer.add(row);
+ }
+ }
+ }
+
+ return answer;
+ }
+
+ @Override
public List<Map<String, String>> getRestServices(String camelContextName) throws Exception {
if (jolokia == null) {
throw new IllegalStateException("Need to connect to remote jolokia first");
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/EndpointStats.java
----------------------------------------------------------------------
diff --git a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/EndpointStats.java b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/EndpointStats.java
new file mode 100644
index 0000000..a9b64b6
--- /dev/null
+++ b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/EndpointStats.java
@@ -0,0 +1,43 @@
+/**
+ * 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.karaf.commands;
+
+import org.apache.camel.commands.EndpointStatisticCommand;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+@Command(scope = "camel", name = "endpoint-stats", description = "Display endpoint runtime statistics")
+public class EndpointStats extends CamelCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the Camel context", required = true, multiValued = false)
+ String name;
+
+ @Option(name = "--filter", aliases = "-f", description = "Filter the list by in,out,static,dynamic",
+ required = false, multiValued = true)
+ String[] filter;
+
+ @Option(name = "--decode", aliases = "-d", description = "Whether to decode the endpoint uri so its human readable",
+ required = false, multiValued = false, valueToShowInHelp = "true")
+ boolean decode = true;
+
+ protected Object doExecute() throws Exception {
+ EndpointStatisticCommand command = new EndpointStatisticCommand(name, decode, filter);
+ return command.execute(camelController, System.out, System.err);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/fae3bb65/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
----------------------------------------------------------------------
diff --git a/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml b/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
index 8603db2..ba134bf 100644
--- a/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
+++ b/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
@@ -179,6 +179,15 @@
<null/>
</completers>
</command>
+ <command name="camel/endpoint-stats">
+ <action class="org.apache.camel.karaf.commands.EndpointStats">
+ <property name="camelController" ref="camelController"/>
+ </action>
+ <completers>
+ <ref component-id="camelContextCompleter"/>
+ <null/>
+ </completers>
+ </command>
<command name="camel/endpoint-explain">
<action class="org.apache.camel.karaf.commands.EndpointExplain">
<property name="camelController" ref="camelController"/>