Zabbix provides templates easy to setup which do not require any external scripts. As an example, you can check one of my previous blog post on the subject where I monitored a WildFly server. These one includes many items and several discovery rules, but one part is not covered by it: Java Virtual Machine.

One can argue that you can use the Generic Java JMX template, but unfortunately, it cannot be used as is for two reasons:

  • Item conflict between the two templates: jmx["java.lang:type=Runtime","Uptime"]
  • The requirement to enable an extra JMX interface

Conflict

If you try to link the Generic Java JMX template on a host already having WildFly Server by JMX, the following error will be raised:

Cannot inherit item with key "jmx["java.lang:type=Runtime","Uptime"]" of template "Generic Java JMX" to host "srv-linux-1", because an item with the same key is already inherited from template "WildFly Server by JMX".

Clone

Before doing any modification of the template, it is better to clone it and work on the clone.

First, open the template by going into Data collection, Templates and going into Generic Java JMX. From there, you will see the Full clone button. You can customize the name, tags, macros and value mapping. For me, I will name it Generic Java WildFly and click Add button.

Resolving the Conflict

To avoid the conflict, we should remove the key from one of the two template. In the cloned template, look for an item named “Runtime: JVM uptime” and remove it. Now, you should be able to link the cloned template to the host without error.

Good, but we are not done yet, I want to use the existing RMI protocol and not open a new RMI port.

JMX Endpoint

Each items and item prototypes has a JMS endpoint URL like that:

service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi

As you can see protocol (rmi:///jndi/rmi) is hard-coded, in other words “not using a macro”, as WildFly template does with macro {$WILDFLY.JMX.PROTOCOL}.

Let’s update that!

In the list of items, select all items and click Mass update button. Tick the JMX endpoint box and paste the following text:

service:jmx:{$WILDFLY.JMX.PROTOCOL}://{HOST.CONN}:{HOST.PORT}

We will update two other fields in the same occasion. Actually, Generic Java JMX template defines {$JMX.USER} and {$JMX.PASSWORD}. We don’t need them or, to be more precise, we can use the same macros as in WildFly template (ie. {$WILDFLY.USER} and {$WILDFLY.PASSWORD}).

Mass update windows look like that, now:

Finally, click Update button. Are we done? No, we have to do the same twice for the item prototype of the discover rules:

Another more brutal approach to this is to export file in YAML, replace strings in it and re-import it in Zabbix.

What Next?

While looking at the gathered data, I was not able to find any discovered items. To figure out what is happening, I ran a test on the Garbage collector discovery rule and received that data:

{
    "data": [{
            "{#JMXDOMAIN}": "java.lang",
            "{#JMXTYPE}": "GarbageCollector",
            "{#JMXOBJ}": "java.lang:name=G1 Young Generation,type=GarbageCollector",
            "{#JMXNAME}": "G1 Young Generation"
        }, {
            "{#JMXDOMAIN}": "java.lang",
            "{#JMXTYPE}": "GarbageCollector",
            "{#JMXOBJ}": "java.lang:name=G1 Old Generation,type=GarbageCollector",
            "{#JMXNAME}": "G1 Old Generation"
        }
    ]
}

It looks fine, but why Zabbix does not create the associated items? It does not expect to have the data encapsulated in a data array (line 2). The idea here is to add a preprocessing rule to remove that envelop:

And now, I can see the item created: