root / plugins / jvm / jvm_sun_memory @ 17f78427
Historique | Voir | Annoter | Télécharger (5,68 ko)
| 1 |
#!/usr/bin/perl -w |
|---|---|
| 2 |
|
| 3 |
# Sun JVM memory statistics. Parses a verbose log of minor GC and |
| 4 |
# tenured GC stats. |
| 5 |
|
| 6 |
# To determine the totalheap value it looks for maxmem stats (from a |
| 7 |
# tenured gc) in the last 5 minutes of the log file. If there are no |
| 8 |
# log lines in the last 5 minutes the value will be U(ndefined). |
| 9 |
|
| 10 |
# Since the log lines are timestamped with seconds since the JVM |
| 11 |
# started we look at the last line of the log to determine when "now" |
| 12 |
# is for the JVM. In a reasonably active JVM there will be several |
| 13 |
# minor GCs a minute so the "now" approximation based on these log |
| 14 |
# lines are close enough. |
| 15 |
|
| 16 |
# Configuration (common with the other sun_jvm_* plugins in this family): |
| 17 |
# [jvm_sun_*] |
| 18 |
# env.logfile /var/foo/java.log (default: /var/log/app/jvm/gc.log) |
| 19 |
# env.graphtitle (default: "Sun Java") |
| 20 |
|
| 21 |
# You need to configure your Sun JVM with these options: |
| 22 |
# -verbose:gc |
| 23 |
# -Xloggc:/var/log/app/jvm/gc.log |
| 24 |
# -XX:+PrintGCTimeStamps |
| 25 |
# -XX:+PrintGCDetails |
| 26 |
|
| 27 |
# History: |
| 28 |
|
| 29 |
# This plugin was developed by various people over some time - no logs |
| 30 |
# of this has been found. - In 2006 significant contributions was |
| 31 |
# financed by NRK (Norwegian Broadcasting Coproration) and performed |
| 32 |
# by Nicolai Langfeldt of Linpro AS in Oslo, Norway. |
| 33 |
|
| 34 |
# $Id: $ |
| 35 |
|
| 36 |
use strict; |
| 37 |
use warnings; |
| 38 |
use Fcntl qw(:seek); |
| 39 |
|
| 40 |
# Full path to jvm log file |
| 41 |
my $logfile = $ENV{logfile} || "/var/log/app/jvm/gc.log";
|
| 42 |
my $grtitle = $ENV{graphtitle} || "Sun Java";
|
| 43 |
|
| 44 |
# Title that appears on munin graph |
| 45 |
my $title = "$grtitle memory usage"; |
| 46 |
# Extended information that appears below munin graph |
| 47 |
my $info = "Write som info about this graph..."; |
| 48 |
|
| 49 |
sub analyze_record {
|
| 50 |
# Match all interesting elements of a record and insert them |
| 51 |
# into a hash |
| 52 |
|
| 53 |
my $record = shift; |
| 54 |
my %elements; |
| 55 |
|
| 56 |
if ( $record =~ |
| 57 |
m/(\d+\.\d+).+?(\d+\.\d+).+?DefNew: (\d+).+?(\d+).+?(\d+).+?(\d+\.\d+).+?(\d+\.\d+): \[Tenured(\[U.+\])*: (\d+).+?(\d+).+?(\d+).+?(\d+\.\d+).+?(\d+).+?(\d+).+?(\d+).+?(\d+\.\d+).+/ |
| 58 |
) {
|
| 59 |
%elements = ( |
| 60 |
total_timestamp => $1, |
| 61 |
defnew_timestamp => $2, |
| 62 |
defnew_mem_from => $3*1024, |
| 63 |
defnew_mem_to => $4*1024, |
| 64 |
defnew_mem_max => $5*1024, |
| 65 |
defnew_time_used => $6, |
| 66 |
tenured_timestamp => $7, |
| 67 |
tenured_mem_from => $9*1024, |
| 68 |
tenured_mem_to => $10*1024, |
| 69 |
tenured_mem_max => $11*1024, |
| 70 |
tenured_time_used => $12, |
| 71 |
total_mem_from => $13*1024, |
| 72 |
total_mem_to => $14*1024, |
| 73 |
total_mem_max => $15*1024, |
| 74 |
total_time_used => $16 ); |
| 75 |
} |
| 76 |
return %elements; |
| 77 |
} |
| 78 |
|
| 79 |
my $record=''; |
| 80 |
|
| 81 |
# Print config information to munin server |
| 82 |
if ( $ARGV[0] and $ARGV[0] eq "config" ) {
|
| 83 |
print "graph_title $title\n"; |
| 84 |
print "graph_vlabel Bytes Memory\n"; |
| 85 |
print "graph_category virtualization\n"; |
| 86 |
print "graph_args --lower-limit 0\n"; |
| 87 |
print "graph_info Show heap memory usage of JVM\n"; |
| 88 |
print "graph_order defnew_max tenured_max tenured_start tenured_end defnew_start defnew_end totalheap totalheapmax\n"; |
| 89 |
print "defnew_max.label DefNew max\n"; |
| 90 |
print "defnew_max.draw AREA\n"; |
| 91 |
print "tenured_max.label Tenured max\n"; |
| 92 |
print "tenured_max.draw STACK\n"; |
| 93 |
print "tenured_max.info DefNew max and Tenured max are stacked to show the total heap memory usage\n"; |
| 94 |
print "tenured_start.label Tenured start\n"; |
| 95 |
print "tenured_start.info Tenured (long term) memory used at start of GC\n"; |
| 96 |
print "tenured_end.label Tenured end\n"; |
| 97 |
print "tenured_end.info Tenured (long term) memory used at end of GC\n"; |
| 98 |
print "defnew_start.label DefNew start\n"; |
| 99 |
print "defnew_start.info Short term memory used by objects at start of GC\n"; |
| 100 |
print "defnew_end.label DefNew end\n"; |
| 101 |
print "defnew_end.info Short term memory claimed by objects that survived the GC\n"; |
| 102 |
print "totalheapmax.label Maximum total heap\n"; |
| 103 |
print "totalheapmax.info Maximum used total heap last 5 minutes\n"; |
| 104 |
print "totalheaptomax.label Total heap end\n"; |
| 105 |
print "totalheaptomax.info Heapsize at maximum after GC\n"; |
| 106 |
exit 0; |
| 107 |
} |
| 108 |
|
| 109 |
# Scan through the log file and keep the last instance of a |
| 110 |
# Tenured record in $record. |
| 111 |
|
| 112 |
my %last; |
| 113 |
# We can't be sure that there is a totalmemto in the log. |
| 114 |
my $totalmemto_atmax = 0; |
| 115 |
my $totalmemfrom_max = 0; |
| 116 |
|
| 117 |
|
| 118 |
open( FILE, "< $logfile" ) or die "Can't open $logfile: $!\n"; |
| 119 |
|
| 120 |
# We want to collect the highest total_mem_max in the last 5 minute period. |
| 121 |
seek(FILE,-4096,SEEK_END); |
| 122 |
my $now; |
| 123 |
my $lastnow = 0; |
| 124 |
|
| 125 |
while (<FILE>) {
|
| 126 |
chomp; |
| 127 |
if (/:/) {
|
| 128 |
($now,undef) = split(/:/,$_,2); |
| 129 |
$now = $lastnow unless $now; |
| 130 |
} |
| 131 |
} |
| 132 |
|
| 133 |
my $noolderthan = $now - 300; |
| 134 |
|
| 135 |
# print "Latest time is: $now. 5 min ago is $noolderthan\n"; |
| 136 |
|
| 137 |
seek(FILE,0,SEEK_SET); |
| 138 |
|
| 139 |
$lastnow = 0; |
| 140 |
$now=0; |
| 141 |
|
| 142 |
while (<FILE>) {
|
| 143 |
chomp; |
| 144 |
if (/:/) {
|
| 145 |
($now,undef) = split(/:/,$_,2); |
| 146 |
$now = $lastnow unless $now; |
| 147 |
} |
| 148 |
|
| 149 |
if (/.+Tenured.+/) {
|
| 150 |
$record = $_; |
| 151 |
} elsif (/^:.+/) {
|
| 152 |
$record .= $_; |
| 153 |
} |
| 154 |
if ($record =~ /Tenured.+secs\]$/) {
|
| 155 |
%last = analyze_record($record); |
| 156 |
|
| 157 |
#print "($now > $noolderthan and $last{total_mem_from} > $totalmemfrom_max)\n";
|
| 158 |
|
| 159 |
if ($now > $noolderthan and $last{total_mem_from} > $totalmemfrom_max) {
|
| 160 |
$totalmemfrom_max = $last{total_mem_max};
|
| 161 |
$totalmemto_atmax = $last{total_mem_to};
|
| 162 |
# print "New larger at $now: $totalmemto_max\n"; |
| 163 |
} |
| 164 |
$record = ''; |
| 165 |
} |
| 166 |
$lastnow=$now; |
| 167 |
} |
| 168 |
close FILE; |
| 169 |
|
| 170 |
$totalmemfrom_max=$totalmemto_atmax='U' if $totalmemfrom_max==0; |
| 171 |
|
| 172 |
# Print the values to be represented in the munin graph |
| 173 |
print "tenured_max.value $last{total_mem_max}\n";
|
| 174 |
print "tenured_start.value $last{total_mem_from}\n";
|
| 175 |
print "tenured_end.value $last{total_mem_to}\n";
|
| 176 |
|
| 177 |
print "defnew_max.value $last{defnew_mem_max}\n";
|
| 178 |
print "defnew_start.value $last{defnew_mem_from}\n";
|
| 179 |
print "defnew_end.value $last{defnew_mem_to}\n";
|
| 180 |
|
| 181 |
print "totalheapmax.value $totalmemfrom_max\n"; |
| 182 |
print "totalheaptomax.value $totalmemto_atmax\n"; |
