#!/usr/bin/perl use strict; require Exporter; use AutoLoader qw(AUTOLOAD); use RRDs; use vars qw(@ISA @EXPORT); our @ISA = qw(Exporter); our %EXPORT_TAGS = ( 'all' => [ qw( generate_load generate_cpu generate_disk generate_eth generate_mem rrderrorcheck ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( generate_load generate_cpu generate_disk generate_eth rrderrorcheck generate_mem ); my $basedir = '/var/www/apps/'; my $now = time; sub getopts { my %options; my @opts = split(/ /,$_[0]); foreach my $tst(@opts) { my ($o,$v) = split(/=/,$tst); $options{$o} = $v; } return %options; } # Load-stats sub generate_load { my %options = &getopts; my @color = ('#EACC00','#EA8F00','#FF0000','#000000'); my $host = $options{'host'}; my $mode = $options{'mode'}; my $starttime = $options{'start'}; my $endtime = $options{'end'}; my $title = "$mode loadstats for $host"; my $width = $options{'width'}; $width = 600 unless(defined($options{'width'})); my $dir = "$basedir/cpustats"; my $infile = "$dir/$host.rrd"; my $outfile = "$dir/$host-load-$mode-$width.png"; my $now = time; RRDs::graph( "$outfile", # "-z", "-w $width", "-b 1000", "-v load", "-s $starttime", "-e $endtime", "-t $title", "--slope-mode", "--alt-autoscale-max", "--lower-limit=0", "--units-exponent=0", "--rigid", "DEF:a=$infile:loadavg1:AVERAGE", "DEF:b=$infile:loadavg5:AVERAGE", "DEF:c=$infile:loadavg15:AVERAGE", "CDEF:d=a,b,c,+,+", "AREA:a$color[0]:1 minute average", "GPRINT:a:LAST: Current\\:%8.2lf", "GPRINT:a:AVERAGE:Average\\:%8.2lf %s", "GPRINT:a:MAX:Maximum\\:%8.2lf %s\\n", "AREA:b$color[1]:5 minute average:STACK", "GPRINT:b:LAST: Current\\:%8.2lf", "GPRINT:b:AVERAGE:Average\\:%8.2lf %s", "GPRINT:b:MAX:Maximum\\:%8.2lf %s\\n", "AREA:c$color[2]:15 minute average:STACK", "GPRINT:c:LAST:Current\\:%8.2lf", "GPRINT:c:AVERAGE:Average\\:%8.2lf %s", "GPRINT:c:MAX:Maximum\\:%8.2lf %s\\n", "LINE1:d#000000:Total", ); &rrderrorcheck; return "\"$title\"/\n"; } # CPU-stats sub generate_cpu { my %options = &getopts; my @color = ('#FF0000','#EAAF00','#F5F800','#00FF00','#0000FF','#00EAFF','#FFFFFF'); my $host = $options{'host'}; my $mode = $options{'mode'}; my $starttime = $options{'start'}; my $endtime = $options{'end'}; my $title = "$mode cpustats for $host"; my $width = $options{'width'}; $width = 600 unless(defined($options{'width'})); my $dir = "$basedir/cpustats"; my $infile = "$dir/$host.rrd"; my $outfile = "$dir/$host-cpu-$mode-$width.png"; RRDs::graph( "$outfile", # "-z", "-w $width", "-b 1000", "-v tics/s", "-s $starttime", "-e $endtime", "-t $title", "-r", "-l 0", "--slope-mode", "DEF:system=$infile:system:AVERAGE", "DEF:user=$infile:user:AVERAGE", "DEF:wait=$infile:iowait:AVERAGE", "DEF:nice=$infile:nice:AVERAGE", "DEF:idle=$infile:idle:AVERAGE", "DEF:irq=$infile:irq:AVERAGE", "DEF:softirq=$infile:softirq:AVERAGE", "AREA:system$color[0]:System", "GPRINT:system:LAST:Current\\:%8.2lf %s", "GPRINT:system:AVERAGE:Average\\:%8.2lf %s", "GPRINT:system:MAX:Maximum\\:%8.2lf %s\\n", "AREA:user$color[1]:User:STACK", "GPRINT:user:LAST: Current\\:%8.2lf %s", "GPRINT:user:AVERAGE:Average\\:%8.2lf %s", "GPRINT:user:MAX:Maximum\\:%8.2lf %s\\n", "AREA:wait$color[2]:Wait:STACK", "GPRINT:wait:LAST: Current\\:%8.2lf %s", "GPRINT:wait:AVERAGE:Average\\:%8.2lf %s", "GPRINT:wait:MAX:Maximum\\:%8.2lf %s\\n", "AREA:nice$color[3]:Nice:STACK", "GPRINT:nice:LAST: Current\\:%8.2lf %s", "GPRINT:nice:AVERAGE:Average\\:%8.2lf %s", "GPRINT:nice:MAX:Maximum\\:%8.2lf %s\\n", "AREA:irq$color[4]:irq:STACK", "GPRINT:irq:LAST: Current\\:%8.2lf %s", "GPRINT:irq:AVERAGE:Average\\:%8.2lf %s", "GPRINT:irq:MAX:Maximum\\:%8.2lf %s\\n", "AREA:softirq$color[5]:sirq:STACK", "GPRINT:softirq:LAST: Current\\:%8.2lf %s", "GPRINT:softirq:AVERAGE:Average\\:%8.2lf %s", "GPRINT:softirq:MAX:Maximum\\:%8.2lf %s\\n", "AREA:idle$color[6]:Idle:STACK", "GPRINT:idle:LAST: Current\\:%8.2lf %s", "GPRINT:idle:AVERAGE:Average\\:%8.2lf %s", "GPRINT:idle:MAX:Maximum\\:%8.2lf %s\\n", ); &rrderrorcheck; return "\"$title\"/\n"; } # diskstats sub generate_disk { my %options = &getopts; my @color = ('#4668E4','#EAAF00'); my $host = $options{'host'}; my $device = $options{'dev'}; my $mode = $options{'mode'}; my $start = $options{'start'}; my $end = $options{'end'}; my $title = "$mode stats for $device\@$host"; my $width = $options{'width'}; $width = 600 unless(defined($options{'width'})); my $dir = "$basedir/diskstats"; my $infile = "$dir/$host/$device.rrd"; my $outfile = "$dir/$host-$device-$mode-$width.png"; RRDs::graph( "$outfile", # "-z", "-w $width", "-b 1024", "-v B/sec", "-s $start", "-e $end", "-t $title", "--slope-mode", "DEF:read_$device=$infile:read:AVERAGE", "DEF:write_$device=$infile:write:AVERAGE", "CDEF:readkb_$device=read_$device,1024,*", "CDEF:writekb_$device=write_$device,1024,*", "AREA:readkb_$device$color[0]:$device\(read\)", "COMMENT: Current\\:", "GPRINT:readkb_$device:LAST:%3.0lf%sB/sec", "COMMENT:Max\\:", "GPRINT:readkb_$device:MAX:%3.0lf%sB/sec", "COMMENT:Average\\:", "GPRINT:readkb_$device:AVERAGE:%3.0lf%sB/sec", "COMMENT:\\n", "LINE1:writekb_$device$color[1]:$device\(write\)", "COMMENT:Current\\:", "GPRINT:writekb_$device:LAST:%3.0lf%sB/sec", "COMMENT:Max\\:", "GPRINT:writekb_$device:MAX:%3.0lf%sB/sec", "COMMENT:Average\\:", "GPRINT:writekb_$device:AVERAGE:%3.0lf%sB/sec" ); &rrderrorcheck; return "\"$title\"/\n"; } # Ethernetstats sub generate_eth { my %options = &getopts; my @color = ('#00CF00','#002A97'); my $host = $options{'host'}; my $if = $options{'dev'}; my $mode = $options{'mode'}; my $starttime = $options{'start'}; my $endtime = $options{'end'}; my $title = "$mode stats for $if\@$host"; my $width = $options{'width'}; $width = 600 unless(defined($options{'width'})); my $dir = "$basedir/etherstats"; my $infile = "$dir/$host\/$if.rrd"; my $outfile = "$dir/$host-$if-$mode-$width.png"; RRDs::graph( "$outfile", # "-z", "-w $width", "-b 1024", "-v B/s", "-s $starttime", "-e $endtime", "-t $title", "--lower-limit=0", "--alt-autoscale-max", "--slope-mode", "DEF:bytesIn=$infile:bytesIn:AVERAGE", "DEF:bytesOut=$infile:bytesOut:AVERAGE", "AREA:bytesIn$color[0]:In", "COMMENT: Current\\:", "GPRINT:bytesIn:LAST:%3.0lf%sB/sec", "COMMENT:Max\\:", "GPRINT:bytesIn:MAX:%3.0lf%sB/sec", "COMMENT:Average\\:", "GPRINT:bytesIn:AVERAGE:%3.0lf%sB/sec", "COMMENT:\\n", "LINE1:bytesOut$color[1]:Out", "COMMENT:Current\\:", "GPRINT:bytesOut:LAST:%3.0lf%sB/sec", "COMMENT:Max\\:", "GPRINT:bytesOut:MAX:%3.0lf%sB/sec", "COMMENT:Average\\:", "GPRINT:bytesOut:AVERAGE:%3.0lf%sB/sec" ); &rrderrorcheck; return "\"$title\"/\n"; } # Memstats sub generate_mem { my %options = &getopts; my @color = ('#862F2F','#EA8F00','#FFC73B','#74C366'); my $host = $options{'host'}; my $mode = $options{'mode'}; my $starttime = $options{'start'}; my $endtime = $options{'end'}; my $title = "$mode memstats for $host"; my $width = $options{'width'}; $width = 600 unless(defined($options{'width'})); my $dir = "$basedir/memstats/"; my $infile = "$dir/$host.rrd"; my $outfile = "$dir/$host-$mode-$width.png"; RRDs::graph( "$outfile", # "-z", "-w $width", "-b 1024", "-v Bytes", "-s $starttime", "-e $endtime", "-t $title", "--slope-mode", "--lower-limit=0", "--alt-autoscale-max", "DEF:total=$infile:total:AVERAGE", "DEF:used=$infile:used:AVERAGE", "DEF:free=$infile:free:AVERAGE", "DEF:buffers=$infile:buffers:AVERAGE", "DEF:cached=$infile:cached:AVERAGE", "AREA:used$color[0]:Used", "COMMENT: Current\\:", "GPRINT:used:LAST:%8.2lf%siB", "COMMENT:Max\\:", "GPRINT:used:MAX:%8.2lf%siB", "COMMENT:Average\\:", "GPRINT:used:AVERAGE:%8.2lf%siB", "COMMENT:\\n", "AREA:buffers$color[1]:Buffers:STACK", "COMMENT:Current\\:", "GPRINT:buffers:LAST:%8.2lf%siB", "COMMENT:Max\\:", "GPRINT:buffers:MAX:%8.2lf%siB", "COMMENT:Average\\:", "GPRINT:buffers:AVERAGE:%8.2lf%siB", "COMMENT:\\n", "AREA:cached$color[2]:Cached:STACK", "COMMENT: Current\\:", "GPRINT:cached:LAST:%8.2lf%siB", "COMMENT:Max\\:", "GPRINT:cached:MAX:%8.2lf%siB", "COMMENT:Average\\:", "GPRINT:cached:AVERAGE:%8.2lf%siB", "COMMENT:\\n", "AREA:free$color[3]:Free:STACK", "COMMENT: Current\\:", "GPRINT:free:LAST:%8.2lf%siB", "COMMENT:Max\\:", "GPRINT:free:MAX:%8.2lf%siB", "COMMENT:Average\\:", "GPRINT:free:AVERAGE:%8.2lf%siB" ); &rrderrorcheck; return "\"$title\"/\n"; } sub rrderrorcheck { my $ERR = RRDs::error; print "$ERR\n" if defined($ERR); return 1 unless(defined($ERR)); } 1;