From 5e4b9fe9ed3975e519e317e07288fcee1a2180a3 Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Sun, 11 Sep 2011 10:03:03 +0000 Subject: fix library paths and start perl via env, following todays custom --- bin/smokeping | 177 +++++++++++++++++ bin/smokeping.dist | 174 ----------------- bin/tSmoke | 544 +++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/tSmoke.dist | 543 ---------------------------------------------------- 4 files changed, 721 insertions(+), 717 deletions(-) create mode 100755 bin/smokeping delete mode 100755 bin/smokeping.dist create mode 100755 bin/tSmoke delete mode 100755 bin/tSmoke.dist diff --git a/bin/smokeping b/bin/smokeping new file mode 100755 index 0000000..3fe0575 --- /dev/null +++ b/bin/smokeping @@ -0,0 +1,177 @@ +#!/usr/bin/env perl +# -*-perl-*- + +use strict; +use warnings; + +use FindBin; +use lib "$FindBin::Bin/../thirdparty/lib/perl5"; +use lib "$FindBin::Bin/../lib"; + +use Smokeping 2.004002; + +Smokeping::main("etc/config.dist"); + +=head1 NAME + +smokeping - Commandline tool for SmokePing + +=head1 SYNOPSIS + +B [ B<--email> | B<--makepod> | B<--version> | B<--restart> ] + + Options: + + --man[=x] Show the manpage for the program (or for probe x, if specified) + + --help Help :-) + + --email Send SmokePing Agents to all Targets marked DYNAMIC + + --config=x Use a config file different from the default + + --check Just check the config file syntax, don't start the daemon + + --makepod[=x] Create POD documentation on Config file (or for probe x, if specified) + + --version Show SmokePing Version + + --debug Run Only once and do not Fork + + --debug-daemon Start the daemon with debugging enabled + + --restart Restart SmokePing + + --reload Reload configuration in the running process without interrupting + any probes + + --nodaemon Do no daemonize the process (no fork) + + --filter=x Only measure entries which pass the filter x + + --logfile=x Append warnings to logfile x. + + --static[=x] Generates a static website in directory x. If x is left out, + pagedir from the config is used. + + --nosleep For debugging you may want to run SmokePing without sleep interval + + --gen-examples Generate the smokeping_examples document and example config files + (to be used while building inside the smokeping distribution) + With --check : check the syntax of the generated examples. + + --master-url=s Run smokeping in slave mode. Attach to master for config. + + --slave-name=s By default the slave will use whatever it thinks its name + is, when talking to its master. In some cases you may + probably want to override this. + + + --shared-secret=s File containing the shared secret for talking to the server. + + --cache-dir=s Directory for temporary data storage when running in slave mode. + + --pid-dir=s Directory for the PID file when running in slave mode. + (optional, defaults to --cache-dir) + +=head1 DESCRIPTION + +The B tool is the commandline part of the SmokePing system. Its +main function is to run as a daemon and send Pings to all the Targets you +have specified in the Config file. When you call B without +arguments it will start as a daemon and do its work. + +If called with an argument, then further functions can be activated, as seen +in the Synopsis above. The B<--email> function is explained in the +documentation on the config file. + +The B<--filter> option allows you to run the daemon on a big config file, +but have the config file filtered and only measure the entries that pass the +filter. This is useful for remote measurement. Run Smokeping with two +exclusive filters in two locations and rsync the rrds back to the webserver +host where you run the cgi. Filters act on the section names in the config +file. Multiple section names are concatenated with B like path names: + + *** targets *** + + A + .... + + B + ... + ++ C + +This gives + + /A + +and + + /B, /B/C + +If I want to monitor /A my filter would look like this: + + --filter=/A + +Filters follow regular expression syntax. The are always anchored at the tip of the string. +by adding a B to the front of the filter string you negate it. Matching entries will be excluded from monitoring. +Multiple B<--filter> arguments can be used to assemble complex filters: + + --filter=/A --filter=/B + +would include all the targets + + --filter=/A --filter=/B --filter=!/B/C + +would include all but /B/C. + +The B<--makepod> does get used internally to produce the +L. + +Please refer to L for detailed setup instructions. + +=head1 SETUP + +When installing SmokePing, this file has to be adjusted to fit your +local system. Three paths have to be entered. + +One pointing to your B installation + + use lib qw(/usr/pack/rrdtool-1.0.33-to/lib/perl); + +One pointing to the place where you have installed the SmokePing libraries + + use lib qw(/home/oetiker/public_html/smokeping/lib); + +The third path is the argument to the Smokeping::main command. It points to +the SmokePing configuration file. + + use Smokeping; + Smokeping::main("/home/oetiker/.smokeping/config"); + +=head1 COPYRIGHT + +Copyright (c) 2002 by Tobias Oetiker. All right reserved. + +=head1 LICENSE + +This program is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public +License along with this program; if not, write to the Free +Software Foundation, Inc., 675 Mass Ave, Cambridge, MA +02139, USA. + +=head1 AUTHOR + +Tobias Oetiker Etobi@oetiker.chE + +=cut diff --git a/bin/smokeping.dist b/bin/smokeping.dist deleted file mode 100755 index 94e7807..0000000 --- a/bin/smokeping.dist +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/perl -w -# -*-perl-*- - -use lib qw(/scratch/oetiker/rrd-trunk/lib/perl); -use lib qw(lib); -use strict; -use warnings; -use Smokeping 2.004002; - -Smokeping::main("etc/config.dist"); - -=head1 NAME - -smokeping - Commandline tool for SmokePing - -=head1 SYNOPSIS - -B [ B<--email> | B<--makepod> | B<--version> | B<--restart> ] - - Options: - - --man[=x] Show the manpage for the program (or for probe x, if specified) - - --help Help :-) - - --email Send SmokePing Agents to all Targets marked DYNAMIC - - --config=x Use a config file different from the default - - --check Just check the config file syntax, don't start the daemon - - --makepod[=x] Create POD documentation on Config file (or for probe x, if specified) - - --version Show SmokePing Version - - --debug Run Only once and do not Fork - - --debug-daemon Start the daemon with debugging enabled - - --restart Restart SmokePing - - --reload Reload configuration in the running process without interrupting - any probes - - --nodaemon Do no daemonize the process (no fork) - - --filter=x Only measure entries which pass the filter x - - --logfile=x Append warnings to logfile x. - - --static[=x] Generates a static website in directory x. If x is left out, - pagedir from the config is used. - - --nosleep For debugging you may want to run SmokePing without sleep interval - - --gen-examples Generate the smokeping_examples document and example config files - (to be used while building inside the smokeping distribution) - With --check : check the syntax of the generated examples. - - --master-url=s Run smokeping in slave mode. Attach to master for config. - - --slave-name=s By default the slave will use whatever it thinks its name - is, when talking to its master. In some cases you may - probably want to override this. - - - --shared-secret=s File containing the shared secret for talking to the server. - - --cache-dir=s Directory for temporary data storage when running in slave mode. - - --pid-dir=s Directory for the PID file when running in slave mode. - (optional, defaults to --cache-dir) - -=head1 DESCRIPTION - -The B tool is the commandline part of the SmokePing system. Its -main function is to run as a daemon and send Pings to all the Targets you -have specified in the Config file. When you call B without -arguments it will start as a daemon and do its work. - -If called with an argument, then further functions can be activated, as seen -in the Synopsis above. The B<--email> function is explained in the -documentation on the config file. - -The B<--filter> option allows you to run the daemon on a big config file, -but have the config file filtered and only measure the entries that pass the -filter. This is useful for remote measurement. Run Smokeping with two -exclusive filters in two locations and rsync the rrds back to the webserver -host where you run the cgi. Filters act on the section names in the config -file. Multiple section names are concatenated with B like path names: - - *** targets *** - + A - .... - + B - ... - ++ C - -This gives - - /A - -and - - /B, /B/C - -If I want to monitor /A my filter would look like this: - - --filter=/A - -Filters follow regular expression syntax. The are always anchored at the tip of the string. -by adding a B to the front of the filter string you negate it. Matching entries will be excluded from monitoring. -Multiple B<--filter> arguments can be used to assemble complex filters: - - --filter=/A --filter=/B - -would include all the targets - - --filter=/A --filter=/B --filter=!/B/C - -would include all but /B/C. - -The B<--makepod> does get used internally to produce the -L. - -Please refer to L for detailed setup instructions. - -=head1 SETUP - -When installing SmokePing, this file has to be adjusted to fit your -local system. Three paths have to be entered. - -One pointing to your B installation - - use lib qw(/usr/pack/rrdtool-1.0.33-to/lib/perl); - -One pointing to the place where you have installed the SmokePing libraries - - use lib qw(/home/oetiker/public_html/smokeping/lib); - -The third path is the argument to the Smokeping::main command. It points to -the SmokePing configuration file. - - use Smokeping; - Smokeping::main("/home/oetiker/.smokeping/config"); - -=head1 COPYRIGHT - -Copyright (c) 2002 by Tobias Oetiker. All right reserved. - -=head1 LICENSE - -This program is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public -License along with this program; if not, write to the Free -Software Foundation, Inc., 675 Mass Ave, Cambridge, MA -02139, USA. - -=head1 AUTHOR - -Tobias Oetiker Etobi@oetiker.chE - -=cut diff --git a/bin/tSmoke b/bin/tSmoke new file mode 100755 index 0000000..fc0d74f --- /dev/null +++ b/bin/tSmoke @@ -0,0 +1,544 @@ +#!/usr/bin/env perl +# +#----------------------------------------------- +# tSmoke.pl +# Dan McGinn-Combs, Sep 2003 +# tSmoke.v 0.4 2004/03 McGinn-Combs +#----------------------------------------------- +# +# Modified for Smokeping official distribution since 20050526 +# Original README follows +# +# tSmoke.v04.README +# - added downtime report (--downtime) +# - a few tweaks to the calculations to ensure it's consistent +# +# tSmoke.v03.README +# - Initial Release +# - The script, started through cron, will cull through a config file and +# determine which hosts are down at a point in time (Morning report) and +# send out an smtp message to a mobile phone (for example). +# +# - It will also cull through the same config file and, using an included html +# file (small change to General section of the config file), send an html +# message which shows the availability over the past day, week, month +# and quarter. +# +# - It can also show detail data depending on the setting of +# command line option "detail". +# +# tSmoke.v02.README +# - Local testing version +#----------------------------------------------- +# +# 1) This program is run via CRON or the command line +# 2) It extracts RRD information from a smokeping config file +# 3) It pulls data from RRD files to determine if anything is offline, that is returning 0 PINGs +# 4) tSmoke reports status via an SMTP alert +# 5) tSmoke also generates an SMTP mail showing historical view of availability +# +# Many thanks to the following people for their help and guidance: +# Jim Horwath of Agere Systems Inc. for his examples and pointers to Spreadsheet::WriteExcel +# Frank Harper the author of SLAMon, a tool for tracking Service Level Agreements +# Tobias Oetiker, or course, the author of Smokeping, RRDTool and MRTG +# +use strict; +use warnings; + +# We need to use +# -- Smokeping libraries +# -- RRDTool +# -- Getopt::Long +# +# Point the lib variables to your implementation +use FindBin; +use lib "$FindBin::Bin/../thirdparty/lib/perl5"; +use lib "$FindBin::Bin/../lib"; + +use Smokeping 2.004002; +use Net::SMTP; +use Getopt::Long; +use Pod::Usage; +use RRDs; + +# Point to your Smokeping config file +my $cfgfile = "etc/config.dist"; + +# global variables +my $cfg; + +#this is designed to work on IPv4 only +my $havegetaddrinfo = 0; + +# we want opts everywhere +my %opt; + +#Hashes for the data +my (%Daily,%Weekly,%Monthly,%Quarterly); # the entries +my (%DailyC,%WeeklyC,%MonthlyC,%QuarterlyC); # a count of the entries + +###################### +### Moving Average ### +###################### +# Just a reminder of how to do a moving average if you ever want to +# PREV,UN,,UN,1,,IF,PREV,IF,,UN,1,,IF,-,,*,A,UN,1,A,IF,+ + +# Change Log: +# DMC - Added Quarterly Status +# DMC - Added HTML mail reporting and consolidated functions +# DMC = Added an external HTML mail template, tMail +my $RCS_VERSION = '$id: tSmoke.v 0.4 2004/03 McGinn-Combs'; + +sub test_mail($) { + my $cfg = shift; + my $mail = <<"EOF"; +Subject: tSmoke test +To: $cfg->{Alerts}{to} + +This is a test mail with 'tSmoke --testmail'. +EOF + print "Sending a test mail to $cfg->{Alerts}{to} from $cfg->{Alerts}{from}..."; + Smokeping::sendmail($cfg->{Alerts}{from}, $cfg->{Alerts}{to}, $mail); + print "done.\n"; +}; + +sub morning_update($) { + # Send out a morning summary of devices that are down + my $cfg = shift; + my $Body = ""; + my $TmpBody = ""; + my $To = ""; + if ( $opt{to} ) { $To = $opt{to}; } else { $To = $cfg->{Alerts}{to}; } + + # Get a list of the existing RRD Files + my @rrds = split ( /\n/,list_rrds($cfg->{Targets},"","") ); + my $Count = $#rrds + 1; + my $Down = 0; + + foreach my $target (@rrds) { + my $Loss = 0; + my ($start,$step,$names,$data) = RRDs::fetch "$target","AVERAGE","--start","-300"; + my $ERR=RRDs::error; + die "ERROR while reading $_: $ERR\n" if $ERR; + foreach my $line (@$data) { + $Loss += $$line[3]; + } + $Down += 1 if $Loss == 0; + $target =~ s/^([a-zA-Z0-9]*\/)*//; + $target =~ s/.rrd//; + $TmpBody .= "$target\n" if $Loss == 0; + } + $Body = <{Alerts}{from},$To,$Body); +} + +sub weekly_update($) { + # Send out a formatted HTML Table of the + # Previous Day, Week, Month and Quarter Availability + # Get a list of the existing RRD Files + my @rrds = split ( /\n/,list_rrds($cfg->{Targets},"","") ); + + my $To = ""; + if ( $opt{to} ) { $To = $opt{to}; } else { $To = $cfg->{Alerts}{to}; } + + my $Body =''; + +# Calculations Based on the following: +# RRDs::graph "fake.png", +# '--start','-86400', +# '-end','-300', +# "DEF:loss=${rrd}:loss:AVERAGE", +# "CDEF:avail=loss,0,100,IF", or more precisely "CDEF:avail=loss,2,GE,0,100,IF" +# and adding in the check for unknown for systems just coming on line +# "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF" + # Arbitrarily a loss of 10% of Pings means the system was down + my $pings = $cfg->{Database}{pings} * .1; + + foreach my $target (@rrds) { + # Get an average Availability for each RRD file + my $ERR; + + my ($DAverage,$Dxsize,$Dysize) = RRDs::graph "fake.png", + "--start","-86400", + "--end","-600", + "--step","1008", + "DEF:loss=$target:loss:AVERAGE", + "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF", + "PRINT:avail:AVERAGE:%.2lf"; + $ERR=RRDs::error; + die "ERROR while reading $_: $ERR\n" if $ERR; + + my ($WAverage,$Wxsize,$Wysize) = RRDs::graph "fake.png", + "--start","-604800", + "--end","-600", + "--step","4320", + "DEF:loss=$target:loss:AVERAGE", + "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF", + "PRINT:avail:AVERAGE:%.2lf"; + $ERR=RRDs::error; + die "ERROR while reading $_: $ERR\n" if $ERR; + + my ($MAverage,$Mxsize,$Mysize) = RRDs::graph "fake.png", + "--start","-2592000", + "--end","-600", + "--step","4320", + "DEF:loss=$target:loss:AVERAGE", + "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF", + "PRINT:avail:AVERAGE:%.2lf"; + $ERR=RRDs::error; + die "ERROR while reading $_: $ERR\n" if $ERR; + + my ($QAverage,$Qxsize,$Qysize) = RRDs::graph "fake.png", + "--start","-7776000", + "--end","-600", + "--step","4320", + "DEF:loss=$target:loss:AVERAGE", + "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF", + "PRINT:avail:AVERAGE:%.2lf"; + $ERR=RRDs::error; + die "ERROR while reading $_: $ERR\n" if $ERR; + + $target =~ s/$cfg->{General}{datadir}\///; + $target =~ s/.rrd//; + my @Path; + push @Path,split/\//,$target; + update_stats ( \@Path, @$DAverage[0], @$WAverage[0], @$MAverage[0], @$QAverage[0]); + } + + # Prepare the e-mail message + $Body = <{General}{tmail} or die "ERROR: can't read $cfg->{General}{tmail}\n"; + while (){ + my $Summary = Summary_Sheet(); + s/<##SUMMARY##>/$Summary/ig; + my $Daily = DetailSheet(86400); + s/<##DAYDETAIL##>/$Daily/ig; + my $Weekly = DetailSheet(604800); + s/<##WEEKDETAIL##>/$Weekly/ig; + my $Monthly = DetailSheet(2592000); + s/<##MONTHDETAIL##>/$Monthly/ig; + my $Quarterly = DetailSheet(7776000); + s/<##QUARTERDETAIL##>/$Quarterly/ig; + $Body .= $_; + } + close tSMOKE; + Smokeping::sendmail($cfg->{Alerts}{from}, $To, $Body); +} + +sub update_stats($$$$$); +sub update_stats($$$$$) { + # Update the uptime percentages in the Hash Arrays + my $Path = shift; + my $DAverage = shift; + my $WAverage = shift; + my $MAverage = shift; + my $QAverage = shift; + + #Enter everything once as it exists + #Trim off the rightmost component (hostname) and reenter the code + #If there is only one component, this is the final level + #This is an average of averages + + my $Ticket = join ( ".",@$Path); + $Daily { $Ticket } += $DAverage; + $Weekly { $Ticket } += $WAverage; + $Monthly { $Ticket } += $MAverage; + $Quarterly {$Ticket } += $QAverage; + $DailyC { $Ticket }++; + $WeeklyC { $Ticket }++; + $MonthlyC { $Ticket }++; + $QuarterlyC { $Ticket }++; + my $Length = @$Path; + @$Path = @$Path [ 0 .. $Length - 2 ]; + update_stats(\@$Path,$DAverage,$WAverage,$MAverage,$QAverage) if $Length > 1; +} + +sub Summary_Sheet() { + my $Body = ''; + + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= " + + + + \n"; + foreach (sort { $a cmp $b } keys %Monthly) { + next if ( $_ =~ /\./ ); + # this is a major section heading + $Body .= "\n"; + $Body .= ""; + $Body .= "" + if $Quarterly{$_}/$QuarterlyC{$_} >= 99 ; + $Body .= "" + if $Quarterly{$_}/$QuarterlyC{$_} > 95 and $Quarterly{$_}/$QuarterlyC{$_} < 99 ; + $Body .= "" + if $Quarterly{$_}/$QuarterlyC{$_} > 90 and $Quarterly{$_}/$QuarterlyC{$_} < 95 ; + $Body .= "" + if $Quarterly{$_}/$QuarterlyC{$_} < 90 ; + $Body .= "" + if $Monthly{$_}/$MonthlyC{$_} >= 99 ; + $Body .= "" + if $Monthly{$_}/$MonthlyC{$_} > 95 and $Monthly{$_}/$MonthlyC{$_} < 99 ; + $Body .= "" + if $Monthly{$_}/$MonthlyC{$_} > 90 and $Monthly{$_}/$MonthlyC{$_} < 95 ; + $Body .= "" + if $Monthly{$_}/$MonthlyC{$_} < 90 ; + $Body .= "" + if $Weekly{$_}/$WeeklyC{$_} >= 99; + $Body .= "" + if $Weekly{$_}/$WeeklyC{$_} > 95 and $Weekly{$_}/$WeeklyC{$_} < 99 ; + $Body .= "" + if $Weekly{$_}/$WeeklyC{$_} > 90 and $Weekly{$_}/$WeeklyC{$_} < 95 ; + $Body .= "" + if $Weekly{$_}/$WeeklyC{$_} < 90 ; + $Body .= "" + if $Daily{$_}/$DailyC{$_} >= 99; + $Body .= "" + if $Daily{$_}/$DailyC{$_} > 95 and $Daily{$_}/$DailyC{$_} < 99 ; + $Body .= "" + if $Daily{$_}/$DailyC{$_} > 90 and $Daily{$_}/$DailyC{$_} < 95 ; + $Body .= "" + if $Daily{$_}/$DailyC{$_} < 90 ; + $Body .= "\n"; + } + $Body .= "
IT Network Systems Availability Summary
Compiled: ". scalar(localtime) . "
ServicePast QuarterPast MonthPast WeekPast Day
$_" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%
"; + $Body .= "

\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "
Legend:
if uptime > 99% then GREEN
if uptime > 95% but < 99% then BLUE
if uptime > 90% but < 95% then YELLOW
if uptime < 90% then RED
\n"; + return $Body; +} + +sub NumDots($) { + # Count the number of dots in a string + # There's probably a better way to do this + my $DNA = shift; + my $a = 0; + while($DNA =~ /\./ig){$a++} + return $a +} + +sub DetailSheet($) { + # Populate the table with details depending on the value of %opts{detail} + my $Seconds = shift; + my $Body = ''; + + return '' unless $opt{detail}; + + # Monthly/Weekly/Daily + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= " + + \n"; + + my %CornBeef; + my %CornBeefC; + + CASE: { + %CornBeef = %Daily, %CornBeefC = %DailyC, print "Doing Daily\n", last CASE if $Seconds == 86400; + %CornBeef = %Weekly, %CornBeefC = %WeeklyC, print "Doing Weekly\n", last CASE if $Seconds == 604800; + %CornBeef = %Monthly, %CornBeefC = %MonthlyC, print "Doing Monthly\n", last CASE if $Seconds == 2592000; + %CornBeef = %Quarterly, %CornBeefC = %QuarterlyC, print "Doing Quarterly\n", last CASE if $Seconds == 7776000; + } # end of CASE block + + foreach (sort { $a cmp $b } keys %CornBeef ) { + next if NumDots ($_) > $opt{detail}; + if ( $_ =~ /\./ ) { + #this is a sub section + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + } else { + # this is a non-sub section + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= "\n"; + $Body .= ""; + } + } + $Body .= "
IT Network Systems Availability Previous " . $Seconds/86400 . " Day(s)
Compiled: ". scalar(localtime) . "
ServiceSecondsPercent
$_" . sprintf('%.0f',(100 - $CornBeef{$_} / $CornBeefC{$_}) * ($Seconds/100)) . "" . sprintf('%.2f',$CornBeef{$_} / $CornBeefC{$_}) . "%
" . $_ . "" . sprintf('%.0f',(100 - $CornBeef{$_} / $CornBeefC{$_}) * ($Seconds/100)) . "" . sprintf('%.2f',$CornBeef{$_} / $CornBeefC{$_}) . "%
\n"; + return $Body; + } + +sub list_rrds($$$); +sub list_rrds($$$) { + # List the RRD's used by this configuration + my $tree = shift; + my $path = shift; + my $print = shift; + my $prline; + foreach my $rrds (keys %{$tree}) { + if (ref $tree->{$rrds} eq 'HASH'){ + $prline .= list_rrds( $tree->{$rrds}, $path."/$rrds", $print ); + } + if ($rrds eq 'host' and $tree->{$rrds} !~ m|/| ) { + $prline .= "$cfg->{General}{datadir}$path".".rrd\n"; + } + } + return $prline; +} + +sub load_cfg ($) { + my $cfgfile = shift; +# my $parser = get_parser; + my $parser = Smokeping::get_parser; + $cfg = Smokeping::get_config $parser, $cfgfile; +} + +########################################################################### +# The Main Program +########################################################################### + +sub main($); +main($cfgfile); + +sub main ($) { + umask 022; + my $cfgfile = shift; + my $sendto; + GetOptions(\%opt, 'quiet','version','testmail','listrrds','to=s','detail=n','morning','weekly','help','man') or pod2usage(2); + if($opt{version}) { print "$RCS_VERSION\n"; exit(0) }; + if($opt{help}) { pod2usage(-verbose => 1); exit 0 }; + if($opt{man}) { pod2usage(-verbose => 2); exit 0 }; + load_cfg $cfgfile; + print "tSmoke for network managed by $cfg->{General}{owner}\nat $cfg->{General}{contact}\n(c) 2003 Dan McGinn-Combs\n" unless $opt{quiet}; + if($opt{testmail}) { test_mail($cfg) }; + if($opt{listrrds}) { print "List of Round Robin Databases used by this implementation\n"; + my @rrds = split ( /\n/,list_rrds($cfg->{Targets},"","") ); + foreach (@rrds) { + print "RRD: $_\n"; }; + } + if($opt{morning}) { morning_update($cfg) }; + if($opt{weekly}) { weekly_update($cfg) }; + exit 0; +} + +=head1 NAME + +tSmoke - Commandline tool for sending SmokePing information + +=head1 SYNOPSIS + +B [ B<--testmail> | B<--morning> | B<--weekly> | B<--version> | B<--help> | B<--man>] + + Options: + + --man Show the manpage + --help Help :-) + --version Show SmokePing Version + --testmail Send a test message + --listrrds List the RRDs used by this Smokeping + --morning Send a morning synopsis + --weekly Send a weekly status report + --to E-mail address to send message (i.e. '--to=xyz@company.com.invalid' + --detail How much detail to send in weekly report (i.e. '--detail=1') + --quiet Do not print welcome + +=head1 DESCRIPTION + +The B tool is a commandline tool which interfaces with the SmokePing system. +Its main function is to send a message indicating the current status of the systems +being monitored by Smokeping or an HTML mail file containing the status over the past day, +past week and past month including an overview. + +Typical crontab used to invoke this are + + # Quick morning alert to see what's down + 0 6 * * * /usr/local/smokeping/bin/tSmoke.pl --q --to=mobilephone@att.net.invalid --morning + # Weekly report on the percent availability of network systems with no detail + 0 8 * * * /usr/local/smokeping/bin/tSmoke.pl --q --to=mailbox@company.com.invalid --weekly --detail=0 + +=head1 SETUP + +When installing tSmoke, some variables must be adjusted to fit your local system. + +We need to use the following B: + +=over + +=item Smokeping + +=item RRDTool Perl bindings + +=item Getopt::Long + +=back + +Set up your libraries: + + use lib "/usr/local/smokeping/lib"; + use lib "/usr/local/rrdtool-1.0.39/lib/perl"; + +Point to your Smokeping B file + + my $cfgfile = "/usr/local/smokeping/etc/config"; + +Modify the Smokeping config file to include a path for tmail in the +General section: + + tmail = /usr/local/smokeping/etc/tmail + +=head1 COPYRIGHT + +Copyright (c) 2003 by Dan McGinn-Combs. All right reserved. + +=head1 LICENSE + +This program is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public +License along with this program; if not, write to the Free +Software Foundation, Inc., 675 Mass Ave, Cambridge, MA +02139, USA. + +=head1 AUTHOR + +Dan McGinn-Combs Ed.mcginn-combs@mindspring.comE + +Modified for Smokeping official distribution by Niko Tyni Entyni@iki.fiE + +=cut + diff --git a/bin/tSmoke.dist b/bin/tSmoke.dist deleted file mode 100755 index e389ff2..0000000 --- a/bin/tSmoke.dist +++ /dev/null @@ -1,543 +0,0 @@ -#!/usr/bin/perl -# -#----------------------------------------------- -# tSmoke.pl -# Dan McGinn-Combs, Sep 2003 -# tSmoke.v 0.4 2004/03 McGinn-Combs -#----------------------------------------------- -# -# Modified for Smokeping official distribution since 20050526 -# Original README follows -# -# tSmoke.v04.README -# - added downtime report (--downtime) -# - a few tweaks to the calculations to ensure it's consistent -# -# tSmoke.v03.README -# - Initial Release -# - The script, started through cron, will cull through a config file and -# determine which hosts are down at a point in time (Morning report) and -# send out an smtp message to a mobile phone (for example). -# -# - It will also cull through the same config file and, using an included html -# file (small change to General section of the config file), send an html -# message which shows the availability over the past day, week, month -# and quarter. -# -# - It can also show detail data depending on the setting of -# command line option "detail". -# -# tSmoke.v02.README -# - Local testing version -#----------------------------------------------- -# -# 1) This program is run via CRON or the command line -# 2) It extracts RRD information from a smokeping config file -# 3) It pulls data from RRD files to determine if anything is offline, that is returning 0 PINGs -# 4) tSmoke reports status via an SMTP alert -# 5) tSmoke also generates an SMTP mail showing historical view of availability -# -# Many thanks to the following people for their help and guidance: -# Jim Horwath of Agere Systems Inc. for his examples and pointers to Spreadsheet::WriteExcel -# Frank Harper the author of SLAMon, a tool for tracking Service Level Agreements -# Tobias Oetiker, or course, the author of Smokeping, RRDTool and MRTG -# -use strict; -use warnings; - -# We need to use -# -- Smokeping libraries -# -- RRDTool -# -- Getopt::Long -# -# Point the lib variables to your implementation -use lib qw(lib); -use lib qw(/usr/local/rrdtool-1.0.39/lib/perl); - -use Smokeping 2.004002; -use Net::SMTP; -use Getopt::Long; -use Pod::Usage; -use RRDs; - -# Point to your Smokeping config file -my $cfgfile = "etc/config.dist"; - -# global variables -my $cfg; - -#this is designed to work on IPv4 only -my $havegetaddrinfo = 0; - -# we want opts everywhere -my %opt; - -#Hashes for the data -my (%Daily,%Weekly,%Monthly,%Quarterly); # the entries -my (%DailyC,%WeeklyC,%MonthlyC,%QuarterlyC); # a count of the entries - -###################### -### Moving Average ### -###################### -# Just a reminder of how to do a moving average if you ever want to -# PREV,UN,,UN,1,,IF,PREV,IF,,UN,1,,IF,-,,*,A,UN,1,A,IF,+ - -# Change Log: -# DMC - Added Quarterly Status -# DMC - Added HTML mail reporting and consolidated functions -# DMC = Added an external HTML mail template, tMail -my $RCS_VERSION = '$id: tSmoke.v 0.4 2004/03 McGinn-Combs'; - -sub test_mail($) { - my $cfg = shift; - my $mail = <<"EOF"; -Subject: tSmoke test -To: $cfg->{Alerts}{to} - -This is a test mail with 'tSmoke --testmail'. -EOF - print "Sending a test mail to $cfg->{Alerts}{to} from $cfg->{Alerts}{from}..."; - Smokeping::sendmail($cfg->{Alerts}{from}, $cfg->{Alerts}{to}, $mail); - print "done.\n"; -}; - -sub morning_update($) { - # Send out a morning summary of devices that are down - my $cfg = shift; - my $Body = ""; - my $TmpBody = ""; - my $To = ""; - if ( $opt{to} ) { $To = $opt{to}; } else { $To = $cfg->{Alerts}{to}; } - - # Get a list of the existing RRD Files - my @rrds = split ( /\n/,list_rrds($cfg->{Targets},"","") ); - my $Count = $#rrds + 1; - my $Down = 0; - - foreach my $target (@rrds) { - my $Loss = 0; - my ($start,$step,$names,$data) = RRDs::fetch "$target","AVERAGE","--start","-300"; - my $ERR=RRDs::error; - die "ERROR while reading $_: $ERR\n" if $ERR; - foreach my $line (@$data) { - $Loss += $$line[3]; - } - $Down += 1 if $Loss == 0; - $target =~ s/^([a-zA-Z0-9]*\/)*//; - $target =~ s/.rrd//; - $TmpBody .= "$target\n" if $Loss == 0; - } - $Body = <{Alerts}{from},$To,$Body); -} - -sub weekly_update($) { - # Send out a formatted HTML Table of the - # Previous Day, Week, Month and Quarter Availability - # Get a list of the existing RRD Files - my @rrds = split ( /\n/,list_rrds($cfg->{Targets},"","") ); - - my $To = ""; - if ( $opt{to} ) { $To = $opt{to}; } else { $To = $cfg->{Alerts}{to}; } - - my $Body =''; - -# Calculations Based on the following: -# RRDs::graph "fake.png", -# '--start','-86400', -# '-end','-300', -# "DEF:loss=${rrd}:loss:AVERAGE", -# "CDEF:avail=loss,0,100,IF", or more precisely "CDEF:avail=loss,2,GE,0,100,IF" -# and adding in the check for unknown for systems just coming on line -# "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF" - # Arbitrarily a loss of 10% of Pings means the system was down - my $pings = $cfg->{Database}{pings} * .1; - - foreach my $target (@rrds) { - # Get an average Availability for each RRD file - my $ERR; - - my ($DAverage,$Dxsize,$Dysize) = RRDs::graph "fake.png", - "--start","-86400", - "--end","-600", - "--step","1008", - "DEF:loss=$target:loss:AVERAGE", - "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF", - "PRINT:avail:AVERAGE:%.2lf"; - $ERR=RRDs::error; - die "ERROR while reading $_: $ERR\n" if $ERR; - - my ($WAverage,$Wxsize,$Wysize) = RRDs::graph "fake.png", - "--start","-604800", - "--end","-600", - "--step","4320", - "DEF:loss=$target:loss:AVERAGE", - "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF", - "PRINT:avail:AVERAGE:%.2lf"; - $ERR=RRDs::error; - die "ERROR while reading $_: $ERR\n" if $ERR; - - my ($MAverage,$Mxsize,$Mysize) = RRDs::graph "fake.png", - "--start","-2592000", - "--end","-600", - "--step","4320", - "DEF:loss=$target:loss:AVERAGE", - "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF", - "PRINT:avail:AVERAGE:%.2lf"; - $ERR=RRDs::error; - die "ERROR while reading $_: $ERR\n" if $ERR; - - my ($QAverage,$Qxsize,$Qysize) = RRDs::graph "fake.png", - "--start","-7776000", - "--end","-600", - "--step","4320", - "DEF:loss=$target:loss:AVERAGE", - "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF", - "PRINT:avail:AVERAGE:%.2lf"; - $ERR=RRDs::error; - die "ERROR while reading $_: $ERR\n" if $ERR; - - $target =~ s/$cfg->{General}{datadir}\///; - $target =~ s/.rrd//; - my @Path; - push @Path,split/\//,$target; - update_stats ( \@Path, @$DAverage[0], @$WAverage[0], @$MAverage[0], @$QAverage[0]); - } - - # Prepare the e-mail message - $Body = <{General}{tmail} or die "ERROR: can't read $cfg->{General}{tmail}\n"; - while (){ - my $Summary = Summary_Sheet(); - s/<##SUMMARY##>/$Summary/ig; - my $Daily = DetailSheet(86400); - s/<##DAYDETAIL##>/$Daily/ig; - my $Weekly = DetailSheet(604800); - s/<##WEEKDETAIL##>/$Weekly/ig; - my $Monthly = DetailSheet(2592000); - s/<##MONTHDETAIL##>/$Monthly/ig; - my $Quarterly = DetailSheet(7776000); - s/<##QUARTERDETAIL##>/$Quarterly/ig; - $Body .= $_; - } - close tSMOKE; - Smokeping::sendmail($cfg->{Alerts}{from}, $To, $Body); -} - -sub update_stats($$$$$); -sub update_stats($$$$$) { - # Update the uptime percentages in the Hash Arrays - my $Path = shift; - my $DAverage = shift; - my $WAverage = shift; - my $MAverage = shift; - my $QAverage = shift; - - #Enter everything once as it exists - #Trim off the rightmost component (hostname) and reenter the code - #If there is only one component, this is the final level - #This is an average of averages - - my $Ticket = join ( ".",@$Path); - $Daily { $Ticket } += $DAverage; - $Weekly { $Ticket } += $WAverage; - $Monthly { $Ticket } += $MAverage; - $Quarterly {$Ticket } += $QAverage; - $DailyC { $Ticket }++; - $WeeklyC { $Ticket }++; - $MonthlyC { $Ticket }++; - $QuarterlyC { $Ticket }++; - my $Length = @$Path; - @$Path = @$Path [ 0 .. $Length - 2 ]; - update_stats(\@$Path,$DAverage,$WAverage,$MAverage,$QAverage) if $Length > 1; -} - -sub Summary_Sheet() { - my $Body = ''; - - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= " - - - - \n"; - foreach (sort { $a cmp $b } keys %Monthly) { - next if ( $_ =~ /\./ ); - # this is a major section heading - $Body .= "\n"; - $Body .= ""; - $Body .= "" - if $Quarterly{$_}/$QuarterlyC{$_} >= 99 ; - $Body .= "" - if $Quarterly{$_}/$QuarterlyC{$_} > 95 and $Quarterly{$_}/$QuarterlyC{$_} < 99 ; - $Body .= "" - if $Quarterly{$_}/$QuarterlyC{$_} > 90 and $Quarterly{$_}/$QuarterlyC{$_} < 95 ; - $Body .= "" - if $Quarterly{$_}/$QuarterlyC{$_} < 90 ; - $Body .= "" - if $Monthly{$_}/$MonthlyC{$_} >= 99 ; - $Body .= "" - if $Monthly{$_}/$MonthlyC{$_} > 95 and $Monthly{$_}/$MonthlyC{$_} < 99 ; - $Body .= "" - if $Monthly{$_}/$MonthlyC{$_} > 90 and $Monthly{$_}/$MonthlyC{$_} < 95 ; - $Body .= "" - if $Monthly{$_}/$MonthlyC{$_} < 90 ; - $Body .= "" - if $Weekly{$_}/$WeeklyC{$_} >= 99; - $Body .= "" - if $Weekly{$_}/$WeeklyC{$_} > 95 and $Weekly{$_}/$WeeklyC{$_} < 99 ; - $Body .= "" - if $Weekly{$_}/$WeeklyC{$_} > 90 and $Weekly{$_}/$WeeklyC{$_} < 95 ; - $Body .= "" - if $Weekly{$_}/$WeeklyC{$_} < 90 ; - $Body .= "" - if $Daily{$_}/$DailyC{$_} >= 99; - $Body .= "" - if $Daily{$_}/$DailyC{$_} > 95 and $Daily{$_}/$DailyC{$_} < 99 ; - $Body .= "" - if $Daily{$_}/$DailyC{$_} > 90 and $Daily{$_}/$DailyC{$_} < 95 ; - $Body .= "" - if $Daily{$_}/$DailyC{$_} < 90 ; - $Body .= "\n"; - } - $Body .= "
IT Network Systems Availability Summary
Compiled: ". scalar(localtime) . "
ServicePast QuarterPast MonthPast WeekPast Day
$_" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%
"; - $Body .= "

\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "
Legend:
if uptime > 99% then GREEN
if uptime > 95% but < 99% then BLUE
if uptime > 90% but < 95% then YELLOW
if uptime < 90% then RED
\n"; - return $Body; -} - -sub NumDots($) { - # Count the number of dots in a string - # There's probably a better way to do this - my $DNA = shift; - my $a = 0; - while($DNA =~ /\./ig){$a++} - return $a -} - -sub DetailSheet($) { - # Populate the table with details depending on the value of %opts{detail} - my $Seconds = shift; - my $Body = ''; - - return '' unless $opt{detail}; - - # Monthly/Weekly/Daily - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= " - - \n"; - - my %CornBeef; - my %CornBeefC; - - CASE: { - %CornBeef = %Daily, %CornBeefC = %DailyC, print "Doing Daily\n", last CASE if $Seconds == 86400; - %CornBeef = %Weekly, %CornBeefC = %WeeklyC, print "Doing Weekly\n", last CASE if $Seconds == 604800; - %CornBeef = %Monthly, %CornBeefC = %MonthlyC, print "Doing Monthly\n", last CASE if $Seconds == 2592000; - %CornBeef = %Quarterly, %CornBeefC = %QuarterlyC, print "Doing Quarterly\n", last CASE if $Seconds == 7776000; - } # end of CASE block - - foreach (sort { $a cmp $b } keys %CornBeef ) { - next if NumDots ($_) > $opt{detail}; - if ( $_ =~ /\./ ) { - #this is a sub section - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - } else { - # this is a non-sub section - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= "\n"; - $Body .= ""; - } - } - $Body .= "
IT Network Systems Availability Previous " . $Seconds/86400 . " Day(s)
Compiled: ". scalar(localtime) . "
ServiceSecondsPercent
$_" . sprintf('%.0f',(100 - $CornBeef{$_} / $CornBeefC{$_}) * ($Seconds/100)) . "" . sprintf('%.2f',$CornBeef{$_} / $CornBeefC{$_}) . "%
" . $_ . "" . sprintf('%.0f',(100 - $CornBeef{$_} / $CornBeefC{$_}) * ($Seconds/100)) . "" . sprintf('%.2f',$CornBeef{$_} / $CornBeefC{$_}) . "%
\n"; - return $Body; - } - -sub list_rrds($$$); -sub list_rrds($$$) { - # List the RRD's used by this configuration - my $tree = shift; - my $path = shift; - my $print = shift; - my $prline; - foreach my $rrds (keys %{$tree}) { - if (ref $tree->{$rrds} eq 'HASH'){ - $prline .= list_rrds( $tree->{$rrds}, $path."/$rrds", $print ); - } - if ($rrds eq 'host' and $tree->{$rrds} !~ m|/| ) { - $prline .= "$cfg->{General}{datadir}$path".".rrd\n"; - } - } - return $prline; -} - -sub load_cfg ($) { - my $cfgfile = shift; -# my $parser = get_parser; - my $parser = Smokeping::get_parser; - $cfg = Smokeping::get_config $parser, $cfgfile; -} - -########################################################################### -# The Main Program -########################################################################### - -sub main($); -main($cfgfile); - -sub main ($) { - umask 022; - my $cfgfile = shift; - my $sendto; - GetOptions(\%opt, 'quiet','version','testmail','listrrds','to=s','detail=n','morning','weekly','help','man') or pod2usage(2); - if($opt{version}) { print "$RCS_VERSION\n"; exit(0) }; - if($opt{help}) { pod2usage(-verbose => 1); exit 0 }; - if($opt{man}) { pod2usage(-verbose => 2); exit 0 }; - load_cfg $cfgfile; - print "tSmoke for network managed by $cfg->{General}{owner}\nat $cfg->{General}{contact}\n(c) 2003 Dan McGinn-Combs\n" unless $opt{quiet}; - if($opt{testmail}) { test_mail($cfg) }; - if($opt{listrrds}) { print "List of Round Robin Databases used by this implementation\n"; - my @rrds = split ( /\n/,list_rrds($cfg->{Targets},"","") ); - foreach (@rrds) { - print "RRD: $_\n"; }; - } - if($opt{morning}) { morning_update($cfg) }; - if($opt{weekly}) { weekly_update($cfg) }; - exit 0; -} - -=head1 NAME - -tSmoke - Commandline tool for sending SmokePing information - -=head1 SYNOPSIS - -B [ B<--testmail> | B<--morning> | B<--weekly> | B<--version> | B<--help> | B<--man>] - - Options: - - --man Show the manpage - --help Help :-) - --version Show SmokePing Version - --testmail Send a test message - --listrrds List the RRDs used by this Smokeping - --morning Send a morning synopsis - --weekly Send a weekly status report - --to E-mail address to send message (i.e. '--to=xyz@company.com.invalid' - --detail How much detail to send in weekly report (i.e. '--detail=1') - --quiet Do not print welcome - -=head1 DESCRIPTION - -The B tool is a commandline tool which interfaces with the SmokePing system. -Its main function is to send a message indicating the current status of the systems -being monitored by Smokeping or an HTML mail file containing the status over the past day, -past week and past month including an overview. - -Typical crontab used to invoke this are - - # Quick morning alert to see what's down - 0 6 * * * /usr/local/smokeping/bin/tSmoke.pl --q --to=mobilephone@att.net.invalid --morning - # Weekly report on the percent availability of network systems with no detail - 0 8 * * * /usr/local/smokeping/bin/tSmoke.pl --q --to=mailbox@company.com.invalid --weekly --detail=0 - -=head1 SETUP - -When installing tSmoke, some variables must be adjusted to fit your local system. - -We need to use the following B: - -=over - -=item Smokeping - -=item RRDTool Perl bindings - -=item Getopt::Long - -=back - -Set up your libraries: - - use lib "/usr/local/smokeping/lib"; - use lib "/usr/local/rrdtool-1.0.39/lib/perl"; - -Point to your Smokeping B file - - my $cfgfile = "/usr/local/smokeping/etc/config"; - -Modify the Smokeping config file to include a path for tmail in the -General section: - - tmail = /usr/local/smokeping/etc/tmail - -=head1 COPYRIGHT - -Copyright (c) 2003 by Dan McGinn-Combs. All right reserved. - -=head1 LICENSE - -This program is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public -License along with this program; if not, write to the Free -Software Foundation, Inc., 675 Mass Ave, Cambridge, MA -02139, USA. - -=head1 AUTHOR - -Dan McGinn-Combs Ed.mcginn-combs@mindspring.comE - -Modified for Smokeping official distribution by Niko Tyni Entyni@iki.fiE - -=cut - -- cgit v1.2.3-24-g4f1b