This Confluence has been LDAP enabled, if you are an ASF Committer, please use your LDAP Credentials to login. Any problems file an INFRA jira ticket please.

Child pages
  • Camel JMX

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

...

Apache Camel has extensive support for JMX to allow you to monitor and control the Camel managed objects with a JMX client. Camel also provides a JMX component that allows you to subscribe to MBean notifications. This page is about how to manage and monitor Camel using JMX.

Activating JMX in Camel

Table of Contents

...

Spring JAR Dependencies Required By Camel 2.8 or Older

The following Spring jar files must be on the classpath in order for Camel to be able to use JMX instrumentation:

  • spring-context.jar
  • spring-aop.jar
  • spring-beans.jar
  • spring-core.jar

If these jar files are not on the classpath Camel will fallback to non JMX mode. Camel will log a warning to this affect using the logger: org.apache.camel.impl.DefaultCamelContext.

From Camel 2.9: the Spring jar files are no longer required for Camel to run in JMX mode.

Using JMX to manage Apache Camel

...

The DefaultManagementNamingStrategy is the default naming strategy which builds object names used for MBean registration. By default org.apache.camel is the domain name for all object names created by CamelNamingStrategy. The domain name of the MBean object can be configured by Java VM system property:

Code Block
-Dorg.apache.camel.jmx.mbeanObjectDomainName=your.domain.name

...

Or, by adding a jmxAgent element inside the camelContext element in Spring configuration:

Code Block
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" mbeanObjectDomainName="your.domain.name"/>
    ...
</camelContext>

...

Spring configuration always takes precedence over system properties when they both present. It is true for all JMX related configurations.

...

You can disable JMX instrumentation agent by setting the Java VM system property as follow. The property value is treated as boolean.

Code Block
-Dorg.apache.camel.jmx.disabled=true

...

Or, by adding a jmxAgent element inside the camelContext element in Spring configuration:

Code Block
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" disabled="true"/>
    ...
</camelContext>

...

Or in Camel 2.1 its a bit easier (not having to use JVM system property) if using pure Java as you can disable it as follows:

Code Block
CamelContext camel = new DefaultCamelContext();
camel.disableJMX();

...

Locating a MBeanServer in the Java VM

...

You can configure the matching default domain name via system property.

Code Block
-Dorg.apache.camel.jmx.mbeanServerDefaultDomain=<your.domain.name>

...

Or, by adding a jmxAgent element inside the camelContext element in Spring configuration:

Code Block
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" mbeanServerDefaultDomain="your.domain.name"/>
    ...
</camelContext>

...

If no matching MBeanServer can be found, a new one is created and the new MBeanServer's default domain name is set according to the default and configuration as mentioned above.

...

From Camel 1.5: the default value of usePlatformMBeanServer is true. Set the property to false to disable using platform MBeanServer.

Code Block
-Dorg.apache.camel.jmx.usePlatformMBeanServer=True

...

Or, by adding a jmxAgent element inside the camelContext element in Spring configuration:

Code Block
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" usePlatformMBeanServer="true"/>
    ...
</camelContext>

...

Creating JMX RMI Connector Server

JMX connector server enables MBeans to be remotely managed by a JMX client such as JConsole; Camel JMX RMI connector server can be optionally turned on by setting system property and the MBeanServer used by Camel is attached to that connector server.

Code Block
-Dorg.apache.camel.jmx.createRmiConnector=True

...

Or, by adding a jmxAgent element inside the camelContext element in Spring configuration:

Code Block
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" createConnector="true"/>
    ...
</camelContext>

...

JMX Service URL

The default JMX Service URL has the format:

Code Block
service:jmx:rmi:///jndi/rmi://localhost:<registryPort>/<serviceUrlPath>

...

where registryPort is the RMI registry port and the default value is 1099.

You can set the RMI registry port by system property.

Code Block
-Dorg.apache.camel.jmx.rmiConnector.registryPort=<port number>

...

Or, by adding a jmxAgent element inside the camelContext element in Spring configuration:

Code Block
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" createConnector="true" registryPort="port number"/>
    ...
</camelContext>

...

where serviceUrlPath is the path name in the URL and the default value is /jmxrmi/camel.

You can set the service URL path by system property.

Code Block
-Dorg.apache.camel.jmx.serviceUrlPath=<path>

...

From Camel 2.4: various options can also be set on the ManagementAgent:

...

{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedServiceUrlPathTest.java}

Or, by adding a jmxAgent element inside the camelContext element in Spring configuration:

Code Block
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" createConnector="true" serviceUrlPath="path"/>
    ...
</camelContext>

...

By default, RMI server object listens on a dynamically generated port, which can be a problem for connections established through a firewall. In such situations, RMI connection port can be explicitly set by the system property.

Code Block
-Dorg.apache.camel.jmx.rmiConnector.connectorPort=<port number>

...

Or by adding a jmxAgent element inside the camelContext element in Spring configuration:

Code Block
<camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring">
  <jmxAgent id="agent" createConnector="true" connectorPort="port number"/>
    ...
</camelContext>

...

When the connector port option is set, the JMX service URL will become:

Code Block
service:jmx:rmi://localhost:<connectorPort>/jndi/rmi://localhost:<registryPort>/<serviceUrlPath>

...

System Properties for Camel JMX Support

...

In short, modify your catalina.sh (or catalina.bat in Windows) file to set the following options...

Code Block
 set CATALINA_OPTS=-Dcom.sun.management.jmxremote \
    -Dcom.sun.management.jmxremote.port=1099 \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Dcom.sun.management.jmxremote.authenticate=false

...

JBoss AS 4

By default JBoss creates its own MBeanServer. To allow Camel to expose to the same server follow these steps:

  • Tell Camel to use the Platform MBeanServer (This defaults to true in Camel 1.5)
Code Block
<camel:camelContext id="camelContext">
  <camel:jmxAgent id="jmxAgent" mbeanObjectDomainName="org.yourname" usePlatformMBeanServer="true"/>
</camel:camelContext>

...

...

Alter the mbeanServerDefaultDomain to be WebSphere

Code Block
<camel:jmxAgent id="agent" createConnector="true" mbeanObjectDomainName="org.yourname" usePlatformMBeanServer="false" mbeanServerDefaultDomain="WebSphere"/>

...

Oracle OC4j

The Oracle OC4J J2EE application server will not allow Camel to access the platform MBeanServer. You can identify this in the log as Camel will log a WARN.

Code Block
xxx xx, xxxx xx:xx:xx xx org.apache.camel.management.InstrumentationLifecycleStrategy onContextStart
WARNING: Could not register CamelContext MBean
java.lang.SecurityException: Unauthorized access from application: xx to MBean: java.lang:type=ClassLoading
        at oracle.oc4j.admin.jmx.shared.UserMBeanServer.checkRegisterAccess(UserMBeanServer.java:873)

...

To resolve this you should disable the JMX agent in Camel, see section Disabling JMX instrumentation agent in Camel

...

The 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:

Code Block
<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.

Code Block
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.)

...

First you need to set up a JmxNotificationEventNotifier before you start the CamelContext.

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxNotificationEventNotifierTest.java}
Second you can register your listener for listening the event Wiki Markup
{snippet:id=e2|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxNotificationEventNotifierTest.java}

Using the Tracer MBean to get fine grained tracing

...

For example we have the following custom endpoint where we define some options to be managed:

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/management/CustomEndpoint.java}
From Camel 2.9: it's encouraged that you use the @ManagedResource, @ManagedAttribute, and @ManagedOperation attributes from the org.apache.camel.api.management package. This allows your custom code to not depend on Spring JARs.

...

From Camel 2.10: we made it easier to configure a naming pattern for the MBeans. The pattern is used as part of the ObjectName as they key after the domain name. By default Camel will use MBean names for the ManagedCamelContextMBean as follows:

Code Block
org.apache.camel:context=localhost/camel-1,type=context,name=camel-1

...

From Camel 2.13: the hostname is not included in the MBean names, so the above example would be as follows:

Code Block
org.apache.camel:context=camel-1,type=context,name=camel-1

...

If you configure a name on the CamelContext then that name is part of the ObjectName as well. For example if we have

...

...

<camelContext id="myCamel" ...>

Then the MBean names will be as follows:

Code Block
org.apache.camel:context=localhost/myCamel,type=context,name=myCamel

...

Now if there is a naming clash in the JVM, such as there already exists a MBean with that given name above, then Camel will by default try to auto correct this by finding a new free name in the JMXMBeanServer by using a counter. As shown below the counter is now appended, so we have myCamel-1 as part of the ObjectName:

Code Block
org.apache.camel:context=localhost/myCamel-1,type=context,name=myCamel

...

This is possible because Camel uses a naming pattern by default that supports the following tokens

...

Set a JVM system property to use a default management name pattern that prefixes the name with cool.

Code Block
System.setProperty(JmxSystemPropertyKeys.MANAGEMENT_NAME_PATTERN, "cool-#name#");

...

 

So if we want to explicit name both the CamelContext and to use fixed MBean names, that do not change e.g., has no counters, then we can use the new managementNamePattern attribute:

...

...

<camelContext id="myCamel" managementNamePattern="#name#">

Then the MBean names will always be as follows:

Code Block
org.apache.camel:context=localhost/myCamel,type=context,name=myCamel

...

In Java, you can configure the managementNamePattern as follows:

Code Block
context.getManagementNameStrategy().setNamePattern("#name#");

...

You can also use a different name in the managementNamePattern than the id, so for example we can do:

...

...

<camelContext id="myCamel" managementNamePattern="coolCamel">

You may want to do this in OSGi environments in case you do not want the OSGi bundle id as part of the MBean names. As the OSGi bundle id can change if you restart the server, or uninstall and install the same application. You can then do as follows to not use the OSGi bundle id as part of the name:

...

...

<camelContext id="myCamel" managementNamePattern="#name#">

Note this requires that myCamel is unique in the entire JVM. If you install a 2nd Camel application that has the same CamelContext id and managementNamePattern then Camel will fail upon starting, and report a MBean already exists exception.

...

Statistics enabled means that Camel will do fine grained performance statistics for that particular MBean. The statistics you can see are many, such as: number of exchanges completed/failed, last/total/mina/max/mean processing time, first/last failed time, etc.

Using Java DSL you set this level by:

Code Block
// only enable routes when Camel starts
context.getManagementStrategy().setStatisticsLevel(ManagementStatisticsLevel.RoutesOnly);

...

And from Spring DSL you do:

...

...

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" statisticsLevel="RoutesOnly"/>
  ...
</camelContext>

Hiding sensitive information

...

Using Java DSL you turn this on by:

Code Block
// only enable routes when Camel starts
context.getManagementStrategy().getManagementAgent().setMask(true);

...

And from Spring DSL you do:

...

...

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" mask="true"/>
  ...
</camelContext>

This will mask URIs having options such as password and passphrase, and use xxxxxx as the replacement value.

...

For example, on the default managed endpoints from camel-core org.apache.camel.api.management.mbean.ManagedEndpointMBean, we have declared that the EndpointUri JMX attribute is masked.

Code Block
@ManagedAttribute(description = "Endpoint URI", mask = true)
String getEndpointUri();

...

See Also