#!/usr/bin/perl -w # #@# check_jungledisk plugin for nagios #@# #@# usage: check_jungledisk -H -f [-s ] #@# #@# Checks the health of your most recent Jungle Disk backup for the hostname specified by parsing #@# the atom feed. You can specify either just a hostname or the FQDN that appears in JD. #@# #@# The URL should be something like: #@# http://backupreporting.jungledisk.com/feeds/backupreporting.ashx?format=atom&guid= #@# NOTE: Be sure to use quotes around the URL otherwise the last '&' character will probably instruct #@# your shell to run this process in the background. #@# #@# By default, this plugin will warn if the most recent backup is more than 720 hours (30 days) old. #@# Change this default using the -s option. #@# #@# In this example, jungledisk warns if backups are more than 24 hours old: #@# check_jungledisk -H myhost -f -s 24 # # Dependency: XML::Simple # (sorry, couldn't find an elegant way to avoid this) #@# #@# initial version: 1 Dec 2010 by Arya Abdian #@# Thanks to Intunity Pty ltd (www.intunity.com.au) for permitting release. # # CHANGELOG # 2011-02-01 v1.1 Looks like JungleDisk made achange to their atom feed, # which broke a validation step: feed->entry->id matched # "^http:feeds.jungledisk.com", now it matches # "^http://feeds.jungledisk.com" # 2011-02-03 v1.2 More unanounced changes by JungleDisk. # 1) feed->entry->id now matches http://www.jungledisk.com # 2) feed->updated now matches format YYYY-mm-ddTHH:MM:SS.0000000Z # this is not natively supported by GNU date, so bullet has been bitten # and all date/time processing is being handled within perl, thus # improving portability. # 3) feed->entry->link->"URL" is now feed->entry->link->href->"URL" # 4) feed->updated is reporting a timestamp in the future. Bug raised. # # # 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. use strict; use lib "/usr/local/nagios/libexec"; use XML::Simple; use Getopt::Long; use LWP::Simple; use Time::Local; my ($opt_H, $opt_s, $opt_f); my $PROGNAME = "check_jungledisk"; my $max_stale_hours = 720; sub print_usage(); sub invalid_url(); Getopt::Long::Configure('bundling'); GetOptions("H=s" => \$opt_H, "hostname=s" => \$opt_H, "s=s" => \$opt_s, "stale-hours=s" => \$opt_s, "f=s" => \$opt_f, "feed_url=s" => \$opt_s); if ((! $opt_H) or (! $opt_f)) { print_usage(); exit 3; } if ($opt_s and $opt_s =~ m/[0-9]+/) { $max_stale_hours = $opt_s; } my $feed = get $opt_f or ( invalid_url() and exit 3 ); # initialize parser and read the file my $xml = eval { XMLin($feed) }; (invalid_url() and exit 3) if ($@); my $hostname = $opt_H; my $mostrecent_updated = 0; my $mostrecent_entry = 0; my $mostrecent_jobname = "UNKNOWN"; my $mostrecent_status = "UNKNOWN"; my ($mostrecent_summary, $mostrecent_link); my $output_str = ""; my $output_ret = 0; if (!(($xml->{link}->{href} =~ m/jungledisk/) && ($xml->{xmlns} =~ m/Atom/))) { invalid_url(); exit 3; } my ($updated_unixtime, $entry); my ($sec, $min, $hour, $mday, $mon, $year); for $entry (keys %{$xml->{entry}}) { unless ($entry =~ m/^http:.*jungledisk.com/) { invalid_url(); exit 3; } if ( $xml->{entry}->{$entry}->{updated} =~ /^(\d{4})-(\d\d)-(\d\d).(\d\d):(\d\d):(\d\d).*$/ ) { ($year, $mon, $mday, $hour, $min, $sec) = ($1, $2 - 1, $3, $4, $5, $6); } else { invalid_url(); exit 3; } $updated_unixtime = timegm($sec, $min, $hour, $mday, $mon, $year); if ($xml->{entry}->{$entry}->{title} =~ m/(.*?) on $hostname.*?\((.*?)\).*$/) { if ($updated_unixtime > $mostrecent_updated) { $mostrecent_updated = $updated_unixtime; $mostrecent_entry = $entry; $mostrecent_jobname = $1; $mostrecent_status = $2; $mostrecent_summary = $xml->{entry}->{$entry}->{summary}; $mostrecent_link= $xml->{entry}->{$entry}->{link}->{href}; } } } if ($mostrecent_updated == 0) { print "No JungleDisk backups for hostname $hostname were found."; exit 2; } if ((time() - ($max_stale_hours * 3600)) > $mostrecent_updated) { $output_ret++; $output_str .= "STALE ALERT. "; } if ($mostrecent_status eq "COMPLETE") { $output_str .= "$mostrecent_jobname completed successfully "; } elsif ($mostrecent_status eq "FAILED") { $output_ret=2 ; $output_str .= "$mostrecent_jobname failed "; } else { $output_ret++ ; $output_str .= "$mostrecent_jobname $mostrecent_status "; } $output_str .= "at " . localtime($mostrecent_updated) . ". "; $output_str .= "Stats: $mostrecent_summary. "; $output_str .= 'Details.'; print "$output_str\n"; exit $output_ret; sub print_usage () { print `grep '^#@#' $0 | sed -e 's/^#@#[ ]*//g'`; } sub invalid_url () { print "ERROR: URL should be a valid JungleDisk Atom feed. Set up my atom feed.\n"; }