Category: | Utility Scripts |
Author/Contact Info | bpoag@comcast.net |
Description: | DeathClock attempts to determine how much time remains before a given filesystem has zero free space remaining, based on how quickly existing storage is being utilized. It will send a panic message via email to one or more recipients depending upon how confident it is that death (zero free space in the filesystem) is imminent. DeathClock can be used as a monitoring tool as well, spitting out predictions of woeful and untimely filesystem demise at user-specified intervals. It can either be run as a one-time gauge, or set to monitor a filesystem constantly. DeathClock is a morbid script that lives a mostly solitary life, with the possible exception of his partially mummified mother, in a gothic-inspired home on a hill overlooking a motel. It enjoys taxidermy, quiet dinners with the motel guests, and attacking unsuspecting customers while they shower.
Example output: # /usr/local/bin/deathclock.pl /prod 37 1 1 0 foo@bar.com DeathClock: Starting up.. DeathClock: Collecting 37 seconds of growth information for /prod. Please wait...................................... DeathClock: 85094.79 MB remaining in /prod. Estimated time of death: 7w 5d 9h 56m 9s. |
#!/usr/bin/perl # # DeathClock 0.1 written 021307:1105 by BJP # # DeathClock attempts to predict how much time remains until a given f +ilesystem runs out of storage. # # Usage: deathclock.pl <filesystem> <number_of_samples> <sleep_interva +l> <cycles> <panic_threshold> <email_address> # # # $version=0.1; use Mail::Sendmail; startupRoutine(); mainRoutine(); sub mainRoutine() { while(true) { collectStatusInfo(); determineTimeRemaining(); $counter++; if ($samples==$counter-1) { print"\n"; } if ($samples<=$counter-1) { print "DeathClock: $spaceRemaining MB remaining in $filesystem. +Estimated time of death: $timeRemaining.\n"; } else { print "."; } if ($counter-$samples>=$duration && $duration!=0) { print"\n"; exit(); } sleep($sleep); } } sub collectStatusInfo() { @dfStuff=`df -m | grep " $filesystem\$"`; @filesystemState=split /\s+/,@dfStuff[0]; $filesystemSize=$filesystemState[1]; $spaceRemaining=$filesystemState[2]; unshift(@history,$spaceRemaining); if ($counter>$samples) { pop(@history); } } sub determineTimeRemaining() { $timeRemaining=$spaceRemaining/((($history[$samples]-$history[0])/($s +amples*$sleep))+0.0001); ## 1) ^^^^ A really, REALLY long way of saying y=mx+b and solving for + x :) ## 2) The +0.0001 there is to prevent div-by-zero errors when the del +ta stays flat for the entire sample set. if($timeRemaining<5270400 && $timeRemaining>0) # 2 months { panicCheck(); $wks=int($timeRemaining/604800); $timeRemaining=int($timeRemaining%604800); $day=int($timeRemaining/86400); $timeRemaining=int($timeRemaining%86400); $hrs=int($timeRemaining/3600); $timeRemaining=int($timeRemaining%3600); $min=int($timeRemaining/60); $sec=int($timeRemaining%60); $timeRemaining="".$wks."w ".$day."d ".$hrs."h ".$min."m ".$sec."s" +; } else { $timeRemaining="Immortal (>2 months)"; } } sub panicCheck() { if ($timeRemaining<3600 && $timeRemaining>=0) { $panicStateDuration++; } else { $panicStateDuration=0; } if ($panicStateDuration>=$panicThreshold && $panicThreshold!=0) { print "DeathClock: Panic threshold exceeded!\n"; notifyRecipients(); } } sub notifyRecipients() { if ($counter>=$lastPanic+$silencerWaitTime || $firstPass==1) # If we' +ve waited long enough between sending emails.. { print "DeathClock: Sending panic notification to $mailRecipients.\n +"; %mail=( To => $mailRecipients, From => $mailSender, Subject => "DeathClock Panic Notification", Message => "DeathClock strongly believes less than 1 hour remains u +ntil $filesystem on $whereAmI runs out of space." ); sendmail(%mail) or die("Send failed: $Mail::Sendmail::error\n"); $lastPanic=$counter; $firstPass=0; } else { print "DeathClock: Supressing email notification. Recipient(s) were + notified less than 10 minutes ago.\n"; } } sub startupRoutine() { if ($#ARGV!=5) { if ($#ARGV<5) { print"\n\nToo few arguments specified. See below."; } else { print"\n\nToo many arguments specified. See below."; } print "\n\nDeathClock v$version written 021307:1105 by BJP"; print "\n\n Usage: $0 <filesystem> <number_of_samples> <sleep_int +erval> <cycles> <panic_threshold> <email_address>"; print "\n Example: $0 /tmp 10 2 34 18 foo@bar.com"; print "\n English: Monitor /tmp, based on 10 readings, checking eve +ry 2 seconds, and do so 34 times. If DeathClock sees less than an hou +r"; print "\n remains for 18 cycles in a row, it will notify f +oo@bar.com\n"; print "\nSpecifying 0 for the cycles parameter will run DeathClock in +definitely. Specifying 0 for panic_threshold will disable panic repor +ting."; print "\nMultiple email recipients can be specified using a comma del +imiter, and no spaces between the addresses."; print "\n\n\n"; exit(); } else { # Usage: deathclock.pl <filesystem> <number_of_samples> <sleep +_interval> <cycles> <panic_threshold> <email_address> print "\n\nDeathClock: Starting up..\n"; $whereAmI=`hostname`; $mailSender=$ENV{"USER"}."\@"."$whereAmI.yourcompanyname.com"; $filesystem=$ARGV[0]; $samples=$ARGV[1]; $sleep=$ARGV[2]; $duration=$ARGV[3]; $panicThreshold=$ARGV[4]; $mailRecipients=$ARGV[5]; @history=(); $queueLength=scalar(@history)+0; $silencerWaitTime=600/$sleep; # hardcoding this at 10 minutes.. $firstPass=1; chomp($whereAmI); $wait=($sleep*$samples)+0; print "DeathClock: Collecting $wait seconds of growth information for + $filesystem. Please wait."; } } |
Back to
Code Catacombs