Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Unix disk space reports

by halxd2 (Monk)
on Dec 15, 2000 at 02:15 UTC ( #46730=CUFP: print w/ replies, xml ) Need Help??

My supervisor needed to know how much space was on each of our servers. I knew what I needed was the df-k from each server, but that can be a lot of stuff. Welcome to Perl. So here's the quicky df-k grinder
#!/usr/local/bin/perl # # This is a unix disk space report generator. It takes df -k's and sp +its out # one report that gives each host's name, the total drive space, t +otal free # space available, and the percentage of free space on the system. + This is # total space, not separated by drive. Swap space not counted, nor + are NFS # mounted file systems. It supports Solaris and Linux, but not AIX +. To use # each host must have a separate file named for the host (df -k > +HOSTNAME) # as that is the way it will be called from the command line. I ca +n login # NIS and just create some of the files. I can log in as root on s +ome # non-NIS machines and use mail (dk -k > HOSTNAME; cat HOSTNAME | +mail hck) # have several systems that do not have mail access, but I can sft +p. I put # all the files in one directory and call the script ./disk.pl hos +ts/* # Calling the hosts by name from the command line also allows me t +o get a # report of just one host, or a selection of hosts. # #A typical df -k looks like this: ############################################################# #Filesystem 1k-blocks Used Available Use% Mounted on #/dev/dsk/c0t0d0s0 8061757 6306497 1674643 79% / #/dev/dsk/c0t0d0s1 380815 121164 221570 35% /var #swap 534400 216 534184 0% /tmp #nfs.home.edu:/mounts/pluto4/vol4/u04 # 43505106 39604270 3465785 92% /u04 #nfs.home.edu:/export/sun4/SunOS5.7/usr/x11 # 69607865 54714403 14197384 79% /usr/x11 #nfs.home.edu:/export/sun4/SunOS5.7/usr/misc # 69607865 54714403 14197384 79% /usr/misc #nfs.home.edu:/mounts/pluto4/vol4/u04/hck # 43505106 39604270 3465785 92% /home/hck #/vol/dev/dsk/c0t2d0/sol_8_sparc_2 # 115408 115408 0 100% /cdrom/sol_8_ +sparc_2 #mail.home.edu:/var/mail # 51998176 34547199 16930996 67% /var/mail #nfs.home.edu:/export/sun4/SunOS5.7/usr/perl-5.6 # 41562853 38366501 2780724 93% /usr/perl-5.6 #nfs.home.edu:/export/sun4/SunOS5.7/usr/gnu # 69607865 54714403 14197384 79% /usr/gnu ############################################################# #So we know some things about it fast. The only lines of interest are +the ones # that start with "/" CDROM drives stick out, but could be edited out + if # needed. NFS drives match the != /\// so they're gone. Headers from +mail get # wild, but they match != /\// also. Blank lines are the same. The fi +elds we # care about are the second and fourth. So we grab them and dump the +rest! # use strict; use diagnostics; my $host; my $line; #make a tmp file to read from open WRITEIT, ">report"; #All relevant hosts have been put on the command line (maybe hosts/*) #This will generate our data file. I like to see the raw data sometime +s. while($host = pop @ARGV) { chomp $host; open (READIT, "<$host") || die "\n can\'t open the host file: $!\n" +; print WRITEIT "start of $host\n"; while($line = <READIT>) { if($line !~ /^\/.*/){next;} if($line =~ /^\/proc.*/){next;}#Proc is not of interest $line =~ s/^([^ ]*) *([^ ]*) *[^ ]* *([^ ]*) *[^ ]* (.*)/$2 $3/; print WRITEIT "$line"; } print WRITEIT "end of $host\n"; close READIT; } close WRITEIT; #Now read the data and spit out a report. open READIT, "<report"; open WRITEIT, ">space"; my @numbers = qw(0 0); #numbers from the data file line my @space = qw(0 0); #space derived from numbers while($line = <READIT>) { chomp $line; #If this is the beginning of a host report, get the host name # and make the first entry. Then clear the space variables. if($line =~ /^start of.*/) { $line =~ s/start of (.*)/$1/; $host = $line; $host =~ s/hosts\/(.*)/$1/; print WRITEIT "Space report for $host\n"; @numbers = qw(0 0); @space = qw(0 0); next; } #if this is disk line grab the numbers and add them to the totals if($line =~ /^[0-9].*/) { @numbers = split " ", $line; $space[0] = $space[0] + $numbers[0]; $space[1] = $space[1] + $numbers[1]; next; } #if this the end of a host report, write the totals with a percenta +ge if($line =~ /^end of.*/) { my $percentage = $space[1] / $space[0]; #OK so this is a cheap way to format a number, but I didn't want + to # change print statements for one line. $percentage =~ s/..(..).*/$1%/; print WRITEIT "Total space on $host = $space[0]\n"; print WRITEIT "Total space available $host = $space[1]\n"; print WRITEIT "Percentage of free space is $percentage\n"; print WRITEIT "\n\n"; } }

Comment on Unix disk space reports
Download Code
Re: Unix disk space reports
by mr_leisure (Beadle) on Dec 21, 2000 at 18:42 UTC
    And if you are looking for a graphical representation of df -k running on your specified directory and looping on your specified timescale, using Perl::TK, check my little program out... Cheers ML
    ------------------------------------------------------------ DISKCHECK.pl ---------------------------- #!/usr/bin/perl # # Simple Diskcheck GUI, running my ds.pl diskcheck script. This GUI d +isplays the results of a diskcheck loop. # # Usage : diskcheck.pl # # # You will need to be running ds.pl -dir=DIRECTORY -time=LOOPTIME at t +he same time as running the GUI. # # # use Tk; use Net::Telnet(); # open filehandle to log file, in this case, ds.txt open (LOG, "tail -f ds.txt|") || "Could not open logfile!\n"; # create main GUI window my $mw = MainWindow->new(); $mw->Label(-text => "DiskCheck Utility for PerlMonk.org Folks")->pack +; # label that window my $menubar = $mw->Frame(-relief => "ridge", -borderwidth => 2)->pack (-anchor => "nw", -fill => "x"); # cr +eate menubar and its properties my $filemenu = $menubar->Menubutton(-text =>"File", -underline => 1)->pack (-side => "left"); # add first menu but +ton : File $filemenu->separator(); # add line separator on menu $filemenu->command(-label => "Save Current Log to DSlog.txt" -command => \&save_yn); # add button : Save log to file $filemenu->separator(); # add line separator on menu $filemenu->command(-label =>"Quit", -command => \&really_quit); # add button : Quit my $optmenu = $menubar->Menubutton(-text => "Options", -underline =>1)->pack (-side => "left"); # add new menu button + : Options $optmenu->separator(); # add line separator on menu $optmenu->command(-label => "Clear Logs", -command => \&clear_log); # add button : Clear Logs $optmenu->separator(); # add line separator my $helpmenu = $menubar->Menubutton(-text => "Help", -underline => 1)->pack (-side => "left"); # add Help menu $helpmenu->separator(); # add line separator to menu $helpmenu->command(-label => "About DiskCheck", -underline =>1, -command => \&help_about); # add about button +pointing to help_about subroutine my $text = $mw->Listbox(-relief => "sunken", -width => 50, -height => +30, -background => "white"); # add main data box my $scroll = $mw->Scrollbar(-command => ["yview", $text]); # add r +ight scrollbar $text->configure(-yscrollcommand => ["set", $scroll]); $text->pack(-side => "left", -fill => "both", -expand => "yes"); $scroll->pack(-side => "right", -fill => "y"); $mw->fileevent(LOG, 'readable', [\&insert_text]); MainLoop; sub insert_text { my $curline; if ($curline = <LOG>) { $text->insert('end', $curline); $text->yview('moveto', 100); } else { $mw->fileevent(LOG, 'readable', ""); } } sub clear_log { $text->delete(0, 'end'); } sub save_log { my @current_log = $text->get(0, 'end'); open (LOG2, ">>DSlog.txt"); print LOG2 @current_log; close (LOG2); exit; } sub save_yn { if (! Exists($sftl)) { my $sftl = $filemenu->Toplevel(); $sftl->title("Alert!"); $sftl->Label(-text => "Save to DSlog.txt? \nWARNING : Destinat +ion file will be overwritten!")->pack; $sftl->Button(-text => "Yes", -command => \&save_log, -command => sub {$sftl->withdraw}) +->pack(-expand => "yes", -side=>"left"); $sftl->Button(-text => "No", -command => sub { $sftl->withdraw })->pack(-expand => "yes +", -side => "right"); } else { $sftl->deiconify(); $sftl->raise(); } } sub not_complete { if (! Exists($omtl)) { my $omtl = $optmenu->Toplevel(); $omtl->title("Alert!"); $omtl->Label(-text =>"This Section Not Complete!")->pack; $omtl->Button(-text => "Ok", -command => sub { $omtl->withdraw })->pack(-expand => "yes +"); } else { $omtl->deiconify(); $omtl->raise(); } } sub help_about { if (! Exists($hmtl)) { my $hmtl = $helpmenu->Toplevel(); $hmtl->title("About DiskCheck"); $hmtl->Label(-justify => center, -text => "Originally written for UBS warburg, by Mr Leisure <mr_le +isure@hotmail.com>" )->pack; $hmtl->Button(-text => "Ok", -command => sub { $hmtl->withdraw } )->pack(-expand => "yes"); } else { $hmtl->deiconify(); $hmtl->raise(); } } sub really_quit { if (! Exists($qbtl)) { my $qbtl = $filemenu->Toplevel(-height=> 20, -width=> 45); $qbtl->title("Alert!"); $qbtl->Label(-text => "Do You Really Want To Quit?")->pack; $qbtl->Button(-text => "Yes", -command => sub {exit})->pack(-side => "left", -expand => "yes +"); $qbtl->Button(-text => "No", -command => sub {$qbtl->withdraw} )->pack(-expand => "yes", -s +ide => "right"); } else { $qbtl->deiconify(); $qbtl->raise(); } } ----------------------------------------- DS.PL ------------------------ #!/usr/bin/perl ###################################################################### +######## # # ds.pl - check diskspace utility on specified directory # # # # usage : ds.pl -dir=/YOURDIR -time=5 # # - will run utility on /YOURDIR directory, looping every 5 + seconds # # # ###################################################################### +######## # use strict; # use English; # use Cwd; # use efSetupEnv; use Getopt::Long; my %opt = (); GetOptions(\%opt, "dir=s", # name of directory to be checked "time=i", # sleep period before restart ); die "Must specify directory!" unless $opt{dir}; die "Must specify interval in seconds!" unless $opt{time}; until (! $opt{time}) { { check_disk_space($opt{dir} ) ; sleep($opt{time}) } sub check_disk_space { my $dfout = `df -k $opt{dir}` || die "Cannot check space on $o +pt{dir}!\n"; $dfout =~ s/ +/ /g; my @space = split (/ / , $dfout); my $block = $space[9]; if ($block < 50000) { # set this to whatever you want open(OUTPUT,">>ds.txt"); print OUTPUT "Error : Only $space[9] blocks free on $opt{dir} +!\n"; close(OUTPUT); } elsif ( $block < 6000000000 ) { #this too open(OUTPUT,">>ds.txt"); print OUTPUT "$space[9] blocks free on $opt{dir}\n"; close (OUTPUT); } else { } } }
      Is there a CGI version of this script? I have written a CGI script for process monitoring on several servers.. and this would come in handy! A quick question.. I have used remsh instead of Net::Telnet module to access the remote servers, and I am aware of its security pitfalls as it uses .rhosts. What do you think?
Re: Unix disk space reports
by salvadors (Pilgrim) on Dec 31, 2000 at 02:56 UTC
    This seems much too complicated for my liking.

    I really don't like the way it needs to create a temporary file, and that it writes it output out to a fixed file, rather than STDOUT, thus letting me redirect it, or play with it in some other way. I'd go for something more along the lines of:

    use strict; my %space; while (<>) { next unless m#^/#; next if m#^/proc#; next unless m#^[^ ]* *([^ ]*) *[^ ]* *([^ ]*) *[^ ]*#; $space{$ARGV}{total} += $1; $space{$ARGV}{free} += $2; } foreach my $host (sort keys %space) { printf "%s: %dk free, out of %dk, (%.2f%%)\n", $host, $space{$host}{free}, $space{$host}{total}, $space{$host}{free} / $space{$host}{total} * 100; }
    Then I'd call it as: perl ~/dfk hosts/* > report

    Playing with the format of the output is then trivial.

    If you really want to be able to view the intermediate 'space' file, then you could add a command line parameter for it (including the name of the output file?).

    Tony

      Well thanks for the arrogant reply there Tony. I guess the fact that this was my FIRST application of what I have learnt in Perl over the last month was lost on you big guy...
      if ($mr_leisure) { bow; }

        You're welcome.

        Although if you'd actually said "this is my first Perl script", or "please let me know what you think of this - I'm not really sure whether it's good or not", I might have replied differently than if you'd just offered it up as code for everyone, without any comments.

        I guess I'll note you down in my list of people who would rather everyone told them how great they were than offered constructive criticism?

        Tony

      I agree my script does limit general usage; however, I was working to get a report that had the format I wanted for my boss. As for keeping the temp files I usualy keep them until I'm very sure I'm getting everything I what out of the script. I guess I just live in debugland.
        I want the same kind of report which has the capablity of showing the diskpace status for the past month. Can some help?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://46730]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (9)
As of 2014-08-29 14:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (280 votes), past polls