Monitor Java with SNMP

As of Java 1.5, there is native SNMP support built in to the JVM. To enable it, there are three Java flags that need to be set. For Tomcat, these should go in the CATALINA_OPTS variable.

  1. -Dcom.sun.management.snmp.port=snmp-port

    Assuming you are not running your JVM as root (you're not, right? RIGHT?!?), snmp-port must be higher than 1024 on a Unix-based system. 9161, for example.

  2. -Dcom.sun.management.snmp.acl.file=path-to-snmp.acl-file

    This should be the path to your snmp.acl file (more about this later). For tomcat installs in /usr/local/tomcat, I like to put this at /usr/local/tomcat/conf/snmp.acl (or $CATALINA_HOME/conf/snmp.acl).

  3. -Dcom.sun.management.snmp.interface=0.0.0.0

    This allows connections to any interface. If this is not specified, it defaults to localhost. However, since we want to query this from a remote Zabbix server, we need to open it up. We will rely on the snmp.acl file (along with any firewall rules) to provide permissions.

The snmp.acl file should contain something like the following:

acl = {
  {
    communities = public
    access = read-only
    managers = 10.10.10.10
  }
}

The SNMP service is version 2c, which does not really provide any security, so you should really use something other than "public" for the community string. Something long and cryptic like "ouph2Ahtkiqu6Eejle7Aw9eloD6nohmi" would be a much better choice, but "public" lends itself better to this example. managers is a list of hosts that are allowed to access this SNMP resource. This can be host names, IP addresses, or CIDR blocks. 10.10.10.10 here is the IP address of our Zabbix server.

The permissions of the snmp.acl file MUST be such that the owner of the file is the same user that is running the Java process, and MUST be such that only this user has read access to it. Assuming your Java user is "tomcat", the permissions should look something like this:

-rw------- 1 tomcat tomcat 3.5K Aug 25 16:58 snmp.acl

If these permissions are not right, the JVM will fail to start.

Now that you have a working SNMP service, you can query it using snmpwalk (or your SNMP tool of choice). But, before you do that, you should download the JVM-MANAGEMENT-MIB.mib file and put it in your SNMP mibs directory (typically /usr/share/snmp/mibs). Then, do an snmpwalk like so

snmpwalk -m JVM-MANAGEMENT-MIB -v 2c -c public 10.10.10.11:9161 .

10.10.10.11 here is the server hosting the JVM, and don't forget the trailing ".". This will give you a nice list of everything you can query, and track. Below are the items I like to monitor. There is a lot more detail available, specifically regarding the different memory pools in the heap and non-heap memory. However, I find that these values give a well rounded high level view of what is going on.

Description OID Index Numeric OID
Daemon Thread Count JVM-MANAGEMENT-MIB::jvmThreadDaemonCount.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.3.2.0
Heap Memory Committed JVM-MANAGEMENT-MIB::jvmMemoryHeapCommitted.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.2.12.0
Heap Memory Initial Size JVM-MANAGEMENT-MIB::jvmMemoryHeapInitSize.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.2.10.0
Heap Memory Maximum Size JVM-MANAGEMENT-MIB::jvmMemoryHeapMaxSize.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.2.13.0
Heap Memory Used JVM-MANAGEMENT-MIB::jvmMemoryHeapUsed.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.2.11.0
Loaded Classes JVM-MANAGEMENT-MIB::jvmClassesLoadedCount.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.1.1.0
Non-Heap Memory Committed JVM-MANAGEMENT-MIB::jvmMemoryNonHeapCommitted.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.2.22.0
Non-Heap Memory Initial Size JVM-MANAGEMENT-MIB::jvmMemoryNonHeapInitSize.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.2.20.0
Non-Heap Memory Maximum Size JVM-MANAGEMENT-MIB::jvmMemoryNonHeapMaxSize.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.2.23.0
Non-Heap Memory Used JVM-MANAGEMENT-MIB::jvmMemoryNonHeapUsed.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.2.21.0
Objects Pending Finalization JVM-MANAGEMENT-MIB::jvmMemoryPendingFinalCount.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.2.1.0
Thread Count JVM-MANAGEMENT-MIB::jvmThreadCount.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.3.1.0
Uptime JVM-MANAGEMENT-MIB::jvmRTUptimeMs.0 .1.3.6.1.4.1.42.2.145.3.163.1.1.4.11.0

Other Resources