[Orca-users] Re: I know this question has been asked a million times ...

Blair Zajac blair at orcaware.com
Tue May 7 21:49:55 PDT 2002


Joe,

Thanks for sending this to the group, I prefer it when people send
their work to the group to get credit for the work they did.

It looks like Yahoo! reformatted the message to screw up the line lengths.
If you could resend it as an attachment, that would be great.

Some minor Perl points below and we could include this with Orca:

pawlicja wrote:
> Well, I've come up with a script that works for me.  Basically, it
> assumes that your most recent orcallator data file is correct, and
> will rearrange/remove/add columns in old data files to be
> consistent.  That way, when the rrd files and graphs are regenerated,
> duplicate plots are gone!
> 
> Check it out.  BTW - I know it's not the most elegant example of perl
> programming, but hey...
> 
> #!/usr/local/bin/perl

Always use the -w flag to pass to Perl, ie

   #!/usr/local/bin/perl -w

to catch errors.

> #
> #      orcafix.pl - Joe Pawlicki - May 2002
> #      Modify the orcallator data files, to prevent rrd files which
> result
> #      in multiple plots for disk space and inode usage.  This
> situation
> #      arises because filesystems can change over time, and orca
> doesn't
> #      handle this well.
> #
> #      Step 1:  Copy script to all orcallator clients
> #      Step 2:  Backup orcallator data files
> #      Step 3:  Stop orcallator process on client
> #      Step 4:  Uncompress all orcallator data files on client
> #      Step 5:  Run orcafix.pl on client;  when prompted, enter the
> name of the
> #               most recent data file
> #      Step 6:  Re-compress older data files (using gzip, bzip, etc.)
> #      Step 7:  Start orcallator process on client
> #      Step 8:  When orcafix has been run on all clients, remove the
> rrd files and
> #               web pages from the reporting host
> #      Step 9:  Resync the client data files to the reporting host
> by your normal
> #               procedures, and run orca to regenerate rrd files and
> web pages
> #
> 

In addition, add

   use strict;

   before the

   use File::Copy;

   in the file.

> use File::Copy;
> 
> print "orcafix.pl - This script will modify the orcallator data files
> in\n";
> print "the current directory, so that filesystem data is consistent
> with the\n";
> print "most recent data file.  You must provide the name of the most
> recent\n";
> print "data file, and all data files in this directory must be
> uncompressed.\n";
> print "\nDo you want to continue?\n";
> 
> $ANS = <STDIN>;
> if ( $ANS !~ /^[y|Y]/ ) {
>   print "Exiting.\n";
>   exit;
> }
> 
> print "Enter the most recent data file name:\n";
> $newest = <STDIN>;
> chomp $newest;
> open CURRENT, "$newest" || die "Couldn't open data file $newest";

You don't need the "'s around $newest.  Also, add $! to the die message:

open CURRENT, "$newest" || die "Couldn't open data file $newest: $!";

> 
> # Load the most current data file into a big array
> while (<CURRENT>) {
>   @singleline = split /\s+/;
>   push @CurrentData, [ @singleline ];
> }
> close CURRENT;

I always like to check the return value of close, even though in this
case there's nothing that could go wrong.  On writing, you never know
when you're going to fill up a disk.

> 
> # Get the field headings from the first line of the data file
> $firstref = $CurrentData[0];
> for $x (0 .. $#{$firstref}) {
>   $curfields[$x] = $firstref->[$x];
> }
> 
> # Get the list of all orcallator files in the current directory
> opendir THISDIR, ".";

Also check for opendir failure.

> @filelist = readdir THISDIR;
> closedir THISDIR;
> chomp @filelist;
> 
> ### Main loop - repeat for every file in the current directory
> foreach $filename (@filelist) {
>   if ( $filename =~ "orcallator-" && $filename ne $newest ) {
>     print "Working on file: $filename\n";
>     open THISFILE, "$filename" || die "Couldn't open data file
> $filename";

$! again:

> 
>     # Load entire data file into array
>     while (<THISFILE>) {
>       @singleline = split /\s+/;
>       push @OldData, [ @singleline ];
>     }
>     close THISFILE;
>     rename "$filename", "$filename.sav" || die "Couldn't rename file
> $filename";

Instead of renaming the original file, write the output to a
temporary filename and if everything went correctly, then rename
the original and rename the new file to the final name.  This
handles the case when the user does a control-C in the middle of
running the script that could cause loose data.

> 
>     # Get columns from the first line of the data file
>     $firstref = $OldData[0];
>     for $x (0 .. $#{$firstref}) {
>       $oldfields[$x] = $firstref->[$x];
>     }
> 
>     # Compare columns to the good headings to be preserved, add zero
> data
>     # if column doesn't exist in old data file
>     for $curposition ( 0 .. $#curfields ) {
>       $match = 0;
>       for $oldposition ( 0 .. $#oldfields ) {
>         if ( $oldfields[$oldposition] eq $curfields[$curposition] ) {
>           $match = 1;  # Matching column found in old data file
>           for $i ( 0 .. $#OldData ) {
>             $ChangedData[$i][$curposition] = $OldData[$i]
> [$oldposition];
>           }
>         }
>       }
>       if ( $match == 0 ) {  # No matching column found, insert zeroes
>         $ChangedData[0][$curposition] = $curfields[$curposition];
>         for $i ( 1 .. $#OldData ) {
>           $ChangedData[$i][$curposition] = "0.0";
>         }
>       }
>     }
> 
>     # Write out modified data file
>     open OUT, ">$filename" || die "Couldn't create file $filename";

Write to $filename.tmp

>     for $j (0 .. $#ChangedData) {
>       $ref = $ChangedData[$j];
>       for $k (0 .. $#{$ref}) {
>         print OUT "$ref->[$k] ";
>       }
>       print OUT "\n";
>     }
>     close OUT;

Since we're writing a file, check for success , and if close succeeded,
then rename $filename -> $filename.sav and $filename.tmp -> $filename.
If the first rename failed, then quit.  If the second rename failed, then
restore the .sav file with another rename, which should succeed, and
then quit.

Thanks for the script!

Blair

>     undef @OldData;
>     undef @oldfields;
>     undef @ChangedData;
>     undef @changedfields;
>   }
> }
> ### End main loop

-- 
Blair Zajac <blair at orcaware.com>
Web and OS performance plots - http://www.orcaware.com/orca/



More information about the Orca-users mailing list