1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-21 10:39:53 +00:00
Munin-Contrib/plugins/jvm/jstat__heap
Stefan Huehner 583560e57f Fix reporting of 'Permanent Generation' / Metaspace.
Fix regression in last commit. While it added auto-detection of changing
column position it did not take into account the known change from
Java 7 > 8.

Java <8 had the Permanent Generation region which jstat columns PU, PC
While Java >=8 now has a Metaspace region (for similar purpose) with
jstat columns MU,MC.

Add re-add detection for that change to fix reporting of the values.

To simplify code uses the MU,MC labels internally and when MU,MC are
not found in jstat output it fills those with PU,PC values.
2018-12-14 14:43:31 +01:00

174 lines
5.4 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"];
# Java <8 has Permanent Generation (PU,PC columns), while >=8 has/names it Metaspace (MU,MC)
if (idx["MU"] == "") {
idx["MU"] = idx["PU"];
idx["MC"] = idx["PC"];
}
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")"