Author: davsclaus Date: Fri Dec 31 10:00:22 2010 New Revision: 1054080 URL: http://svn.apache.org/viewvc?rev=1054080&view=rev Log: CAMEL-1397: Added some basic route statistics to web console. Thanks to Ben for patch.
Added: camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java Modified: camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp Modified: camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java?rev=1054080&r1=1054079&r2=1054080&view=diff ============================================================================== --- camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java (original) +++ camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java Fri Dec 31 10:00:22 2010 @@ -20,6 +20,8 @@ import org.apache.camel.CamelContext; import org.apache.camel.ServiceStatus; import org.apache.camel.model.DescriptionDefinition; import org.apache.camel.model.RouteDefinition; +import org.apache.camel.web.util.JMXRouteStatistics; +import org.apache.camel.web.util.RouteStatistics; /** * Represents a route. @@ -29,6 +31,7 @@ import org.apache.camel.model.RouteDefin public class Route { private CamelContext camelContext; private RouteDefinition route; + private final RouteStatistics statistics = new JMXRouteStatistics(); public Route() { } @@ -66,4 +69,13 @@ public class Route { public boolean isStoppable() { return route.isStoppable(camelContext); } + + public Object getStatistic(String attribute) { + Object answer = statistics.getRouteStatistic(camelContext, route.getId(), attribute); + if (answer == null) { + // we don't want null on web pages so we return an empty string + return ""; + } + return answer; + } } Added: camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java?rev=1054080&view=auto ============================================================================== --- camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java (added) +++ camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java Fri Dec 31 10:00:22 2010 @@ -0,0 +1,76 @@ +/** + * 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.web.util; + +import java.text.DateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.apache.camel.CamelContext; +import org.apache.camel.management.ManagedManagementStrategy; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Gathers {...@link RouteStatistics} from JMX. + * <p/> + * If JMX is disabled then no statistics can be gathered, and <tt>null</tt> is returned. + */ +public class JMXRouteStatistics implements RouteStatistics { + + private static final Log LOG = LogFactory.getLog(JMXRouteStatistics.class); + + @SuppressWarnings("unchecked") + public Object getRouteStatistic(CamelContext camelContext, String routeID, String attribute) { + // only possible if JMX is enabled + if (!(camelContext.getManagementStrategy() instanceof ManagedManagementStrategy)) { + return null; + } + + try { + MBeanServer server = camelContext.getManagementStrategy().getManagementAgent().getMBeanServer(); + String domain = camelContext.getManagementStrategy().getManagementAgent().getMBeanObjectDomainName(); + + ObjectName objName = new ObjectName(domain + ":type=routes,*"); + List<ObjectName> cacheList = new LinkedList(server.queryNames(objName, null)); + for (Iterator<ObjectName> iter = cacheList.iterator(); iter.hasNext();) { + objName = iter.next(); + String keyProps = objName.getCanonicalKeyPropertyListString(); + ObjectName objectInfoName = new ObjectName(domain + ":" + keyProps); + String currentRouteID = (String) server.getAttribute(objectInfoName, "RouteId"); + if (currentRouteID.equals(routeID)) { + Object value = server.getAttribute(objectInfoName, attribute); + if (value instanceof Date) { + DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); + return df.format(value); + } else { + return value; + } + } + } + } catch (Exception e) { + LOG.warn("Error getting route statistic from JMX. This exception will be ignored.", e); + } + + return null; + } + +} Added: camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java?rev=1054080&view=auto ============================================================================== --- camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java (added) +++ camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java Fri Dec 31 10:00:22 2010 @@ -0,0 +1,35 @@ +/** + * 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.web.util; + +import org.apache.camel.CamelContext; + +/** + * @version $Revision$ + */ +public interface RouteStatistics { + + /** + * Gets statistic for the given route + * + * @param camelContext the context in question + * @param routeID the routeID to retrieve stats for + * @param attribute the attribute to retrieve + * @return the statistic, or <tt>null</tt> if not possible to find or get the statistic + */ + Object getRouteStatistic(CamelContext camelContext, String routeID, String attribute); +} Modified: camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp?rev=1054080&r1=1054079&r2=1054080&view=diff ============================================================================== --- camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp (original) +++ camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp Fri Dec 31 10:00:22 2010 @@ -10,6 +10,9 @@ <th>Route</th> <th colspan="2">Status</th> <th>Remove</th> + <th>Exchanges (Completed/Failed/Inflight)</th> + <th>Processing Time (Min/Max/Mean)</th> + <th>Message Time (First/Last)</th> </tr> <ul> #for(i <- it.getRoutes) @@ -40,6 +43,15 @@ <a href='${uri("/routes/" + i.getId + "/remove")}'>remove</a> #end </td> + <td> + ${i.getStatistic("ExchangesCompleted")} / ${i.getStatistic("ExchangesFailed")} / ${i.getStatistic("InflightExchanges")} + </td> + <td> + ${i.getStatistic("MinProcessingTime")} / ${i.getStatistic("MaxProcessingTime")} / ${i.getStatistic("MeanProcessingTime")} + </td> + <td> + ${i.getStatistic("FirstExchangeCompletedTimestamp")} / ${i.getStatistic("LastExchangeCompletedTimestamp")} + </td> </tr> #end </ul> Added: camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java?rev=1054080&view=auto ============================================================================== --- camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java (added) +++ camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java Fri Dec 31 10:00:22 2010 @@ -0,0 +1,72 @@ +/** + * 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.web.util; + +import java.util.List; +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.model.RouteDefinition; +import org.apache.camel.model.RoutesDefinition; +import org.apache.camel.util.CastUtils; +import org.apache.camel.web.resources.CamelContextResource; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.AbstractXmlApplicationContext; +import org.springframework.context.support.FileSystemXmlApplicationContext; + +public class JMXRouteStatisticsTest extends Assert { + private AbstractXmlApplicationContext applicationContext; + private CamelContext camelContext; + private RouteStatistics statistics = new JMXRouteStatistics(); + + @Test + public void testRouteStats() throws Exception { + CamelContextResource resource = new CamelContextResource(camelContext); + RoutesDefinition routes = resource.getRoutesResource().getRouteDefinitions(); + List<RouteDefinition> list = routes.getRoutes(); + Object exchangesCompleted = statistics.getRouteStatistic(camelContext, list.get(0).getId(), "ExchangesCompleted"); + assertEquals("JMX value incorrect, should be 0", new Long(0), exchangesCompleted); + + ProducerTemplate template = camelContext.createProducerTemplate(); + template.sendBody("seda:foo", "test"); + + Thread.sleep(100); + + exchangesCompleted = statistics.getRouteStatistic(camelContext, list.get(0).getId(), "ExchangesCompleted"); + assertEquals("JMX value incorrect, should be 1", new Long(1), exchangesCompleted); + } + + @Before + public void setUp() throws Exception { + applicationContext = new FileSystemXmlApplicationContext("src/main/webapp/WEB-INF/applicationContext.xml"); + applicationContext.start(); + Map<String, CamelContext> beansOfType = CastUtils.cast(applicationContext.getBeansOfType(CamelContext.class)); + camelContext = beansOfType.isEmpty() ? null : beansOfType.values().iterator().next(); + assertNotNull("camelContext", camelContext); + } + + @After + public void tearDown() throws Exception { + if (applicationContext != null) { + applicationContext.stop(); + } + } +}