Camel provides a lot of JMX information for internal constructs (routes, endpoints, and so on) as well as for Java classes invoked from Camel. For example, when you include a call to a custom Java method as a part of a route, Camel will expose that through JMX as a Camel Processor and associate many JMX attributes with it. These include how many messages were sent to that processor, number of redelivery attempts, timestamps for initial and last messages processed, and so on.
There are times when you want to provide custom, or additional, JMX attributes and operations, such as code-specific metrics, and you want the ability to monitor and interact with these from your operational monitoring tools. This recipe shows how to annotate your Java code to expose custom JMX attributes and operations. These will seamlessly integrate with, and augment, the management information provided by Camel.
The Java code for this recipe is located in the org.camelcookbook.monitoring.managed
package. The Spring XML files are located under src/main/resources/META-INF/spring
and prefixed with managed
.
This recipe's instructions assume you have an existing Java class that you are calling from a Camel route. The following is the base Java code we started adding JMX to:
public class MyManagedBean { private int camelsSeenCount; public String doSomething(String body) { if (body.contains("Camel")) { camelsSeenCount++; } return "Managed " + body; } public int getCamelsSeenCount() { return camelsSeenCount; } public void resetCamelsSeenCount() { camelsSeenCount = 0; } }
This recipe assumes that you have JMX enabled and configured within your Camel route. See the Configuring JMX recipe for more details.
Use Camel's management annotations—@ManagedResource
, @ManagedAttribute
, and @ManagedOperation
—to decorate the Java classes that you want exposed through JMX along with the rest of Camel's MBeans.
@ManagedResource
, including an optional description for your code that will be associated with the JMX MBean for your code:import org.apache.camel.api.management.ManagedResource; @ManagedResource(description="My Bean within Camel") public class MyManagedBean {
getPropertyName()
) in your code that you want to expose as a JMX attribute, annotate that property together with @ManagedAttribute
, including an optional description:import org.apache.camel.api.management.ManagedAttribute; @ManagedAttribute(description = "Number of Camels Seen") public int getCamelsSeenCount() { return camelsSeenCount; }
@ManagedOperation
, including an optional description:import org.apache.camel.api.management.ManagedOperation; @ManagedOperation(description = "Set count to Zero") public void resetCamelsSeenCount() { camelsSeenCount = 0; }
When Camel sees you referencing @ManagedResouce
annotated code, it will include your attributes and operations alongside the standard JMX information that it provides. This will appear in JMX as an ObjectName
like the following:
org.apache.camel:context=localhost/camel-1,type=processors, name="bean1"
Your JMX attributes and operations will be integrated with the ones that Camel provides.
Camel will automatically categorize how your code is exposed as MBeans based on where your code is referenced within the route. Camel will set the type key in the JMX name based on whether your code is referenced as a processor, endpoint, and so on.
Camel will, by default, generically name and number your code within JMX. For example, a bean()
callout in a Camel route will show up as a JMX MBean bean1
. If you want to specify your own unique ID, use the id
DSL after your custom object.
Naming routes and endpoints using the id
statement is a great way to help others, including yourself in future, understand what is happening in your routes at runtime. These names will prove most useful in those stressful times, late at night, when something is not working quite right, and you are under pressure to fix it. Seeing meaningful named objects within your JMX console will save you a lot of stress.
In the XML DSL, you can do this by setting the id
attribute of the bean
element:
<bean id="myManagedBean" ref="myBean"/>
In the Java DSL, use the id
statement:
.bean(MyManagedBean.class, "doSomething").id("myManagedBean")
This will cause your code to show up in JMX using your provided ID:
org.apache.camel:context=localhost/camel-1,type=processors, name="myManagedBean"
18.118.24.106