#!/usr/bin/perl -w # # Program: JVM statistics collector # # Author: Matty < matty91 @ gmail dot com > # # Current Version: 1.0 # # Last Updated: 10-29-2007 # # Purpose: # jvmstats-gather.pl retrieves performance metrics from the # Java SNMP agent, and writes these entries to a file. This # file can then be analyzed by ORCA to produce several # performance graphs. # # Notes; # To enable the Java SNMP agent, the following options can # be appended to the Java command line: # # $ java -Dcom.sun.management.snmp.interface=0.0.0.0 \ # -Dcom.sun.management.snmp.port=8161 \ # -Dcom.sun.management.snmp.acl=true \ # -Dcom.sun.management.snmp.acl.file=/usr/java/jre/lib/management/snmp.acl ... # # Additional documentation is available here: # JAVA MIB: http://java.sun.com/javase/6/docs/jre/api/management/JVM-MANAGEMENT-MIB.mib # Sun Java link: http://java.sun.com/j2se/1.5.0/docs/guide/management/SNMP.html # # License: # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2, or (at your option) any # later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # Installation: # Install Net::SNMP and copy the Perl script to a suitable location # # Example: # The following example will collect statistics from the JVM running on # port 8161 on server foo, and will write the collected data to the file # "home/matty/java/jvmstats/server1_myappjvm/javallator-2007-11-05": # # $ jvmstats.pl -s foo.prefetch.net -p 8161 -c public \ # -f /home/matty/java/jvmstats/server1_myappjvm/javallator-2007-11-05 # # Sample graphs: # Sample graphs are available here: http://prefetch.net/images/javallator # use SNMP; use Getopt::Std; # Get and parse the command line options %options=(); getopts("df:m:p:s:",\%options); # The location of the JVM management MIB. my $JVMMIB = defined($options{m}) ? $options{m} : "/etc/sma/snmp/mibs/JVM-MANAGEMENT-MIB.mib"; # Where to write the collected statistics. my $STATSFILE = defined($options{f}) ? $options{f} : ""; # Name or IP address of the JVM. my $SNMP_TARGET = defined($options{s}) ? $options{s} : "localhost"; # SNMP port to use. my $SNMP_PORT = defined($options{p}) ? $options{p} : 161; # Community string to pass to the SNMP server my $SNMP_COMMUNITY = defined($options{c}) ? $options{c} : "public"; # Dump OID values from server to STDOUT my $DEBUG = defined($options{d}) ? $options{d} : 0; # List of OIDS to retrieve from the SNMP server my @oids = ( "jvmRTUptimeMs.0", # Total time the JVM has been up "jvmJITCompilerTimeMs.0", # Time spent in the JIT compiler "jvmThreadTotalStartedCount.0", # Number of threads created "jvmThreadCount.0", # Number of live threads "jvmClassesTotalLoadedCount.0", # Number of classes loaded "jvmClassesUnloadedCount.0", # Number of classes unloaded "jvmMemGCCount.2", # New generation GC events "jvmMemGCCount.3", # old generation GC events "jvmMemGCTimeMs.2", # New generation GC time "jvmMemGCTimeMs.3", # Old generation GC time "jvmMemoryPendingFinalCount.0", # Objects pending finalization "jvmMemoryHeapCommitted.0", # Bytes committed to the heap "jvmMemoryHeapUsed.0", # Bytes used in the heap "jvmMemoryNonHeapCommitted.0", # Bytes committed to non-heap use "jvmMemoryNonHeapUsed.0"); # Bytes used in the non-heap # Headers associated with the OID values above my @headers = ( "TIMESTAMP", "JVMUPTIME", "JITTIME", "THREADSTOTAL", "THREADSACTIVE", "CLASSLOADS", "CLASSUNLOADS", "NGGCEVENTS", "OLDGCEVENTS", "NGGCTIME", "OLDGCTIME", "OBJECTFINALIZATION", "HEAPCOMMITTED", "HEAPUSED", "NONHEAPCOMMITTED", "NONHEAPUSED"); # If the statistics file exists, append the sample to it. If it doesn't # exist, then we need to create a new one. if ( -e $STATSFILE ) { open (STATS, ">>$STATSFILE") || die "ERROR: Couldn't open \"$STATSFILE\" : $!\n"; } else { open(STATS, ">$STATSFILE") || die "ERROR: Couldn't open \"$STATSFILE\" : $!\n"; foreach $header (@headers) { push(@headervalues, "$header"); } print STATS "@headervalues\n"; } # Load the Java management MIB if (( defined $JVMMIB ) && ( -e $JVMMIB)) { $ENV{'MIBS'}="$JVMMIB"; } else { print "Cannot find JVM management MIB\n"; } # Create a new SNMP session object ($SESSION, $error) = new SNMP::Session ( DestHost => ${SNMP_TARGET}, Community => ${SNMP_COMMUNITY}, RemotePort => ${SNMP_PORT}, Timeout => 10, Version => 2); if ($error) { die "Cannot create SNMP session : $!\n"; } # Write a timestamp to the array push(@oidvalues, time()); # Get the values for each OID in the array foreach $oid (@oids) { $value = &getvalue($oid); push(@oidvalues, $value); } print STATS "@oidvalues\n"; # Retrieve the value for a specific OID. sub getvalue() { # This should be an OID my $oid = shift; # Ping the server to get the object id my $result = $SESSION->get($oid) || 0; if ($DEBUG) { print "OID: $oid Value: $result\n"; } return $result; }