Camel JMXPage edited by willem jiang
Comment:
CAMEL-2753
Changes (1)
Full ContentCamel JMXApache Camel has extensive support for JMX to allow you to monitor and control the Camel managed objects a JMX client.
Spring Dependencyspring-context.jar, spring-aop.jar, spring-beans.jar, spring-core.jar is needed on the classpath by Camel to be able to use JMX instrumentation. If these .jars is not on the classpath Camel will fallback to non JMX mode. This situation is logged at WARN level using logger name org.apache.camel.impl.DefaultCamelContext. Using JMX to manage Apache Camel
JMX inside an Application ServerJBoss AS 4By default JBoss creates its own MBean server. To allow Camel to expose to the same server follow these steps: 1. Tell Camel to use the Platform MBean Server (This defaults to true in Camel 1.5) <camel:camelContext id="camelContext"> <camel:jmxAgent id="jmxAgent" mbeanObjectDomainName="org.yourname" usePlatformMBeanServer="true" /> </camel:camelContext> 2. Alter your JBoss instance to use the Platform MBean server. WebSphereAlter the mbeanServerDefaultDomain to be "WebSphere" <camel:jmxAgent id="agent" createConnector="true" mbeanObjectDomainName="org.yourname" mbeanServerDefaultDomain="WebSphere"/> Advanced JMX ConfigurationThe spring configuration file allows you to configure how Camel is exposed to JMX for management. In some cases, you could specify more information here, like the connector's port or the path name. Example:<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <jmxAgent id="agent" createConnector="true" registryPort="2000" mbeanServerDefaultDomain="org.apache.camel.test"/> <route> <from uri="seda:start"/> <to uri="mock:result"/> </route> </camelContext> If you wish to change the Java 5 JMX settings you can use various JMX system properties For example you can enable remote JMX connections to the Sun JMX connector, via setting the following environment variable (using set or export depending on your platform). These settings only configure the Sun JMX connector within Java 1.5+, not the JMX connector that Camel creates by default. SUNJMX=-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=1616 \ -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false (The SUNJMX environment variable is simple used by the startup script for Camel, as additional startup parameters for the JVM. If you start Camel directly, you'll have to pass these parameters yourself.) jmxAgent Properties Reference
Registering your own Managed EndpointsAvailable as of Camel 2.0 For example we have the following custom endpoint where we define some options to be managed: @ManagedResource(description = "Our custom managed endpoint") public class CustomEndpoint extends MockEndpoint implements ManagementAware<CustomEndpoint> { public CustomEndpoint(final String endpointUri, final Component component) { super(endpointUri, component); } public Object getManagedObject(CustomEndpoint object) { return this; } public boolean isSingleton() { return true; } protected String createEndpointUri() { return "custom"; } @ManagedAttribute public String getFoo() { return "bar"; } @ManagedAttribute public String getEndpointUri() { return super.getEndpointUri(); } } Programming your own Managed ServicesAvailable as of Camel 2.1 Camel now offers to use your own mbeans when registering services for management. What that means is for example you can develop a custom Camel component and have it expose mbeans for endpoints, consumers and producers etc. All you need to do is to implement the interface org.apache.camel.spi.ManagementAware and return the managed object Camel should use. Now before you think oh boys the JMX API is really painful and terrible, then yeah you are right. Lucky for us Spring though too and they created a range of annotations you can use to export management on an existing bean. That means that you often use that and just return this in the getManagedObject from the ManagementAware interface. For an example see the code example above with the CustomEndpoint. Now in Camel 2.1 you can do this for all the objects that Camel registers for management which are quite a bunch, but not all. For services which do not implement this ManagementAware interface then Camel will fallback to using default wrappers as defined in the table below:
In addition to that there are some extended wrappers for specialized types such as
And in the future we will add additional wrappers for more EIP patterns. ManagementNamingStrategyAvailable as of Camel 2.1 Camel provides a pluggable API for naming strategy by org.apache.camel.spi.ManagementNamingStrategy. A default implementation is used to compute the mbean names that all mbeans are registered with. ManagementStrategyAvailable as of Camel 2.1 Camel now provides a totally pluggable management strategy that allows you to be 100% in control of management. It is a rich interface with many methods for management. Not only for adding and removing managed objects from the mbean server but also event notification is provided as well using the org.apache.camel.spi.EventNotifier API. What it does for example is to easier provide an adapter for other management products. In additional it also allows you to provide more details and features that are provided out of the box at Apache. Configuring level of granularity for performance statisticsAvailable as of Camel 2.1 You can now set a pre set level whether performance statistics is enabled or not when Camel start ups. The levels are
At runtime you can always use the management console (such as jconsole) to change on a given route or processor whether its statistics are enabled or not.
Using Java DSL you set this level by:
// only enable routes when Camel starts
context.getManagementStrategy().setSatisticsLevel(ManagementStatisticsLevel.RoutesOnly);
And from Spring DSL you do: <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <jmxAgent id="agent" statisticsLevel="RoutesOnly"/> ... </camelContext> Which endpoints are registeredIn Camel 2.1 onwards only singleton endpoints are registered as the overhead for non singleton will be substantial in cases where thousands or millions of endpoints are used. This can happens when using a Recipient List EIP or from a ProducerTemplate that sends a lot of messages. Which processors are registeredSee this FAQ. How to use the JMX NotificationListener to listen the camel events?From Camel 2.4 you can use a customer JMX NotificationListener to listen the camel events. // Set up the JmxNotificationEventNotifier notifier = new JmxNotificationEventNotifier(); notifier.setSource("MyCamel"); notifier.setIgnoreCamelContextEvents(true); notifier.setIgnoreRouteEvents(true); notifier.setIgnoreServiceEvents(true); CamelContext context = new DefaultCamelContext(createRegistry()); context.getManagementStrategy().addEventNotifier(notifier); // Set up the ManagementNamingStrategy DefaultManagementNamingStrategy naming = (DefaultManagementNamingStrategy) context.getManagementStrategy().getManagementNamingStrategy(); naming.setHostName("localhost"); naming.setDomainName("org.apache.camel"); return context; } public void testExchangeDone() throws Exception { // register the NotificationListener ObjectName on = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=eventnotifiers,name=JmxEventNotifier"); MyNotificationListener listener = new MyNotificationListener(); context.getManagementStrategy().getManagementAgent().getMBeanServer().addNotificationListener(on, listener, new NotificationFilter() { public boolean isNotificationEnabled(Notification notification) { return notification.getSource().equals("MyCamel"); } }, null); getMockEndpoint("mock:result").expectedMessageCount(1); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); assertEquals("Get a wrong number of events", 5, listener.getEventCounter()); context.stop(); } public void testExchangeFailed() throws Exception { ObjectName on = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=eventnotifiers,name=JmxEventNotifier"); MyNotificationListener listener = new MyNotificationListener(); context.getManagementStrategy().getManagementAgent().getMBeanServer().addNotificationListener(on, listener, new NotificationFilter() { public boolean isNotificationEnabled(Notification notification) { return true; } }, null); try { template.sendBody("direct:fail", "Hello World"); fail("Should have thrown an exception"); } catch (Exception e) { // expected assertIsInstanceOf(IllegalArgumentException.class, e.getCause()); } assertEquals("Get a wrong number of events", 3, listener.getEventCounter()); context.stop(); } @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").to("log:foo").to("mock:result"); from("direct:fail").throwException(new IllegalArgumentException("Damn")); } }; } private class MyNotificationListener implements NotificationListener { private int eventCounter; public void handleNotification(Notification notification, Object handback) { log.debug("Get the notification : " + notification); eventCounter++; } public int getEventCounter() { return eventCounter; } } } Second you can register your listener for listening the event Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
See Also
Change Notification Preferences
View Online
|
View Changes
|
Add Comment
|
- [CONF] Apache Camel > Camel JMX confluence
- [CONF] Apache Camel > Camel JMX confluence
- [CONF] Apache Camel > Camel JMX confluence
- [CONF] Apache Camel > Camel JMX confluence
- [CONF] Apache Camel > Camel JMX confluence