[Orca-users] Re: Mimicking ORCA data gathering on IBM AIX

Blair Zajac blair at gps.caltech.edu
Tue Jul 10 12:13:09 PDT 2001


When you think it's in good enough shape, let me know and I'll include
it in the contrib directory.

Blair

"Jason D. Kelleher" wrote:
> 
> Try the attached script (at your own risk).  The latest mods (made
> this morning) are still being tested, but it should get you started.
> 
> Some of the column headings differ from those in the orcallator
> file bundled with Orca such as %wait and PagesI/s  because Orca
> added them recently or I was just lazy.  It's not very pretty, but
> it's getting the job done. Maybe someday it will be ready for
> contrib...  Good luck.
> 
> jason
> 
> --- skintstudent at yahoo.co.uk wrote:
> > I'm new to ORCA,
> > and have been given the task of mimicking the data file that orca
> > uses in creating graphs; for an IBM AIX which can then be fed into
> > ORCA.
> > I'm looking for somewhere which gives an explanation of the
> > structure
> > of the ORCA data file (the one with timestamp, loccltime,...)
> > i.e. what all those terms mean and how they are calculated.
> >
> > Any ideas??
> >
> >
> 
>     ---------------------------------------------------------------
> #!/usr/local/bin/perl
> 
> # Version 1.5
> 
> # Description:
> # Collect general perfromance statistics formatted for
> # interpretaion by Orca.
> 
> # Usage:
> # The following variables may be set:
> #
> #     OUT_ROOT          root directory for datafiles (eg
> /opt/log/performance)
> #     INTERVAL          the number of seconds between checks (eg 300 =
> 5 min)
> #     DURATION          numer of hours to run (eg 1 = 1 hr)
> #
> # This script runs various standard system utilities to collect
> # system performance statistics and writes them out to datafile named
> # HOSTNAME/stats.YYYY-MM-DD-HHmm under the OUT_ROOT directory.
> #
> # It runs for the the numbers specified by DURATION collecting data
> # every INTERVAL number of seconds.  After DURATION, the script
> # closes and compresses it's datafile via /usr/bin/compress and then
> # exits.  If DURATION=24 and INTERVAL=300 (recommended) then the
> # following cron entry would collect continuos stats for a system:
> #
> # 0 0 * * * /<PATH_TO_SCRIPT>/stats.pl
> #
> 
> # 2001-04-16 - JDK - Genesis... by Jason D. Kelleher
> # 2001-05-02 - JDK - Updates to make data aggregation easier.
> #                    Added #open connections, pagestotl.
> # 2001-07-06 - JDK - added command-line args & data checks
> # 2001-07-09 - JDK - added signal handler, column checks, & umask
> # 2001-07-10 - JDK - now autodetects interfaces via netstat -i
> #                    v1.5
> 
> # Note: Execution speed is more important than cleanliness here.
> 
> # Explicitly set PATH to prevent odd problems if run manually.
> $ENV{PATH} = '/usr/bin:/etc:/usr/sbin:/usr/ucb:/sbin';
> 
> $Usage_Message= '
> Usage: stats.pl [-r out_root] [-i interval] [-d duration] [-h]
> 
>         -r out_root     set root output directory, default:
> /opt/log/performance
>         -i interval     number of seconds between checks, default: 300
>         -d duration     number of hours to run, default: 24
>         -h              this message
> 
> ';
> 
> # Parse the command line arguments
> while ( $#ARGV >= 0 ) {
> 
>         if ($ARGV[0] eq "-r") {
>                 shift @ARGV;
>                 $OUT_ROOT = shift @ARGV;
>         }
>         elsif ($ARGV[0] eq "-i") {
>                 shift @ARGV;
>                 $INTERVAL = shift @ARGV;
>         }
>         elsif ($ARGV[0] eq "-d") {
>                 shift @ARGV;
>                 $DURATION = shift @ARGV;
>         }
>         elsif ($ARGV[0] eq "-h") {
>                 print $Usage_Message;
>                 exit 0;
>         }
>         elsif ($ARGV[0] =~ /^-/) {
>                 die "Invalid flag: $ARGV[0]\n$Usage_Message";
>         }
>         else {
>                 die "Invalid argument: $ARGV[0]\n$Usage_Message";
>         }
> }
> 
> ## BEGIN set defaults
> 
> $OUT_ROOT ||= '/opt/log/performance';   # root directory for datafiles
> $INTERVAL ||= 300;                      # seconds between checks
> $DURATION ||= 24;                       # number of hours to run
> 
> ## END set defaults
> 
> ## Derived variables.
> $iterations = $DURATION * 60 * 60 / $INTERVAL;  # Number of checks.
> chomp( $HOST = `uname -n` );
> $out_dir = "${OUT_ROOT}/${HOST}";
> ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
> localtime(time);
> $stat_file = sprintf("%s/stats.%.2d-%.2d-%.2d-%.2d%.2d", $out_dir,
> $year+1900, $mon+1, $mday, $hour, $min);
> 
> # Base all timestamps on start time.
> $start_time = time();
> $timestamp = 0;
> 
> ## Autodetect network interfaces
> #open IN, "ifconfig -a|";
> open IN, "netstat -i|";
> while ( <IN> ) {
> #       if ( /^(\S+):/ ) {
>         if ( /^(\w+).*link/ ) {
>                 push @net_interfaces, $1;
>         }
> }
> close IN;
> 
> # Grab some base system info prior to collecting stats.
> open IN, "lsattr -El sys0 -a realmem |";
> while ( <IN> ) {
>         if ( /^realmem (\d+) / ) {
>                 $pagestotl = $1 * 1024 / 4096;  # Grab realmem in KB
> and convert to pages.
>                 # this gets used down in the vmstat section
>         }
> }
> close IN;
> 
> ## Make sure we can write output.
> umask 0022;     # make sure the file can be harvested
> unless ( -d $out_dir ) {
>         system("mkdir", "-p", "$out_dir");
> }
> open OUT, ">$stat_file" or die "ERROR: Could not open $stat_file: $!";
> my $oldfh = select OUT; $| = 1; select $oldfh;
> 
> # Set signal handlers to close and compress the output
> # file just in case.
> $SIG{HUP} = \&exit_nicely;
> $SIG{INT} = \&exit_nicely;
> $SIG{QUIT} = \&exit_nicely;
> $SIG{TERM} = \&exit_nicely;
> 
> # Set gloabals used for printing (or not) headers.
> $need_header = 1;
> $prev_header_cnt = 0;
> $prev_info_cnt = 0;
> 
> while ( $iterations-- > 0 ) {
> 
>         $timestamp = $timestamp ? time() : $start_time;
>         ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst
> ) = localtime(time);
>         $locltime = sprintf("%.2d:%.2d:%.2d", $hour, $min, $sec);
> 
>         ## Get runq data
>         open IN, "uptime |";
>         while ( <IN> ) {
>                 if ( /load average:\s+(\S+),\s+(\S+),\s+(\S+)/ ) {
>                         $load_info = join "\t", $1, $2, $3;
>                 }
>         }
>         close IN;
>         $load_header = "1runq\t5runq\t15runq";
>         if ( scalar( split ' ', $load_header ) != scalar( split ' ',
> $load_info ) ) {
>                 $load_header = '';
>                 $load_info = '';
>                 $need_header = 1;
>                 print STDERR "WARNING: load header does not match load
> info.\n";
>         }
> 
>         ## Get number of system processes
>         $num_proc = -1; # Don't count the header.
>         open IN, "ps -ek |";
>         while ( <IN> ) {
>                 $num_proc++;
>         }
>         close IN;
>         $proc_info =  $num_proc;
>         $proc_header = '#proc';
>         if ( scalar( split ' ', $proc_header ) != scalar( split ' ',
> $proc_info ) ) {
>                 $proc_header = '';
>                 $proc_info = '';
>                 $need_header = 1;
>                 print STDERR "WARNING: #proc header does not match
> #proc info.\n";
>         }
> 
>         ## Get vmstat data
>         open IN, "vmstat 1 2|";
>         while ( <IN> ) {
>                 chomp;
>                 if ( /^[\s\d]+$/ ) {
>                         # overwrite first line on 2nd pass
>                         ( $vmstat_r, $vmstat_b, $vmstat_avm,
> $vmstat_fre, $vmstat_re, $vmstat_pi, $vmstat_po, $vmstat_fr,
> $vmstat_sr, $vmstat_cy, $vmstat_inf, $vmstat_syf, $vmstat_csf,
> $vmstat_us, $vmstat_sy, $vmstat_id, $vmstat_wa ) = split;
>                         $vmstat_info = join "\t", $vmstat_avm,
> $vmstat_fre, $pagestotl, $vmstat_pi, $vmstat_po, $vmstat_fr,
> $vmstat_sr, $vmstat_us, $vmstat_sy, $vmstat_wa;
>                 }
>         }
>         close IN;
>         $vmstat_header =
> "pagesactive\tpagesfree\tpagestotl\tPagesI/s\tPagesO/s\tPagesF/s\tscanrate\tusr%\tsys%\twait%";
>         if ( scalar( split ' ', $vmstat_header ) != scalar( split ' ',
> $vmstat_info ) ) {
>                 print STDERR "WARNING: vmstat header does not match
> vmstat info.\n";
>                 $vmstat_header = '';
>                 $vmstat_info = '';
>                 $need_header = 1;
>         }
> 
>         ## Get filesystem data
>         $fs_header =  '';
>         $fs_info = '';
>         open IN, "df -k -v |";
>         while ( <IN> ) {
>                 chomp;
>                 if ( m%^/% ) {
>                         ( $mnt_dev, $blocks, $used, $free, $pct_used,
> $iused, $ifree, $ipct_used, $mnt ) = split;
>                         # Recalculate percents because df rounds.
>                         $fs_info .= "\t" .
> sprintf("%s\t%s\t%s\t%.5f\t%d\t%s\t%s\t%.5f", $blocks, $used, $free,
> ($used/$blocks)*100, ($iused+$ifree), $iused, $ifree,
> ($iused/($iused+$ifree))*100 );
>                         $fs_header .= "\t" . join "\t", "mntC_$mnt",
> "mntU_$mnt", "mntA_$mnt", "mntP_$mnt", "mntc_$mnt", "mntu_$mnt",
> "mnta_$mnt", "mntp_$mnt";
>                 }
>         }
>         close IN;
>         if ( scalar( split ' ', $fs_header ) != scalar( split ' ',
> $fs_info ) ) {
>                 print STDERR "WARNING: filesystem header does not
> match filesystem info.\n";
>                 $fs_header = '';
>                 $fs_info = '';
>                 $need_header = 1;
>         }
> 
>         ## Get iostat data
>         $disk_t = 0;
>         $disk_rK = 0;
>         $disk_wK = 0;
>         undef %disks;
>         open IN, "iostat -d 1 2|";
>         while ( <IN> ) {
>                 if ( /^(\S+)\s+\S+\s+\S+\s+(\S+)\s+(\d+)\s+(\d+)/ ) {
>                         my $disk = $1;
>                         my $tps = $2;
>                         my $rK = $3;
>                         my $wK = $4;
>                         if ( not $disks{$disk} ) {
>                                 $disks{$disk}++;        # Get rK & wK
> from first pass.
>                                 $disk_rK += $rK;
>                                 $disk_wK += $wK;
>                         } else {
>                                 $disk_t += $tps;        # Get trans
> per sec from second pass.
>                         }
>                 }
>         }
>         close IN;
>         $iostat_header = "disk_t/s\tdisk_rK/s\tdisk_wK/s\t";
>         $iostat_info = "${disk_t}\t${disk_rK}\t${disk_wK}";
>         if ( scalar( split ' ', $iostat_header ) != scalar( split ' ',
> $iostat_info ) ) {
>                 print STDERR "WARNING: iostat header does not match
> iostat info.\n";
>                 $iostat_header = '';
>                 $iostat_info = '';
>                 $need_header = 1;
>         }
> 
>         ## Get packet data
>         $packet_header = '';
>         $packet_info = '';
>         #foreach $interface ( split(/\s+/, $NET_INTERFACES) ) {
>         foreach $interface ( @net_interfaces ) {
>                 $packet_header .=
> "${interface}Ipkt/s\t${interface}IErr/s\t${interface}Opkt/s\t${interface}OErr/s\t${interface}Coll/s\t";
>                 open IN, "netstat -I $interface 1|";
>                 while ( <IN> ) {
>                         if (
> /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+/ ) {
>                                 $packet_info .= "\t" . join "\t", $1,
> $2, $3, $4, $5;
>                                 last;
>                         }
>                 }
>                 close IN;
>         }
>         if ( scalar( split ' ', $packet_header ) != scalar( split ' ',
> $packet_info ) ) {
>                 print STDERR "WARNING: packet header does not match
> packet info.\n";
>                 $packet_header = '';
>                 $packet_info = '';
>                 $need_header = 1;
>         }
> 
>         ## Get TCP Connection data
>         $tcp_estb = 0;
>         open IN, "netstat -a |";
>         while ( <IN> ) {
>                 if ( /^tcp.+ESTABLISHED$/ ) {
>                 $tcp_estb++;
>                 }
>         }
>         close IN;
>         $tcp_info = $tcp_estb;
>         $tcp_header = 'tcp_estb';
>         if ( scalar( split ' ', $tcp_estb_header ) != scalar( split '
> ', $tcp_estb_info ) ) {
>                 print STDERR "WARNING: tcp_estb header does not match
> tcp_estb info.\n";
>                 $tcp_estb_header = '';
>                 $tcp_estb_info = '';
>                 $need_header = 1;
>         }
> 
>         ## Join header and info then verify column counts.
>         $out_header = join "\t", "timestamp", "locltime",
> $load_header, $proc_header, $vmstat_header, $fs_header,
> $iostat_header, $packet_header, $tcp_header;
>         $out_header =~ tr/ \t/\t/s;     # translate whitespace to
> single tabs
> 
>         $out_info = join "\t", $timestamp, $locltime, $load_info,
> $proc_info, $vmstat_info, $fs_info, $iostat_info, $packet_info,
> $tcp_info;
>         $out_info =~ tr/ \t/\t/s;       # translate whitespace to
> single tabs
> 
>         $header_cnt = split ' ', $out_header;
>         $info_cnt = split ' ', $out_info;
>         if ( $header_cnt != $info_cnt ) {
>                 print STDERR "ERROR: header columns do not equal data
> columns. Exiting.\n";
>                 &exit_nicely;
>         }
>         elsif ( $header_cnt != $prev_header_cnt or $info_cnt !=
> $prev_info_cnt ) {
>                 $need_header = 1;
>         }
>         $prev_header_cnt = $header_cnt;
>         $prev_info_cnt = $info_cnt;
> 
>         ## Write output
>         if ( $need_header ) {
>                 print OUT $out_header, "\n";
>                 $need_header = 0;
>         }
>         print OUT $out_info, "\n";
> 
>         sleep $INTERVAL - (time() - $timestamp);
> 
> }
> close OUT;
> 
> @args = ("compress", "-f", "$stat_file");
> system(@args);
> 
> exit 0;
> 
> # This subroutine is called by the signal handler.
> sub exit_nicely {
>         close OUT;
>         @args = ("compress", "-f", "$stat_file");
>         system(@args);
>         exit 0;
> }



More information about the Orca-users mailing list