root / plugins / jvm / jvm_sun_memory @ 17f78427
Historique | Voir | Annoter | Télécharger (5,68 ko)
| 1 | f5c19172 | Various | #!/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 | 17f78427 | Lars Kruse | # -verbose:gc |
| 23 | f5c19172 | Various | # -Xloggc:/var/log/app/jvm/gc.log |
| 24 | # -XX:+PrintGCTimeStamps |
||
| 25 | # -XX:+PrintGCDetails |
||
| 26 | |||
| 27 | 17f78427 | Lars Kruse | # History: |
| 28 | f5c19172 | Various | |
| 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 | 17f78427 | Lars Kruse | # Match all interesting elements of a record and insert them |
| 51 | f5c19172 | Various | # 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 | 8d9fe5bd | dipohl | print "graph_category virtualization\n"; |
| 86 | f5c19172 | Various | 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 | 17f78427 | Lars Kruse | |
| 149 | f5c19172 | Various | 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"; |
