#!/usr/bin/perl # Filter a sql log to produce summaries at different levels of detail. # The basename for the input log and the corresponding output files # is accepted as a command argument. Names used at the time this # Perl script is created are ip_cfa and ip_gas_updated. # ("ip" stands for "incorporation projections") # This filter/postprocessor script is written to handle output # from an Oracle database using the sqlplus client. # Minor details will need changes to handle results # from other databases or other client programs. # ip_filter should work equally well on Windows or Unix systems, # particularly including Linux. # Invocation is expected to be: # # ip_filter [basename] # use to generate all filenames, both input and output. # For example, "ip_filter ip_cfa" reads log file "ip_cfa.log" # "ip_filter ip_gas_updated" reads "ip_gas_updated.log" # # If is omitted "ip_gas_updated" is assumed. # # On Windows the invocation is "perl ip_filter ". # # Input files are: # # .log log file produced by a run on Oracle # of .sql # _fiscal_summary_template.html # template html file for generation of a # fiscal summary web page # # Output files written as text files are: # # _1.log for all growth reduction levels # _1_baseline.log for 0% (baseline) growth # _1_25.log for 25% reduced growth # _1_50.log for 50% reduced growth # _1_75.log for 75% reduced growth # _1_zero.log for 100% reduced growth (zero growth) # # Ouput file written as an html file (for a web page): # # _fiscal_summary.html if ( $#ARGV >= 0 ) { $basename = $ARGV[0]; } else { $basename = "ip_gas_updated"; } print "Using basename = $basename in all filenames\n"; open( IPLOG, "${basename}.log" ) || die "Unable to open ${basename}.log\n"; @log = ; close( IPLOG ); print "Read ${basename}.log\n"; # Filter out all lines preceding result output, # marked by "set echo off" while ( $log[0] !~ /set echo off/ ) { shift( @log ); } # Shift one more time to drop the "set echo off". shift( @log ); # First filter pass: # Generate @ip1log by deleting only lines not wanted in clean output. # Also assure that eols are minimal, \n, not a Windows/DOS \r\n @ip1log = (); $i = 0; $j = 0; while ( $i <= $#log ) { if ( ($log[$i] =~ /SQL/) || ($log[$i] =~ /rows selected/) ) { ++ $i; next; } chop( $log[$i] ); $ip1log[$j++] = $log[$i++] . "\n"; } # Write text logs for full report: # # _1.log for all growth reduction levels # _1_baseline.log for 0% (baseline) growth # _1_25.log for 25% reduced growth # _1_50.log for 50% reduced growth # _1_75.log for 75% reduced growth # _1_zero.log for 100% reduced growth (zero growth) open( IP1, ">${basename}_1.log" ) || die "Unable to open ${basename}_1.log for output\n"; open( IP10, ">${basename}_1_0.log" ) || die "Unable to open ${basename}_1_0.log for output\n"; open( IP125, ">${basename}_1_25.log" ) || die "Unable to open ${basename}_1_25.log for output\n"; open( IP150, ">${basename}_1_50.log" ) || die "Unable to open ${basename}_1_50.log for output\n"; open( IP175, ">${basename}_1_75.log" ) || die "Unable to open ${basename}_1_75.log for output\n"; open( IP1100, ">${basename}_1_100.log" ) || die "Unable to open ${basename}_1_100.log for output\n"; @individual_files = ( IP0, IP25, IP50, IP75, IP100 ); $growth_alternative = -1; for ( $i=0; $i <= $#ip1log; ++ $i ) { print IP1 $ip1log[$i]; if ( $ip1log[$i] =~ /^==========/ ) { ++ $growth_alternative; } # Pardon the brute force, this probably is closer # to what would be needed in PHP logic if this # is migrated to live generation. if ( $growth_alternative == 0 ) { print IP10 $ip1log[$i]; } elsif ( $growth_alternative == 1 ) { print IP125 $ip1log[$i]; } elsif ( $growth_alternative == 2 ) { print IP150 $ip1log[$i]; } elsif ( $growth_alternative == 3 ) { print IP175 $ip1log[$i]; } elsif ( $growth_alternative == 4 ) { print IP1100 $ip1log[$i]; } else { print "Bogus state\n"; } } close( IP1 ); print "Wrote ${basename}_1.log\n"; close( IP10 ); print "Wrote ${basename}_1_0.log\n"; close( IP125 ); print "Wrote ${basename}_1_25.log\n"; close( IP150 ); print "Wrote ${basename}_1_50.log\n"; close( IP175 ); print "Wrote ${basename}_1_75.log\n"; close( IP1100 ); print "Wrote ${basename}_1_100.log\n"; # If appropriate in the future add filtering to report at higher # levels of abstraction, eliminating selected detail lines. # Files for the first reduction in detail can be named _2_*.log, # the next level would name files _3_*.log, and so on. ## Generate summary of all fiscal projections, comparing ## bottom line surplus/deficit and all-funds balaince ## for each year and for each growth alternative ## ## Produce an html file, it's not worth messing with the formatting ## for a plain text file -- let the reader's browser do it. # Begin by extracting the needed numbers from the log file # and populating a hash with them. Hash codes are used in the # html template file, the final step substitutes the corresponding values. # Template codes for substitution have the form xx # where # is the growth alternative, percentage of reduced growth: # 0, 25, 50, 75, or 100 # is the 2-digit year: # "07", "08", "09", "10", "11", "12", "13", "14", or "15" # Define mapping from growth alternative index values to strings # for generating hash associations for template substitutions. @gamap = ( "0", "25", "50", "75", "100" ); my %surdef; my %allbal; $growth_alternative = -1; for ( $i=0; $i <= $#ip1log; ++ $i ) { print IP1 $ip1log[$i]; if ( $ip1log[$i] =~ /^==========/ ) { ++ $growth_alternative; $ga = $gamap[$growth_alternative]; } if ( $ip1log[$i] =~ /^ALL FUNDS OPERATING SURPLUS\/DEFICIT/ ) { # Extract surplus/deficit numbers from this line @values = split( / +/, $ip1log[$i] ); $surdef{ 'xx' . $ga . '_07' } = $values[4]; $surdef{ 'xx' . $ga . '_08' } = $values[5]; $surdef{ 'xx' . $ga . '_09' } = $values[6]; $surdef{ 'xx' . $ga . '_10' } = $values[7]; $surdef{ 'xx' . $ga . '_11' } = $values[8]; $surdef{ 'xx' . $ga . '_12' } = $values[9]; $surdef{ 'xx' . $ga . '_13' } = $values[10]; $surdef{ 'xx' . $ga . '_14' } = $values[11]; $surdef{ 'xx' . $ga . '_15' } = $values[12]; } if ( $ip1log[$i] =~ /^ALL FUNDS BALANCE/ ) { # Extract all-funds balance numbers from this line @values = split( / +/, $ip1log[$i] ); $allbal{ 'yy' . $ga . '_07' } = $values[3]; $allbal{ 'yy' . $ga . '_08' } = $values[4]; $allbal{ 'yy' . $ga . '_09' } = $values[5]; $allbal{ 'yy' . $ga . '_10' } = $values[6]; $allbal{ 'yy' . $ga . '_11' } = $values[7]; $allbal{ 'yy' . $ga . '_12' } = $values[8]; $allbal{ 'yy' . $ga . '_13' } = $values[9]; $allbal{ 'yy' . $ga . '_14' } = $values[10]; $allbal{ 'yy' . $ga . '_15' } = $values[11]; } } # Substitute values into the template to produce the final html file. open( SUMMARY, ">${basename}_fiscal_summary.html" ) || die "Can't open ${basename}_fiscal_summary.html for output\n"; open( TEMPLATE, "${basename}_fiscal_summary_template.html" ) || die "Can't open fiscal_summary_template.html\n"; @summary =