sensu-plugins-java 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/README.md +3 -0
- data/bin/check-java-heap-pcnt-java8.sh +104 -0
- data/bin/check-java-heap-pcnt.sh +35 -17
- data/bin/java-heap-pcnt.sh +6 -1
- data/bin/metrics-java-heap-graphite-java8.sh +68 -0
- data/bin/metrics-java-heap-graphite.sh +70 -35
- data/bin/metrics-jstat-java8.py +316 -0
- data/lib/sensu-plugins-java/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab00e78e1241adeeeb6695522213bede8f50ce69
|
4
|
+
data.tar.gz: 542d2d4ec7fae55dc6041576b35c4cd64eecdbee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bd326b76ba1d35b660760574812846e4a611c4069e8e512574ceefa3e243853109c1c9c40a78514bfa868abb8354f83c8659e01bcb0757c05961d2d13d5c5be
|
7
|
+
data.tar.gz: 92856fcddeb6796053fb6e4463b66a1564c331f85d0b7888d6bb8a2ded9357a771e7b0f6a3c0cc9b941d177e1a8011218d17c5212fe71a8892336b5d902d3daf
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,14 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
3
3
|
|
4
4
|
This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachangelog.com/)
|
5
5
|
|
6
|
+
## [Unreleased]
|
7
|
+
## [0.0.6] - 2017-06-09
|
8
|
+
### Changed
|
9
|
+
- refactor of check-java-heap-pcnt.sh, metrics-java-heap-graphite.sh made java version agnostic. jstat -gc returns 17 columns and has metaspace in java8. jstat -gc returns 15 columns and has permgen space in java 7, 6. These will work for both versions.
|
10
|
+
- run jstat only once for performance improvement
|
11
|
+
- Fix issue #11.
|
12
|
+
- java-heap-pcnt, check-java-heap-pcnt-java8, metrics-java-heap-graphite-java8 could be removed in a future release
|
13
|
+
|
6
14
|
## [0.0.5] - 2016-11-02
|
7
15
|
### Changed
|
8
16
|
- metrics-jstat.py: support added for py2.6 (RHEL/CentOS 6.x)
|
@@ -36,7 +44,8 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
|
|
36
44
|
### Added
|
37
45
|
- initial release
|
38
46
|
|
39
|
-
[Unreleased]: https://github.com/sensu-plugins/sensu-plugins-java/compare/0.0.
|
47
|
+
[Unreleased]: https://github.com/sensu-plugins/sensu-plugins-java/compare/0.0.6...HEAD
|
48
|
+
[0.0.6]: https://github.com/sensu-plugins/sensu-plugins-java/compare/0.0.4...0.0.6
|
40
49
|
[0.0.4]: https://github.com/sensu-plugins/sensu-plugins-java/compare/0.0.3...0.0.4
|
41
50
|
[0.0.3]: https://github.com/sensu-plugins/sensu-plugins-java/compare/0.0.2...0.0.3
|
42
51
|
[0.0.2]: https://github.com/sensu-plugins/sensu-plugins-java/compare/0.0.1...0.0.2
|
data/README.md
CHANGED
@@ -12,10 +12,13 @@
|
|
12
12
|
* bin/check-java-permgen.rb
|
13
13
|
* bin/java-heap-pcnt.sh - deprecated, use check-java-heap-pcnt
|
14
14
|
* bin/check-java-heap-pcnt.sh
|
15
|
+
* bin/check-java-heap-pcnt-java8.sh - supports java 8 and multiple java processes
|
15
16
|
* bin/check-java-heap-pcnt.rb - ruby wrapper for check-java-heap-pcnt.sh
|
16
17
|
* bin/metrics-java-heap-graphite.sh
|
18
|
+
* bin/metrics-java-heap-graphite-java8.sh - supports java 8 and multiple java processes
|
17
19
|
* metrics-java-heap-graphite.rb - ruby wrapper for metrics-java-heap-graphite.sh
|
18
20
|
* bin/metrics-jstat.py
|
21
|
+
* bin/metrics-jstat-java8.py - supports java 8
|
19
22
|
* bin/metrics-jstat.rb - ruby wrapper script for metrics-jstat.py
|
20
23
|
|
21
24
|
## Usage
|
@@ -0,0 +1,104 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
#
|
3
|
+
# Evaluate percentage of heap usage on specfic Tomcat backed JVM from Linux based systems based on percentage
|
4
|
+
# This was forked from Sensu Community Plugins
|
5
|
+
|
6
|
+
# Date: 2017-02-10
|
7
|
+
# Modified: Nikoletta Kyriakidou
|
8
|
+
|
9
|
+
# You must have openjdk-8-jdk and openjdk-8-jre packages installed
|
10
|
+
# http://openjdk.java.net/install/
|
11
|
+
#
|
12
|
+
# Also make sure the user "sensu" can sudo without password
|
13
|
+
|
14
|
+
# #RED
|
15
|
+
while getopts 'w:c:n:o:j:hp' OPT; do
|
16
|
+
case $OPT in
|
17
|
+
w) WARN=$OPTARG;;
|
18
|
+
c) CRIT=$OPTARG;;
|
19
|
+
n) NAME=$OPTARG;;
|
20
|
+
o) OPTIONS=$OPTARG;;
|
21
|
+
j) JAVA_BIN=$OPTARG;;
|
22
|
+
h) hlp="yes";;
|
23
|
+
p) perform="yes";;
|
24
|
+
*) unknown="yes";;
|
25
|
+
esac
|
26
|
+
done
|
27
|
+
|
28
|
+
# usage
|
29
|
+
HELP="
|
30
|
+
usage: $0 [ -n value -w value -c value -o value -p -h ]
|
31
|
+
|
32
|
+
-n --> Name of JVM process < value
|
33
|
+
-w --> Warning Percentage < value
|
34
|
+
-c --> Critical Percentage < value
|
35
|
+
-o --> options to pass to jps
|
36
|
+
-j --> path to java bin dir (include trailing /)
|
37
|
+
-p --> print out performance data
|
38
|
+
-h --> print this help screen
|
39
|
+
"
|
40
|
+
|
41
|
+
if [ "$hlp" = "yes" ]; then
|
42
|
+
echo "$HELP"
|
43
|
+
exit 0
|
44
|
+
fi
|
45
|
+
|
46
|
+
WARN=${WARN:=0}
|
47
|
+
CRIT=${CRIT:=0}
|
48
|
+
NAME=${NAME:=0}
|
49
|
+
JAVA_BIN=${JAVA_BIN:=""}
|
50
|
+
|
51
|
+
#Get PIDs of JVM.
|
52
|
+
#At this point grep for the names of the java processes running your jvm.
|
53
|
+
PIDS=$(sudo ${JAVA_BIN}jps $OPTIONS | grep " $NAME$" | awk '{ print $1}')
|
54
|
+
|
55
|
+
projectSize=$(printf "%s\n" $(printf "$PIDS" | wc -w))
|
56
|
+
|
57
|
+
i=0
|
58
|
+
for PID in $PIDS
|
59
|
+
do
|
60
|
+
#Get heap capacity of JVM
|
61
|
+
TotalHeap=$(sudo ${JAVA_BIN}jstat -gccapacity $PID | tail -n 1 | awk '{ print ($4 + $5 + $6 + $10) / 1024 }')
|
62
|
+
|
63
|
+
#Determine amount of used heap JVM is using
|
64
|
+
UsedHeap=$(sudo ${JAVA_BIN}jstat -gc $PID | tail -n 1 | awk '{ print ($3 + $4 + $6 + $8) / 1024 }')
|
65
|
+
|
66
|
+
#Get heap usage percentage
|
67
|
+
HeapPer=$(echo "scale=3; $UsedHeap / $TotalHeap * 100" | bc -l| cut -d "." -f1)
|
68
|
+
|
69
|
+
|
70
|
+
if [ "$HeapPer" = "" ]; then
|
71
|
+
echo "MEM UNKNOWN -"
|
72
|
+
codes[i]=3
|
73
|
+
fi
|
74
|
+
|
75
|
+
#For multiple projects running we need to print the name
|
76
|
+
if [ "$projectSize" -ne 1 ]; then
|
77
|
+
projectName=$(sudo jps | grep $PID | awk '{ print $2}' | cut -d. -f1)
|
78
|
+
project=$projectName
|
79
|
+
fi
|
80
|
+
|
81
|
+
if [ "$perform" = "yes" ]; then
|
82
|
+
output="$project jvm heap usage: $HeapPer% | heap usage="$HeapPer"%;$WARN;$CRIT;0"
|
83
|
+
else
|
84
|
+
output="$project jvm heap usage: $HeapPer% | $UsedHeap MB out of $TotalHeap MB"
|
85
|
+
fi
|
86
|
+
|
87
|
+
if (( $HeapPer >= $CRIT )); then
|
88
|
+
echo "MEM CRITICAL - $output"
|
89
|
+
codes[i]=2
|
90
|
+
elif (( $HeapPer >= $WARN )); then
|
91
|
+
echo "MEM WARNING - $output"
|
92
|
+
codes[i]=1
|
93
|
+
else
|
94
|
+
echo "MEM OK - $output"
|
95
|
+
codes[i]=0
|
96
|
+
fi
|
97
|
+
i+=1
|
98
|
+
done
|
99
|
+
|
100
|
+
if (($projectSize -ne $1 && ${codes[0]} != "0")); then
|
101
|
+
exit ${codes[1]}
|
102
|
+
else
|
103
|
+
exit ${codes[0]}
|
104
|
+
fi
|
data/bin/check-java-heap-pcnt.sh
CHANGED
@@ -6,12 +6,15 @@
|
|
6
6
|
# Date: 2013-9-30
|
7
7
|
# Modified: Mario Harvey - badmadrad.com
|
8
8
|
|
9
|
-
#
|
9
|
+
# Date: 2017-06-06
|
10
|
+
# Modified: Nic Scott - re-work to be java version agnostic
|
11
|
+
|
12
|
+
# depends on jps and jstat in openjdk-devel in openjdk-<VERSION>-jdk and
|
13
|
+
# openjdk-<VERSION>-jre packages being installed
|
10
14
|
# http://openjdk.java.net/install/
|
11
15
|
|
12
|
-
# Also make sure the user "sensu" can sudo without password
|
16
|
+
# Also make sure the user "sensu" can sudo jps and jstat without password
|
13
17
|
|
14
|
-
# #RED
|
15
18
|
while getopts 'w:c:n:o:j:hp' OPT; do
|
16
19
|
case $OPT in
|
17
20
|
w) WARN=$OPTARG;;
|
@@ -27,15 +30,14 @@ done
|
|
27
30
|
|
28
31
|
# usage
|
29
32
|
HELP="
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
-h --> print this help screen
|
33
|
+
usage: $0 [ -n value -w value -c value -o value -p -h ]
|
34
|
+
-n --> Name of JVM process < value
|
35
|
+
-w --> Warning Percentage < value
|
36
|
+
-c --> Critical Percentage < value
|
37
|
+
-o --> options to pass to jps
|
38
|
+
-j --> path to java bin dir (include trailing /)
|
39
|
+
-p --> print out performance data
|
40
|
+
-h --> print this help screen
|
39
41
|
"
|
40
42
|
|
41
43
|
if [ "$hlp" = "yes" ]; then
|
@@ -50,13 +52,29 @@ JAVA_BIN=${JAVA_BIN:=""}
|
|
50
52
|
|
51
53
|
#Get PID of JVM.
|
52
54
|
#At this point grep for the name of the java process running your jvm.
|
53
|
-
PID=$(sudo ${JAVA_BIN}jps $OPTIONS | grep $NAME | awk '{ print $1}')
|
55
|
+
PID=$(sudo ${JAVA_BIN}jps $OPTIONS | grep " $NAME$" | awk '{ print $1}')
|
56
|
+
COUNT=$(echo $PID | wc -w)
|
57
|
+
if [ $COUNT != 1 ]; then
|
58
|
+
echo "$COUNT java process(es) found with name $NAME"
|
59
|
+
exit 3
|
60
|
+
fi
|
54
61
|
|
55
|
-
|
56
|
-
TotalHeap=$(sudo ${JAVA_BIN}jstat -gccapacity $PID | tail -n 1 | awk '{ print ($4 + $5 + $6 + $10) / 1024 }')
|
62
|
+
JSTAT=$(sudo ${JAVA_BIN}jstat -gc $PID | tail -n 1)
|
57
63
|
|
58
|
-
#
|
59
|
-
|
64
|
+
# Java 8 jstat -gc returns 17 columns Java 7 returns 15
|
65
|
+
if [[ ${#JSTAT[@]} -gt 15 ]]; then
|
66
|
+
# Metaspace is not a part of heap in Java 8
|
67
|
+
#Get heap capacity of JVM
|
68
|
+
TotalHeap=$(echo $JSTAT | awk '{ print ($1 + $2 + $5 + $7) / 1024 }')
|
69
|
+
#Determine amount of used heap JVM is using
|
70
|
+
UsedHeap=$(echo $JSTAT | awk '{ print ($3 + $4 + $6 + $8) / 1024 }')
|
71
|
+
else
|
72
|
+
# PermGen is part of heap in Java <8
|
73
|
+
#Get heap capacity of JVM
|
74
|
+
TotalHeap=$(echo $JSTAT | awk '{ print ($1 + $2 + $5 + $7 + $9) / 1024 }')
|
75
|
+
#Determine amount of used heap JVM is using
|
76
|
+
UsedHeap=$(echo $JSTAT | awk '{ print ($3 + $4 + $6 + $8 + $10) / 1024 }')
|
77
|
+
fi
|
60
78
|
|
61
79
|
#Get heap usage percentage
|
62
80
|
HeapPer=$(echo "scale=3; $UsedHeap / $TotalHeap * 100" | bc -l| cut -d "." -f1)
|
data/bin/java-heap-pcnt.sh
CHANGED
@@ -45,7 +45,12 @@ NAME=${NAME:=0}
|
|
45
45
|
|
46
46
|
#Get PID of JVM.
|
47
47
|
#At this point grep for the name of the java process running your jvm.
|
48
|
-
PID=$(sudo jps | grep $NAME | awk '{ print $1}')
|
48
|
+
PID=$(sudo jps | grep " $NAME$" | awk '{ print $1}')
|
49
|
+
COUNT=$(echo $PID | wc -w)
|
50
|
+
if [ $COUNT != 1 ]; then
|
51
|
+
echo "$COUNT java process(es) found with name $NAME"
|
52
|
+
exit 3
|
53
|
+
fi
|
49
54
|
|
50
55
|
#Get heap capacity of JVM
|
51
56
|
TotalHeap=$(sudo jstat -gccapacity $PID | tail -n 1 | awk '{ print ($4 + $5 + $6 + $10) / 1024 }')
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
#
|
3
|
+
# Collect metrics on your JVM and allow you to trace usage in graphite
|
4
|
+
|
5
|
+
# Modified: Nikoletta Kyriakidou
|
6
|
+
|
7
|
+
# You must have openjdk-8-jdk and openjdk-8-jre packages installed
|
8
|
+
# http://openjdk.java.net/install/
|
9
|
+
|
10
|
+
# Also make sure the user "sensu" can sudo without password
|
11
|
+
|
12
|
+
# #RED
|
13
|
+
while getopts 's:n:h' OPT; do
|
14
|
+
case $OPT in
|
15
|
+
s) SCHEME=$OPTARG;;
|
16
|
+
n) NAME=$OPTARG;;
|
17
|
+
h) hlp="yes";;
|
18
|
+
esac
|
19
|
+
done
|
20
|
+
#usage
|
21
|
+
HELP="
|
22
|
+
usage $0 [ -n value -s value -h ]
|
23
|
+
-n --> NAME or name of jvm process < value
|
24
|
+
-s --> SCHEME or server name ex. :::name::: < value
|
25
|
+
-h --> print this help screen
|
26
|
+
"
|
27
|
+
if [ "$hlp" = "yes" ]; then
|
28
|
+
echo "$HELP"
|
29
|
+
exit 0
|
30
|
+
fi
|
31
|
+
|
32
|
+
SCHEME=${SCHEME:=0}
|
33
|
+
NAME=${NAME:=0}
|
34
|
+
|
35
|
+
#Get PIDs of JVM.
|
36
|
+
#At this point grep for the names of the java processes running your jvm.
|
37
|
+
PID=$(sudo jps | grep " $NAME$" | awk '{ print $1}')
|
38
|
+
for PID in $PIDS
|
39
|
+
do
|
40
|
+
#Get heap capacity of JVM
|
41
|
+
TotalHeap=$(sudo jstat -gccapacity $PID | tail -n 1 | awk '{ print ($4 + $5 + $6 + $10) / 1024 }')
|
42
|
+
|
43
|
+
#Determine amount of used heap JVM is using
|
44
|
+
UsedHeap=$(sudo jstat -gc $PID | tail -n 1 | awk '{ print ($3 + $4 + $6 + $8) / 1024 }')
|
45
|
+
|
46
|
+
#Determine Old Space Utilization
|
47
|
+
OldGen=$(sudo jstat -gc $PID | tail -n 1 | awk '{ print ($8) / 1024 }')
|
48
|
+
|
49
|
+
#Determine Eden Space Utilization
|
50
|
+
ParEden=$(sudo jstat -gc $PID | tail -n 1 | awk '{ print ($6) / 1024 }')
|
51
|
+
|
52
|
+
#Determine Survivor Space utilization
|
53
|
+
ParSurv=$(sudo jstat -gc $PID | tail -n 1 | awk '{ print ($3 + $4) / 1024 }')
|
54
|
+
|
55
|
+
#For multiple projects running we need to print the name
|
56
|
+
projectSize=$(printf "%s\n" $(printf "$PIDS" | wc -w))
|
57
|
+
|
58
|
+
if [ "$projectSize" -ne 1 ]; then
|
59
|
+
projectName=$(sudo jps | grep $PID | awk '{ print $2}' | cut -d. -f1)
|
60
|
+
project=$projectName
|
61
|
+
fi
|
62
|
+
|
63
|
+
echo "JVMs.$SCHEME.$project.Committed_Heap $TotalHeap `date '+%s'`"
|
64
|
+
echo "JVMs.$SCHEME.$project.Used_Heap $UsedHeap `date '+%s'`"
|
65
|
+
echo "JVMs.$SCHEME.$project.Eden_Util $ParEden `date '+%s'`"
|
66
|
+
echo "JVMs.$SCHEME.$project.Survivor_Util $ParSurv `date '+%s'`"
|
67
|
+
echo "JVMs.$SCHEME.$project.Old_Util $OldGen `date '+%s'`"
|
68
|
+
done
|
@@ -1,62 +1,97 @@
|
|
1
1
|
#!/usr/bin/env bash
|
2
2
|
#
|
3
|
-
# Collect metrics on your
|
3
|
+
# Collect metrics on your JVMs and allow you to trace usage in graphite
|
4
4
|
|
5
5
|
# Modified: Mario Harvey - badmadrad.com
|
6
6
|
|
7
|
-
#
|
7
|
+
# Date: 2017-06-06
|
8
|
+
# Modified: Nic Scott - re-work to be java version agnostic
|
9
|
+
|
10
|
+
# depends on jps and jstat in openjdk-devel in openjdk-<VERSION>-jdk and
|
11
|
+
# openjdk-<VERSION>-jre packages being installed
|
8
12
|
# http://openjdk.java.net/install/
|
9
13
|
|
10
|
-
# Also make sure the user "sensu" can sudo without password
|
14
|
+
# Also make sure the user "sensu" can sudo jps and jstat without password
|
11
15
|
|
12
|
-
# #RED
|
13
16
|
while getopts 's:n:h' OPT; do
|
14
|
-
case $OPT in
|
15
|
-
s) SCHEME=$OPTARG;;
|
16
|
-
n) NAME=$OPTARG;;
|
17
|
-
h) hlp="yes";;
|
18
|
-
esac
|
17
|
+
case $OPT in
|
18
|
+
s) SCHEME=$OPTARG;;
|
19
|
+
n) NAME=$OPTARG;;
|
20
|
+
h) hlp="yes";;
|
21
|
+
esac
|
19
22
|
done
|
23
|
+
|
20
24
|
#usage
|
21
25
|
HELP="
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
usage $0 [ -n value -s value -h ]
|
27
|
+
-n --> NAME or name of jvm process < value
|
28
|
+
-s --> SCHEME or server name ex. :::name::: < value
|
29
|
+
-h --> print this help screen
|
26
30
|
"
|
27
31
|
if [ "$hlp" = "yes" ]; then
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
echo "$HELP"
|
33
|
+
exit 0
|
34
|
+
fi
|
31
35
|
|
32
36
|
SCHEME=${SCHEME:=0}
|
33
37
|
NAME=${NAME:=0}
|
38
|
+
JAVA_BIN=${JAVA_BIN:=""}
|
34
39
|
|
35
40
|
#Get PID of JVM.
|
36
41
|
#At this point grep for the name of the java process running your jvm.
|
37
|
-
|
42
|
+
PIDS=$(sudo ${JAVA_BIN}jps $OPTIONS | grep " $NAME$" | awk '{ print $1 }')
|
43
|
+
COUNT=$(echo $PID | wc -w)
|
44
|
+
for PID in $PIDS
|
45
|
+
do
|
46
|
+
|
47
|
+
project=$(sudo jps | grep $PID | awk '{ print $2 }' | cut -d. -f1)
|
38
48
|
|
39
|
-
|
40
|
-
TotalHeap=$(sudo jstat -gccapacity $PID | tail -n 1 | awk '{ print ($4 + $5 + $6 + $10) / 1024 }')
|
49
|
+
JSTAT=$(sudo ${JAVA_BIN}jstat -gc $PID | tail -n 1)
|
41
50
|
|
42
|
-
#
|
43
|
-
|
51
|
+
# Java version indifferent memory stats
|
52
|
+
#Determine Old Space Utilization
|
53
|
+
OldGen=$(echo $JSTAT | awk '{ print ($8) / 1024 }')
|
44
54
|
|
45
|
-
#Determine
|
46
|
-
|
55
|
+
#Determine Eden Space Utilization
|
56
|
+
ParEden=$(echo $JSTAT | awk '{ print ($6) / 1024 }')
|
47
57
|
|
48
|
-
#Determine
|
49
|
-
|
58
|
+
#Determine Survivor Space utilization
|
59
|
+
ParSurv=$(echo $JSTAT | awk '{ print ($3 + $4) / 1024 }')
|
50
60
|
|
51
|
-
#
|
52
|
-
|
61
|
+
# Java version-specific memory stats
|
62
|
+
# Java 8 jstat -gc returns 17 columns Java 7 returns 15
|
63
|
+
if [[ ${#JSTAT[@]} -gt 15 ]]; then
|
64
|
+
# Metaspace is NOT a part of heap in Java 8
|
65
|
+
#Get heap capacity of JVM
|
66
|
+
TotalHeap=$(echo $JSTAT | awk '{ print ($1 + $2 + $5 + $7) / 1024 }')
|
67
|
+
#Determine amount of used heap JVM is using
|
68
|
+
UsedHeap=$(echo $JSTAT | awk '{ print ($3 + $4 + $6 + $8) / 1024 }')
|
69
|
+
#Get MetaSpace capacity of JVM
|
70
|
+
TotalMeta=$(echo $JSTAT | awk '{ print ($9) / 1024 }')
|
71
|
+
#Determine Meta Space Utilization
|
72
|
+
UsedMeta=$(echo $JSTAT | awk '{ print ($10) / 1024 }')
|
53
73
|
|
54
|
-
|
55
|
-
|
74
|
+
echo "JVMs.$SCHEME.$project.Meta_Capacity $TotalMeta `date '+%s'`"
|
75
|
+
echo "JVMs.$SCHEME.$project.Meta_Util $UsedMeta `date '+%s'`"
|
56
76
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
echo
|
61
|
-
|
62
|
-
echo
|
77
|
+
else
|
78
|
+
# PermGen IS part of heap in Java <8
|
79
|
+
#Get heap capacity of JVM
|
80
|
+
TotalHeap=$(echo $JSTAT | awk '{ print ($1 + $2 + $5 + $7 + $9) / 1024 }')
|
81
|
+
#Determine amount of used heap JVM is using
|
82
|
+
UsedHeap=$(echo $JSTAT | awk '{ print ($3 + $4 + $6 + $8 + $10) / 1024 }')
|
83
|
+
#Get PermGen capacity of JVM
|
84
|
+
TotalPerm=$(echo $JSTAT | awk '{ print ($9) / 1024 }')
|
85
|
+
#Determine PermGen Space Utilization
|
86
|
+
UsedPerm=$(echo $JSTAT | awk '{ print ($10) / 1024 }')
|
87
|
+
|
88
|
+
echo "JVMs.$SCHEME.$project.Perm_Capacity $TotalPerm `date '+%s'`"
|
89
|
+
echo "JVMs.$SCHEME.$project.Perm_Util $UsedPerm `date '+%s'`"
|
90
|
+
fi
|
91
|
+
echo "JVMs.$SCHEME.$project.Committed_Heap $TotalHeap `date '+%s'`"
|
92
|
+
echo "JVMs.$SCHEME.$project.Heap_Util $UsedHeap `date '+%s'`"
|
93
|
+
echo "JVMs.$SCHEME.$project.Eden_Util $ParEden `date '+%s'`"
|
94
|
+
echo "JVMs.$SCHEME.$project.Survivor_Util $ParSurv `date '+%s'`"
|
95
|
+
echo "JVMs.$SCHEME.$project.Old_Util $OldGen `date '+%s'`"
|
96
|
+
|
97
|
+
done
|
@@ -0,0 +1,316 @@
|
|
1
|
+
#!/usr/bin/python -tt
|
2
|
+
#
|
3
|
+
# DESCRIPTION:
|
4
|
+
# Collect everything that can be collected out of jstat (shells out 5 times)
|
5
|
+
# and spits to STDOUT in a graphite ready format, thus meant to be used with a
|
6
|
+
# graphite metric tcp handler.
|
7
|
+
# Since it shells out to jps(1) you will need the user running the sensu client
|
8
|
+
# executing this script to be able to run jps as the same user running the JVM
|
9
|
+
# you are trying to get stats from.
|
10
|
+
# In addition it will also need to be able to run jstat(2) against the JVM
|
11
|
+
# This can be all achieved by allowing the script to be ran as the same user
|
12
|
+
# running the JVM, for instance by prepending "sudo -u <jvm_process_owner>"
|
13
|
+
# in the command check definition (with the proper sudoers config to allow this
|
14
|
+
# with no password being asked)
|
15
|
+
#
|
16
|
+
# The graphite node is composed of an optional root node (defaults to 'metrics')
|
17
|
+
# the specified FQDN "reversed" ('foo.bar.com' becomes 'com.bar.foo') and an
|
18
|
+
# optional scheme (defaults to 'jstat')
|
19
|
+
#
|
20
|
+
# (1) http://docs.oracle.com/javase/8/docs/technotes/tools/share/jps.html
|
21
|
+
# (2) http://docs.oracle.com/javase/8/docs/technotes/tools/share/jstat.html
|
22
|
+
#
|
23
|
+
# OUTPUT:
|
24
|
+
# Graphite plain-text format (name value timestamp\n)
|
25
|
+
#
|
26
|
+
# DEPENDENCIES:
|
27
|
+
# Python 2.7 (untested on python 3 but should work fine)
|
28
|
+
# Java 8
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
32
|
+
# for details.
|
33
|
+
|
34
|
+
# #RED
|
35
|
+
import logging
|
36
|
+
import logging.handlers
|
37
|
+
import optparse
|
38
|
+
import sys
|
39
|
+
import time
|
40
|
+
|
41
|
+
"""
|
42
|
+
Python 2.6 support for check_output:
|
43
|
+
http://stackoverflow.com/questions/4814970/subprocess-check-output-doesnt-seem-to-exist-python-2-6-5
|
44
|
+
"""
|
45
|
+
try:
|
46
|
+
from subprocess import STDOUT, check_output, CalledProcessError
|
47
|
+
except ImportError: # pragma: no cover
|
48
|
+
# python 2.6 doesn't include check_output
|
49
|
+
# monkey patch it in!
|
50
|
+
import subprocess
|
51
|
+
STDOUT = subprocess.STDOUT
|
52
|
+
|
53
|
+
def check_output(*popenargs, **kwargs):
|
54
|
+
if 'stdout' in kwargs: # pragma: no cover
|
55
|
+
raise ValueError('stdout argument not allowed, '
|
56
|
+
'it will be overridden.')
|
57
|
+
process = subprocess.Popen(stdout=subprocess.PIPE,
|
58
|
+
*popenargs, **kwargs)
|
59
|
+
output, _ = process.communicate()
|
60
|
+
retcode = process.poll()
|
61
|
+
if retcode:
|
62
|
+
cmd = kwargs.get("args")
|
63
|
+
if cmd is None:
|
64
|
+
cmd = popenargs[0]
|
65
|
+
raise subprocess.CalledProcessError(retcode, cmd,
|
66
|
+
output=output)
|
67
|
+
return output
|
68
|
+
subprocess.check_output = check_output
|
69
|
+
|
70
|
+
# overwrite CalledProcessError due to `output`
|
71
|
+
# keyword not being available (in 2.6)
|
72
|
+
class CalledProcessError(Exception):
|
73
|
+
|
74
|
+
def __init__(self, returncode, cmd, output=None):
|
75
|
+
self.returncode = returncode
|
76
|
+
self.cmd = cmd
|
77
|
+
self.output = output
|
78
|
+
|
79
|
+
def __str__(self):
|
80
|
+
return "Command '%s' returned non-zero exit status %d" % (
|
81
|
+
self.cmd, self.returncode)
|
82
|
+
subprocess.CalledProcessError = CalledProcessError
|
83
|
+
|
84
|
+
class JstatMetricsToGraphiteFormat(object):
|
85
|
+
'''Prints jstat metrics to stdout in graphite format
|
86
|
+
|
87
|
+
Shells out to run jstat using the JVM id found via jps (also shelled out) and
|
88
|
+
passed argument to print to STDOUT (for use with sensu) the metrics value.
|
89
|
+
Jstat column titles are replaced with more explanatory names. Requires to be
|
90
|
+
ran as a user that can get the JVM id via jps and run jstat on that JVM'''
|
91
|
+
|
92
|
+
def main(self):
|
93
|
+
# Setting up logging to syslog
|
94
|
+
try:
|
95
|
+
logger = logging.getLogger(__name__)
|
96
|
+
logger.setLevel(logging.DEBUG)
|
97
|
+
|
98
|
+
formatter = logging.Formatter("%(pathname)s: %(message)s")
|
99
|
+
|
100
|
+
handler = logging.handlers.SysLogHandler(address = '/dev/log')
|
101
|
+
handler.setFormatter(formatter)
|
102
|
+
logger.addHandler(handler)
|
103
|
+
except Exception:
|
104
|
+
# booting is more important than logging
|
105
|
+
logging.critical("Failed to configure syslog handler")
|
106
|
+
|
107
|
+
parser = optparse.OptionParser()
|
108
|
+
|
109
|
+
parser.add_option('-g', '--graphite-base',
|
110
|
+
default = 'metrics',
|
111
|
+
dest = 'graphite_base',
|
112
|
+
help = 'The base graphite node',
|
113
|
+
metavar = 'NODE')
|
114
|
+
|
115
|
+
parser.add_option('-D', '--debug',
|
116
|
+
action = 'store_true',
|
117
|
+
default = False,
|
118
|
+
dest = 'debug',
|
119
|
+
help = 'Debug output (NOISY!)')
|
120
|
+
|
121
|
+
parser.add_option('-H', '--host',
|
122
|
+
default = None,
|
123
|
+
dest = 'hostname',
|
124
|
+
help = 'The name of the host to run jstat on',
|
125
|
+
metavar = 'HOST')
|
126
|
+
|
127
|
+
parser.add_option('-j', '--java-name',
|
128
|
+
default = None,
|
129
|
+
dest = 'java_app_name',
|
130
|
+
help = 'The name of the Java app to call jstat on',
|
131
|
+
metavar = 'JAVANAME')
|
132
|
+
|
133
|
+
parser.add_option('-s', '--scheme',
|
134
|
+
default = 'jstat',
|
135
|
+
dest = 'service',
|
136
|
+
help = 'Metric naming scheme, text to prepend to metric',
|
137
|
+
metavar = 'SERVICE')
|
138
|
+
|
139
|
+
(options, args) = parser.parse_args()
|
140
|
+
|
141
|
+
if not options.java_app_name:
|
142
|
+
parser.error('A Java app name is required')
|
143
|
+
|
144
|
+
if not options.hostname:
|
145
|
+
parser.error('A host name is required')
|
146
|
+
|
147
|
+
# Replace jstat colums titles with more explicit ones
|
148
|
+
# Stats coming from -gc
|
149
|
+
metric_maps_gc = { "S0U": "survivor_space_0_utilization_KB",
|
150
|
+
"S1U": "survivor_space_1_utilization_KB",
|
151
|
+
"EC": "current_eden_space_capacity_KB",
|
152
|
+
"EU": "eden_space_utilization_KB",
|
153
|
+
"OC": "current_old_space_capacity_KB",
|
154
|
+
"OU": "old_space_utilization_KB",
|
155
|
+
"MC": "metaspace_capacity_KB",
|
156
|
+
"MU": "metacspace_utilization_KB",
|
157
|
+
"CCSC": "compressed_class_space_capacity_KB",
|
158
|
+
"CCSU": "compressed_class_space_used_KB",
|
159
|
+
"YGC": "number_of_young_generation_GC_events",
|
160
|
+
"YGCT": "young_generation_garbage_collection_time",
|
161
|
+
"FGC": "number_of_stop_the_world_events",
|
162
|
+
"FGCT": "full_garbage_collection_time",
|
163
|
+
"GCT": "total_garbage_collection_time"
|
164
|
+
}
|
165
|
+
# Stats coming from -gccapacity
|
166
|
+
metric_maps_gccapacity = { "NGCMN": "minimum_size_of_new_area",
|
167
|
+
"NGCMX": "maximum_size_of_new_area",
|
168
|
+
"NGC": "current_size_of_new_area",
|
169
|
+
"OGCMN": "minimum_size_of_old_area",
|
170
|
+
"OGCMX": "maximum_size_of_old_area",
|
171
|
+
"OGC": "current_size_of_old_area",
|
172
|
+
"MCMN": "minimum_metaspace_capacity",
|
173
|
+
"MCMX": "maximum_metaspace_capacity",
|
174
|
+
"MC": "metaspace_capacity",
|
175
|
+
"CCSMN": "compressed_class_space_minimum_capacity",
|
176
|
+
"CCSMX": "compressed_class_space_maximum_capacity",
|
177
|
+
"CCSC": "compressed_class_space_capacity"
|
178
|
+
}
|
179
|
+
|
180
|
+
# Stats coming from -gcnew
|
181
|
+
metric_maps_gcnew = { "TT" : "tenuring_threshold",
|
182
|
+
"MTT": "maximum_tenuring_threshold",
|
183
|
+
"DSS": "adequate_size_of_survivor"
|
184
|
+
}
|
185
|
+
|
186
|
+
# Stats coming from -compiler
|
187
|
+
metric_maps_compiler = {
|
188
|
+
"Compiled": "compilation_tasks_performed",
|
189
|
+
"Failed": "compilation_tasks_failed",
|
190
|
+
"Invalid": "compilation_tasks_invalidated",
|
191
|
+
"Time": "time_spent_on_compilation_tasks"
|
192
|
+
}
|
193
|
+
|
194
|
+
# Stats coming from -class
|
195
|
+
## Note that since "Bytes" appears twice in jstat -class output we need
|
196
|
+
## to differentiate them by colum number
|
197
|
+
metric_maps_class = {
|
198
|
+
"Loaded": "loaded_classes",
|
199
|
+
"Bytes_column2": "loaded_KB",
|
200
|
+
"Unloaded": "unloaded_classes",
|
201
|
+
"Bytes_column4": "unloaded_KB",
|
202
|
+
"Time": "time_spent_on_class_load_unload"
|
203
|
+
}
|
204
|
+
|
205
|
+
def get_jstat_metrics(jstat_option, lvmid, metric_maps):
|
206
|
+
'''Runs jstat with provided option on provided host, returns mapped stats'''
|
207
|
+
def is_number(s):
|
208
|
+
'''returns true if string is a number'''
|
209
|
+
try:
|
210
|
+
float(s)
|
211
|
+
return True
|
212
|
+
except ValueError:
|
213
|
+
pass
|
214
|
+
try:
|
215
|
+
import unicodedata
|
216
|
+
unicodedata.numeric(s)
|
217
|
+
return True
|
218
|
+
except (TypeError, ValueError):
|
219
|
+
pass
|
220
|
+
return False
|
221
|
+
|
222
|
+
# Get stats from jstat stdout
|
223
|
+
try :
|
224
|
+
jstat_gc_out = check_output(["jstat", jstat_option, lvmid])
|
225
|
+
except Exception as e:
|
226
|
+
if options.debug:
|
227
|
+
print e
|
228
|
+
sys.exit(1)
|
229
|
+
logger.critical(e)
|
230
|
+
sys.exit(1)
|
231
|
+
|
232
|
+
values_all = jstat_gc_out.split("\n")[1].split()
|
233
|
+
# Remove non number strings
|
234
|
+
values = [ jstat_val for jstat_val in values_all if is_number(jstat_val) ]
|
235
|
+
# Transform float strings to integers
|
236
|
+
values = map(int, map(float, values))
|
237
|
+
|
238
|
+
# Change stats titles to long names
|
239
|
+
titles = jstat_gc_out.split("\n")[0].split()
|
240
|
+
# Deal with -class special "double Bytes" output
|
241
|
+
if jstat_option == "-class":
|
242
|
+
titles[2] = "Bytes_column2"
|
243
|
+
titles[4] = "Bytes_column4"
|
244
|
+
return dict([(metric_maps[title], values[position]) for position, title in enumerate(titles) if title in metric_maps])
|
245
|
+
|
246
|
+
# Get lvmid (JVM id)
|
247
|
+
try :
|
248
|
+
jps_out = check_output(["jps", "-v"])
|
249
|
+
except Exception as e:
|
250
|
+
if options.debug:
|
251
|
+
print e
|
252
|
+
sys.exit(1)
|
253
|
+
logger.critical(e)
|
254
|
+
sys.exit(1)
|
255
|
+
|
256
|
+
lvmid = False
|
257
|
+
for line in jps_out.split("\n"):
|
258
|
+
if options.java_app_name in line:
|
259
|
+
lvmid = line.split()[0]
|
260
|
+
|
261
|
+
if not lvmid:
|
262
|
+
if options.debug:
|
263
|
+
print "Could not get an LVM id"
|
264
|
+
sys.exit(1)
|
265
|
+
logger.critical("Could not get an LVM id")
|
266
|
+
sys.exit(1)
|
267
|
+
|
268
|
+
# Get stats from -gc
|
269
|
+
gc_stats = get_jstat_metrics("-gc", lvmid, metric_maps_gc)
|
270
|
+
if options.debug:
|
271
|
+
print gc_stats
|
272
|
+
# Get stats from -gccapacity
|
273
|
+
gccapacity_stats = get_jstat_metrics("-gccapacity",
|
274
|
+
lvmid, metric_maps_gccapacity)
|
275
|
+
if options.debug:
|
276
|
+
print gccapacity_stats
|
277
|
+
# Get stats from -gcnew
|
278
|
+
gcnew_stats = get_jstat_metrics("-gcnew", lvmid, metric_maps_gcnew)
|
279
|
+
if options.debug:
|
280
|
+
print gccapacity_stats
|
281
|
+
|
282
|
+
# Put all GC related stats to the same dict
|
283
|
+
gc_stats.update(gccapacity_stats)
|
284
|
+
gc_stats.update(gcnew_stats)
|
285
|
+
|
286
|
+
# Get stats from -compiler
|
287
|
+
compiler_stats = get_jstat_metrics("-compiler", lvmid, metric_maps_compiler)
|
288
|
+
if options.debug:
|
289
|
+
print compiler_stats
|
290
|
+
|
291
|
+
# Get stats from -class
|
292
|
+
class_stats = get_jstat_metrics("-class", lvmid, metric_maps_class)
|
293
|
+
if options.debug:
|
294
|
+
print class_stats
|
295
|
+
|
296
|
+
# Print to stdout in graphite format
|
297
|
+
now = time.time()
|
298
|
+
graphite_base = '.'.join([options.graphite_base,
|
299
|
+
'.'.join(reversed(options.hostname.split('.')))])
|
300
|
+
|
301
|
+
for metric in gc_stats:
|
302
|
+
print "%s.%s.jvm.gc.%s %s %d" % (graphite_base, options.service, metric,
|
303
|
+
gc_stats[metric], now)
|
304
|
+
|
305
|
+
for metric in compiler_stats:
|
306
|
+
print "%s.%s.jvm.compiler.%s %s %d" % (graphite_base, options.service,
|
307
|
+
metric, compiler_stats[metric], now)
|
308
|
+
|
309
|
+
for metric in class_stats:
|
310
|
+
print "%s.%s.jvm.class.%s %s %d" % (graphite_base, options.service,
|
311
|
+
metric, class_stats[metric], now)
|
312
|
+
|
313
|
+
sys.exit(0)
|
314
|
+
|
315
|
+
if '__main__' == __name__:
|
316
|
+
JstatMetricsToGraphiteFormat().main()
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu-plugins-java
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sensu-Plugins and contributors
|
@@ -177,12 +177,15 @@ files:
|
|
177
177
|
- CHANGELOG.md
|
178
178
|
- LICENSE
|
179
179
|
- README.md
|
180
|
+
- bin/check-java-heap-pcnt-java8.sh
|
180
181
|
- bin/check-java-heap-pcnt.rb
|
181
182
|
- bin/check-java-heap-pcnt.sh
|
182
183
|
- bin/check-java-permgen.rb
|
183
184
|
- bin/java-heap-pcnt.sh
|
185
|
+
- bin/metrics-java-heap-graphite-java8.sh
|
184
186
|
- bin/metrics-java-heap-graphite.rb
|
185
187
|
- bin/metrics-java-heap-graphite.sh
|
188
|
+
- bin/metrics-jstat-java8.py
|
186
189
|
- bin/metrics-jstat.py
|
187
190
|
- bin/metrics-jstat.rb
|
188
191
|
- lib/sensu-plugins-java.rb
|