#!/usr/bin/perl -w package RRDPerf; use strict; use RRDs; use Color::Rgb; BEGIN{ use Exporter (); @RRDPerf::ISA = qw(Exporter); @RRDPerf::EXPORT = qw(); @RRDPerf::EXPORT_OK = qw(update_rrd graph_rrd); } my $rrds = '/usr/local/nagios_indep/var/rrds'; my $imgs = '/usr/local/nagios/share/images/rrdimg'; my $debug = 0; my $rgb = new Color::Rgb(rgb_txt => '/usr/X11R6/lib/X11/rgb.txt'); my @colors = ( $rgb->hex('red','#'), $rgb->hex('blue','#'), $rgb->hex('green','#'), $rgb->hex('orange','#'), $rgb->hex('dark red','#'), $rgb->hex('dark green','#'), $rgb->hex('dark blue','#') ); undef $rgb; =head1 NAME RRDPerf.pm - does the work for L. =head1 AUTHOR (c) 2003 Hannes Schulz =head1 VERSION Version 1.0 =head1 SYNOPSIS use RRDPerf qw/update_rrd graph_rrd/; # create database if not existing and put in data (two "colums": loss and rta): update_rrd("PING","sapwdfr0",30*60,scalar time, "loss", $loss, "RTA", $rta); # create a picture for a host/service: graph_rrd("PING","sapwdfr0","Ping-stats","loss", "RTA"); =head1 DEBUGGING Set C<$debug> to true in the script. If your crontab has a line MAILTO=you@sap.com you should get the results by mail every hour. =head1 DESCRIPTION This is doing all the work for L. Look there for the gory details. You should not need to change anything in here... except... well: This assumes a whole lot of "default" values, like the amount of time the data will be kept, what color which graph should have... You I want to change this, try the documentation for RRDTool at http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/manual/ The parameters described there are the same as those used in RRDs-module. =head2 METHODS =over 4 =item update_rrd This just puts in the values given into a database named by putting together the general database path/hostname/servicedescription.rrd If this file does not exist, it is created by C. Parameters: $sdesc # Service description $hn # Host Name $step # how often $timet # when messure was taken %vals # like (mem => 10, cpu => 99) =cut sub update_rrd($$$$@){ my $sdesc = shift(); # Service description my $hn = shift(); # Host Name my $step = shift(); # how often my $timet = shift(); # when messure was taken my %vals = @_; # like {mem => 10, cpu => 99} my $timeoffset = `cat /usr/local/nagios_indep/var/rrds/$hn/toffset.txt`; $timet += ($timeoffset * 3600); $sdesc =~ s/\W/-/g; # for use as filename unless(-e "$rrds/$hn/$sdesc.rrd"){ create_rrd($sdesc,$hn,$step,$timet,@_); } my @cmd = ( "$rrds/$hn/$sdesc.rrd", ); push @cmd, join(":", $timet, values %vals); RRDs::update(@cmd); my $ERR=RRDs::error; if($ERR){ sleep 2; # wait... and RRDs::update(@cmd); # try again $ERR=RRDs::error; } warn "ERROR while updating: $ERR\n".join(" ",@cmd) if($ERR and $debug); } =item create_rrd($$$@) This creates a new RRD-File, using rough guesses about what you want. See the RRDTool-Documentation and here: L for more infos. It sleeps 1 second at the end, so that an update immediately afterwards is possible. Parameters: $sdesc # Service description $hn # Host Name $step # how often $timet # when messure was taken %vals # like {mem => 10, cpu => 99} =cut sub create_rrd($$$$@){ my $sdesc = shift(); # Service description my $hn = shift(); # Host Name my $step = shift(); # how often my $timet = shift(); # when messure was taken my %vals = @_; # like {mem => 10, cpu => 99} $sdesc =~ s/\W/-/g; # for use as filename mkdir("$rrds/$hn"); my @cmd = ( "$rrds/$hn/$sdesc.rrd", "--start", $timet-$step, "--step", $step ); foreach(keys %vals){ push(@cmd,"DS:$_:GAUGE:".($step*3).":-9999999999:9999999999"); push(@cmd,"RRA:AVERAGE:0.5:1:2688"); # 1 Month if step=15min push(@cmd,"RRA:AVERAGE:0.5:4:4320"); # 6 Months if step=15min/4 } print "creating $rrds/$hn/$sdesc.rrd..." if $debug; RRDs::create(@cmd); my $ERR=RRDs::error; die "ERROR while creating: $ERR\n" if $ERR; print "done.\n" if $debug; sleep 2; } =item graph_rrd This creates a graph for a database (name put together as shown above). Again, it uses rough guesses, use the RRDTool Documentation and here: L if you want to change anything that is B self-explanatory. Parameters: $sdesc # Service Description $hn # Host Name $title # Title of the diagram @DSs # All DSses. =cut sub graph_rrd{ graph_rrd_do_work("180",@_); graph_rrd_do_work("007",@_); graph_rrd_do_work("002",@_); } sub graph_rrd_do_work{ my $days = shift(); # number of days my $sdesc = shift(); # Service Description my $hn = shift(); # Host Name my $title = shift(); # Title of the diagram my @DSs = @_; # All DSses. $sdesc =~ s/\W/-/g; # make filename-usable my $file = "$rrds/$hn/$sdesc.rrd"; return unless(-e $file); my $end = scalar time; my $start = scalar time - ($days*86400); my $grid; $grid = "WEEK:1:MONTH:1:MONTH:1:345600:%b" if($days>10); $grid = "DAY:1:WEEK:1:DAY:1:86400:%m-%d" if($days<10); $grid = "HOUR:2:DAY:1:HOUR:2:0:%H" if($days<=3); my $timeoffset = `cat /usr/local/nagios_indep/var/rrds/$hn/toffset.txt`; $end += ($timeoffset * 3600); $start += ($timeoffset * 3600); my @cmd =( "$imgs/$hn"."__$sdesc"."__$days.png", # Dest "--x-grid", $grid, # Mayor grid 1 week, "--start", $start, # one week ### TODO "--end", $end, # now + offset "--imgformat", "PNG", "--title", "$hn: $title" # "Hostname: Title" ); my $i = 0; my $d = ""; foreach(@DSs){ $d = $_; $d =~ y!_!/! if($sdesc eq "fs-disk-nrpep"); push @cmd, "DEF:$_=$file:$_:AVERAGE"; push @cmd, "LINE2:$_$colors[$i]:$d"; $i++; } RRDs::graph(@cmd); my $ERR=RRDs::error; warn "ERROR while graphing: $ERR\n".join(", ",@cmd) if($ERR); } =back =cut 1;