Monitoring other systems using the Camel JMX Component

Camel includes a JMX Component that can be a JMX consumer for other systems. That is, it can connect to a local or remote JMX MBean server and listen for JMX Notifications that will then flow through the specified Camel route. This component also includes the ability to create and register local JMX Monitor beans that will create JMX Notifications based on changes in other JMX MBeans.

This combination of capabilities—consuming JMX Notifications, and creating local Monitor beans that can generate JMX Notifications—gives you some extra options in terms of monitoring your integration routes. For example, if you have systems deployed remotely across a WAN, you can use this mechanism to aggregate and report on JMX metrics in that remote system onto a channel such as a JMS queue. You can then use this to gather up information within your Data Center.

This recipe will show you how to use the Camel JMX Component to create and register a monitor that watches for changes on an MBean attribute, and then catches those Notifications within a Camel route for processing.

Getting ready

The Java code for this recipe is located in the org.camelcookbook.monitoring.monitor package. The Spring XML files are located under src/main/resources/META-INF/spring and prefixed with monitor.

This recipe's instructions assume that we are monitoring an existing Camel route with an id of "monitorRoute". It does not matter which DSL, XML, or Java, that route is written in, or even what that route does since we are monitoring the number of exchanges (messages) that are processed by that route. This will create an MBean with the following name that we will monitor:

org.apache.camel:context=localhost/camel-1,type=routes,name="monitorRoute"

The following is the Java DSL version of a route used in the provided example code:

from("direct:start")
    .routeId("monitorRoute")
  .transform(simple("Monitoring ${body}"))
  .log("${body}")
  .to("mock:result");

This recipe assumes that you have JMX enabled and configured within your Camel route. See the Configuring JMX recipe for more details.

How to do it...

Create a Camel route that consumes from the Camel JMX endpoint that is configured with the coordinates for the JMX MBean from which you want to gather data.

Tip

In the Java DSL, use the Camel JMX components provided JMXUriBuilder class to make it easier to create the endpoint URI.

  1. Create a HashMap<String, String> that will contain the ObjectName parts for the JMX MBean to be monitored:
    Map<String, String> map = new HashMap<String, String>();
    map.put("context", "localhost/camel-1");
    map.put("type", "routes");
    map.put("name", ""monitorRoute"");

    Note

    Be careful when specifying the "context" portion as that is a combination of the <hostname>/<Camel context management name>, so its value will change depending on the hostname of the server it is running on, as well as the name of the Camel context. In Camel Version 2.13, it is expected that the use of the hostname in the JMX MBean name will become optional, and will be disabled by default.

  2. Use the JMXUriBuilder class provided with the Camel JMX Component to make it easier to create the correct URI to specify in the "from" portion of the Camel route. We are specifying the JMX Server ObjectDomain, and ObjectName properties initially; platform indicates local/in-process MBean server. These are followed by the properties that allow the Camel JMX Component to dynamically create a Monitor bean to send JMX Notifications when something interesting happens:
    JMXUriBuilder jmxUriBuilder = new JMXUriBuilder("platform")
      .withObjectDomain("org.apache.camel")
      .withObjectProperties(map)
      .withMonitorType("counter")
      .withObservedAttribute("ExchangesCompleted")
      .withInitThreshold(0)
      .withGranularityPeriod(500)
      .withOffset(1)
      .withDifferenceMode(false);
  3. Create a Camel route to process the JMX Notifications:
    // Resulting URI should be something like
    //  jmx:platform?objectDomain=org.apache.camel
    //  &key.context=localhost/camel-1&key.type=routes
    //  &key.name="monitorRoute"&monitorType=counter
    //  &observedAttribute=ExchangesCompleted&initThreshold=0
    //  &granularityPeriod=500&offset=1&differenceMode=false
    from(jmxUriBuilder.toString())
        .routeId("jmxMonitor")
      .log("${body}")
      .to("mock:monitor");

Note

The XML DSL format is similar except that you will either need to manually create the correct URI or call some Java method that will perform the equivalent of preceding steps 1 and 2.

How it works...

The Camel JMX Component is used in this recipe to do two things: create a JMX Notification consumer, and create a Monitor bean to send JMX Notifications.

The URI format to set up the Camel JMX Component to consume JMX Notifications from the in-process platform MBean server is as follows:

jmx://platform?options

To connect to a remote MBean server, you would specify the URI as follows:

jmx:service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi?options

To specify the ObjectName composed of multiple properties, you use the following syntax where the ObjectName property name is prefixed with "key." and followed by its value. For example, to monitor an MBean with the ObjectName property:

org.apache.camel:name=simpleBean

You specify the following URI:

jmx:platform?objectDomain=org.apache.camel             &key.name=simpleBean

The second thing that the Camel JMX Component can do for us is to create a local Monitor bean that will generate JMX Notifications based on change rules we specify.

For example, to generate a Notification every time the value of the MonitorNumber JMX attribute changes, we could use the following URI:

jmx:platform?objectDomain=org.apache.camel&key.name=simpleBean&monitorType=counter&observedAttribute=MonitorNumber&initThreshold=1&granularityPeriod=500

Under the covers, the Camel JMX Component will access the JMX API similar to the following example:

CounterMonitor monitor = 
    new CounterMonitor(); // javax.management.monitor
monitor.addObservedObject(makeObjectName("simpleBean"));
monitor.setObservedAttribute("MonitorNumber");
monitor.setNotify(true);
monitor.setInitThreshold(1);
monitor.setGranularityPeriod(500);
registerBean(monitor, makeObjectName("counter"));
monitor.start();

There's more...

In general, you would use the existing JMX aware tools to manage and monitor your Camel routes. The Camel JMX Component is useful in cases where you either can't use a conventional monitoring tool, such as when monitoring systems remotely over constrained network connections, or when you need a more do-it-yourself, custom approach.

The Camel JMX Component generates an XML or Java object that can be processed in subsequent route steps. This allows you to take local action based on the value of the Notification, thereby acting as a lightweight monitoring alert system. It also allows you to aggregate and summarize this data for rebroadcast on other channels, such as summarizing a number of monitored attributes, and periodically publishing on JMS or HTTP to some remote non-JMX listener. This provides you with some extra tools to create a smart agent that can monitor your code, and react to changing conditions—all using Camel.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.18.186