#!/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."; } }

In reply to DeathClock by bpoag

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.