1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-21 18:41:03 +00:00
Munin-Contrib/plugins/jvm/jstat__heap
Stefan Huehner f0548a37de Fix jstat* plugins to work again with java 6+7, fix PU reporting for
Java8.

jstat column output is not stable across JVM versions (technically
version of jstat binary used).
New columns are added not add the end of column list but in the middle
breaking access via constant index.

Following table shows the known columns per version:
Oracle JDK / OpenJDK 1.5 .. 1.7
   S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC    YGCT   FGC     FGCT    GCT
Openjdk 1.8 .. 10
   S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
Openjdk 11  .. 12
   S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     CGC    CGCT     GCT

Earlier commit here added support for java8+ but using version checking
if version == 1.5 > Use pre-java8 column format, else new format.

As fixing java6+7 would mean more version comparison which is ugly this
cmomit changes retrival logic to the following;
a.) Parse first line jstat output to find position for each label
b.) Then use that position to fetch value from 2nd line

That way code auto-adjusts to any ordering change without needing any
java version specific code or checks.

On the way fix 'Permanent Used' value reporting for java8 which was
broken (missing variable rename from PU -> MU when java8 support was
added).
2018-12-13 15:20:34 +01:00

169 lines
5.1 KiB
Bash
Executable file

#!/bin/sh
#
# Plugin for monitor JVM activity - Heap Usage -
#
# Usage:
#
# Symlink into /etc/munin/plugins/ and add the monitored
# alias name like :
#
# ln -s /usr/share/munin/plugins/jstat__heap \
# /etc/munin/plugins/jstat_<jvm alias>_heap
# This should, however, be given through autoconf and suggest.
#
# Requirements:
#
# You need to execute your Java program under jsvc provided by
# http://jakarta.apache.org/commons/daemon/
# which enables you to run your Java program with specified
# pid file with -pidfile option.
# A Brief setup documentation is also available at
# http://tomcat.apache.org/tomcat-5.5-doc/setup.html
#
# Target:
#
# Target Java Virtual Machine to monitor are:
# Sun JDK 5.0 (http://java.sun.com/javase/)
# Sun JDK 8.0 (http://java.sun.com/javase/)
# OpenJDK 1.7 .. 11 (https://openjdk.java.net/)
# BEA JRockit 5.0 (http://dev2dev.bea.com/jrockit/)
#
# Parameters:
#
# config (required)
#
# Config variables:
#
# pidfilepath - Which file path use. Defaults to '/var/run/jsvc.pid'
# javahome - override automatic detection of JRE directory
# graphtitle - Title of the graph (defaults to PID file location)
#
default_java_home=/usr/lib/jvm/default-java
[ -e "$default_java_home" ] || default_java_home=/usr/local/java/jdk
pidfilepath=${pidfilepath:-/var/run/jsvc.pid}
graphtitle=${graphtitle:-$pidfilepath}
JAVA_HOME=${javahome:-$default_java_home}
export JAVA_HOME
get_jdk_type() {
local version
if "${JAVA_HOME}/bin/java" -version 2>&1 | grep -qi 'jrockit'; then
echo "bea"
else
echo "sun"
fi
}
print_config() {
echo "graph_title Heap Usage $graphtitle"
echo "graph_args --base 1024 -l 0"
echo "graph_vlabel Heap Usage(Bytes)"
echo "graph_info Heap Usage"
echo "graph_category virtualization"
if [ "${JDK_TYPE}" = "bea" ]; then
echo "NurserySize.label NurserySize"
echo "HeapSize.label HeapSize"
echo "UsedHeapSize.label UsedHeapSize"
echo "NurserySize.draw AREA"
echo "HeapSize.draw STACK"
echo "UsedHeapSize.draw STACK"
else
echo "Eden_Used.label Eden_Used"
echo "Eden_Free.label Eden_Free"
echo "Survivor0_Used.label Survivor0_Used"
echo "Survivor0_Free.label Survivor0_Free"
echo "Survivor1_Used.label Survivor1_Used"
echo "Survivor1_Free.label Survivor1_Free"
echo "Old_Used.label Old_Used"
echo "Old_Free.label Old_Free"
echo "Permanent_Used.label Permanent_Used"
echo "Permanent_Free.label Permanent_Free"
echo "Eden_Used.draw AREA"
echo "Eden_Free.draw STACK"
echo "Survivor0_Used.draw STACK"
echo "Survivor0_Free.draw STACK"
echo "Survivor1_Used.draw STACK"
echo "Survivor1_Free.draw STACK"
echo "Old_Used.draw STACK"
echo "Old_Free.draw STACK"
echo "Permanent_Used.draw STACK"
echo "Permanent_Free.draw STACK"
fi
}
print_stats() {
local pid_num="$1"
local awk_script
if [ "${JDK_TYPE}" = "bea" ]; then
# shellcheck disable=SC2016
awk_script='{
HeapSize = $1;
NurserySize = $2;
UsedHeapSize = $3;
print "NurserySize.value " NurserySize * 1024;
print "HeapSize.value " HeapSize * 1024;
print "UsedHeapSize.value " UsedHeapSize * 1024; }'
else
# List & Order of columns of jstat changes with java versions
# idx["YGC"] is index of YGC column in output (i.e. 13)
# $idx["YGC"] then accesses the value at this position (taken from 2nd line of the output)
# shellcheck disable=SC2016
awk_script='
NR==1 {
for (i=1;i<=NF;i++) idx[$i]=i
}
NR==2 {
S0F = $idx["S0C"] - $idx["S0U"];
S1F = $idx["S1C"] - $idx["S1U"];
EF = $idx["EC"] - $idx["EU"];
OF = $idx["OC"] - $idx["OU"];
MF = $idx["MC"] - $idx["MU"];
print "Eden_Used.value " $idx["EU"] * 1024;
print "Eden_Free.value " EF * 1024;
print "Survivor0_Used.value " $idx["S0U"] * 1024;
print "Survivor0_Free.value " S0F * 1024;
print "Survivor1_Used.value " $idx["S1U"] * 1024;
print "Survivor1_Free.value " S1F * 1024;
print "Old_Used.value " $idx["OU"] * 1024;
print "Old_Free.value " OF * 1024;
print "Permanent_Used.value " $idx["MU"] * 1024;
print "Permanent_Free.value " MF * 1024;
}'
fi
"${JAVA_HOME}/bin/jstat" -gc "$pid_num" | awk "$awk_script"
}
#
# autoconf
#
if [ "$1" = "autoconf" ]; then
if [ ! -x "${JAVA_HOME}/bin/jstat" ]; then
echo "no (No jstat found in ${JAVA_HOME}/bin)"
elif [ ! -f "$pidfilepath" ]; then
echo "no (missing file $pidfilepath)"
elif [ ! -r "$pidfilepath" ]; then
echo "no (cannot read $pidfilepath)"
else
echo "yes"
fi
exit 0
fi
JDK_TYPE=$(get_jdk_type)
if [ "$1" = "config" ]; then
print_config
fi
print_stats "$(cat "$pidfilepath")"